ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【PyTorch】Autograd

2021-01-28 00:00:45  阅读:276  来源: 互联网

标签:tensor hook Autograd requires data grad PyTorch True


Autograd

  1. requires_grad 需要求导(requires_grad)的tensor即Variable 变量的requires_grad属性默认为False,如果某一个节点requires_grad被设置为True,那么所有依赖它的节点requires_grad都是True。
  2. grad_fn 查看反向传播的函数的类型 AddBackward0/MulBackward0
  3. next_functions保存grad_fn的输入,是一个tuple,tuple的元素也是Function
  4. tensor.data 和tensor.detach()可以独立修改tensor的值,而不被autograd记录
  5. 使用hook进行调查被清空的叶子节点 autograd.grad也行
import torch as t
x = t.ones(1, requires_grad=True)
w = t.rand(1, requires_grad=True)
y = x * w
# y依赖于w,而w.requires_grad = True
x.requires_grad, w.requires_grad, y.requires_grad
(True, True, True)
x.grad_fn,y.grad_fn
(None, <MulBackward0 at 0x2f93ba176d8>)
x.is_leaf, w.is_leaf, y.is_leaf
(True, True, False)
y.grad_fn.next_functions 
((<AccumulateGrad at 0x2f93ba174a8>, 0),
 (<AccumulateGrad at 0x2f93ba17c50>, 0))
a = t.ones(3,4,requires_grad=True)
b = t.ones(3,4,requires_grad=True)
c = a * b

a.data # 还是一个tensor
tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]])
a.data.requires_grad # 但是已经是独立于计算图之外
False
# 近似于 tensor=a.data, 但是如果tensor被修改,backward可能会报错
tensor = a.detach()
tensor.requires_grad
False
# 第一种方法:使用grad获取中间变量的梯度
x = t.ones(3, requires_grad=True)
w = t.rand(3, requires_grad=True)
y = x * w
z = y.sum()
# z对y的梯度,隐式调用backward()
t.autograd.grad(z, y)
(tensor([1., 1., 1.]),)
# 第二种方法:使用hook
# hook是一个函数,输入是梯度,不应该有返回值
def variable_hook(grad):
    print('y的梯度:',grad)

x = t.ones(3, requires_grad=True)
w = t.rand(3, requires_grad=True)
y = x * w
# 注册hook
hook_handle = y.register_hook(variable_hook)
z = y.sum()
z.backward()

# 除非你每次都要用hook,否则用完之后记得移除hook
hook_handle.remove()
y的梯度: tensor([1., 1., 1.])

例程 使用Variable 实现线性回归

import torch as t
from matplotlib import pyplot as plt
from IPython import display
import numpy as np

# 设置随机数种子,为了在不同人电脑上运行时下面的输出一致
t.manual_seed(1000) 

def get_fake_data(batch_size):
    ''' 产生随机数据:y = x*2 + 3,加上了一些噪声'''
    x = t.rand(batch_size,1) * 5
    y = x * 2 + 3 + t.randn(batch_size, 1)
    return x, y
# 来看看产生x-y分布是什么样的
x, y = get_fake_data()
plt.scatter(x.squeeze().numpy(), y.squeeze().numpy())
<matplotlib.collections.PathCollection at 0x2f93f8eeb70>

在这里插入图片描述

#随即初始化参数
w = t.rand(1,1,requires_grad=True)
b = t.zeros(1,1,requires_grad=True)
losses = np.zeros(500)

lr = 0.005

for ii in range(500):
    x,y = get_fake_data(batch_size=32)
    
    #forward
    
    y_pred = x.mm(w) + b.expand_as(y)
    loss = 0.5*(y_pred - y)**2
    loss = loss.sum()
    losses[ii]=loss.item()
    
    #backward:
    loss.backward()
    
    #更新参数
    w.data.sub_(lr*w.grad.data)
    b.data.sub_(lr*b.grad.data)
    
    #梯度清零
    w.grad.data.zero_()
    b.grad.data.zero_()
    
    if ii%50 == 0:
        #plot 
        display.clear_output(wait=True)
        x = t.arange(0,6).view(-1,1).float()
        y = x.mm(w.data) + b.data.expand_as(x)
        plt.plot(x.numpy(),y.numpy())#predict
        
        x2,y2 = get_fake_data(batch_size=20)
        plt.scatter(x2.numpy(),y2.numpy())#true data
        
        plt.xlim(0,5)
        plt.ylim(0,13)
        plt.show()
        plt.pause(0.5)
        
print(w.item(),b.item())

在这里插入图片描述

1.8011078834533691 3.0073609352111816
plt.plot(losses)
plt.ylim(5,50)
(5, 50)

在这里插入图片描述

标签:tensor,hook,Autograd,requires,data,grad,PyTorch,True
来源: https://blog.csdn.net/weixin_42200352/article/details/113284041

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有