pytorch入门Tenser与Autograd

Posted 啊~小 l i

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pytorch入门Tenser与Autograd相关的知识,希望对你有一定的参考价值。

Tenser与Autograd

对Tenser求导需要注意以下事项

  1. 创建叶子节点(Leaf Node)的Tenser,使用requires_gard参数指定是否记录对其的操作,以便之后利用backward()方法进行梯度求解。
  2. 利用requires_gard_()方法修改Tenser的requires_gard属性。调用with torch.no_gard_():,将不在计算张量的梯度,跟踪张量的历史记录。
  3. 通过运算创建的(非叶子节点),会自动赋予grad_fn属性,该属性表示梯度函数。
  4. 最后得到的tenser执行backward()函数,此时自动的计算各变量的梯度,并将累加结果保存到gard属性中,计算完成后,非叶子节点的梯度自动释放。
  5. backword()函数接收参数,该参数应和调用backward()函数的Tenser的维度相同。
  6. 反向传播的中间缓存可能会被清空,如果需要多次反向传播,需要指定backward()中的参数retain_graph=True。多次反向传播时梯度是累加的。
  7. 非叶子节点的梯度backward调用后即被清空
  8. 可以通过torch.no_grad()包裹代码的形式来阻止autograd去跟踪那些标为为requergrad=True的张量的历史记录。(测试阶段常用)

计算图

计算图是一种有向无环图像,用图像的方法来表示算子与变量之间的关系。
如下图所示:圆形表示变量,矩阵表示算子。如表达式z=wx+b,可以写成两个表达式 y=wx z=y+b其中x,w,b为变量,是用户创建的变量,不依赖其他变量,故又称为叶子节点。

x
mul
w
y
add
b
z

PyTorch调用backward()方法将自动的计算个节点的梯度,这是一个反向传播过程。在反向传播过程中,autograd沿着图2-10.从当前根节点z反向溯源,利用导数链式法则,计算所有叶子节点的梯度,其梯度值将累加到grad属性中。对非叶子节点的计算操作(或Function)记录在grad_fn属性中,叶子节点的grad_fn值为None.

dz
addBackward
dy
db
mulBackward
dx
dw

标量反向传播

假设x,w,b都是标量,z=wx+b,对标量z调用backward()方法,我们无需对backward()传入参数。

  1. 定义叶子节点及算子节点
import torch

x = torch.Tensor([2])
print(x)
w = torch.randn(1, requires_grad=True)
b = torch.randn(1, requires_grad=True)
y = torch.mul(w, x)
z = torch.add(y, b)
# 查看叶子节点的requite_gard
print("x,w,b的requires_grad:{},{},{}".format(x.requires_grad, 
  1. 查看叶子节点。非叶子节点其他属性
w.requires_grad, b.requires_grad))
# 查看非叶子节点的requires_grad
print("y,z的requires_grad:{},{}".format(y.requires_grad, z.requires_grad))
# 查看叶子节点的grad_fn 判断是否为叶子节点x.is_leaf
print("x,w,b的requires_grad:{},{},{}".format(x.grad_fn, w.grad_fn, b.grad_fn))
  1. 自动求导实现梯度方向的反向传播
# 自动求导实现反向传播
z.backward()
# 如果多次使用backward需要改动参数为retrain_graph为True
# z.backward(retain_graph=True)
print("w,b的梯度为:{},{}".format(w.grad, b.grad))

控制台输出

F:\\Anaconda3\\python.exe
tensor([2.])
x,w,b的requires_grad:False,True,True
y,z的requires_grad:True,True
x,w,b的requires_grad:None,None,None
w,b的梯度为:tensor([2.]),tensor([1.])

非标量反向传播

定义叶子节点和计算节点

import torch
x = torch.tensor([[2, 3]], dtype=torch.float, requires_grad=True)
j = torch.zeros(2, 2)
y = torch.zeros(1, 2)
# 定义y与x间的映射  y = x1**2+3*x2  y = x2**2+2*x1
y[0, 0] = x[0, 0]**2+3*x[0, 1]
y[0, 1] = x[0, 1]**2+2*x[0, 0]

首先让v=(1,0)得到y1对x的梯度,然后使得v=(0,1),得到y2对x的梯度。这个需要重复 使用backward(),需要对retain_graph=True

y.backward(torch.Tensor([[1, 0]]), retain_graph=True)
j[0] = x.grad
x.grad = torch.zeros_like(x.grad)
y.backward(torch.tensor([[0, 1]]))
j[1] = x.grad
print(j)

使用Tenser和Antograd实现机器学习

生成训练数据

import torch
from matplotlib import pyplot as plt

torch.manual_seed(100)
dtype = torch.float
# 生成x坐标数据,x为tensor,需要把x形状转化为100*1
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)
# 生成y坐标数据,y为tensor,形状为100*1,加上一些噪声
y = 3*x.pow(2)+2+0.2*torch.rand(x.size())

# 把x,y抓为为numpy
plt.scatter(x.numpy(), y.numpy())
plt.show()

初始化权重

# 初始化权重
w = torch.randn(1, 1, dtype=dtype, requires_grad=True)
b = torch.randn(1, 1, dtype=dtype, requires_grad=True)

训练模型

# 训练
lr = 0.01  # 学习率
for i 超简单!pytorch入门教程:Autograd

PyTorch深度学习60分钟快速入门 Part2:Autograd自动化微分

深度学习为什么选择Pytorch?史上最详细Pytorch入门教程

[Pytorch系列-22]:Pytorch基础 - Autograd库 Autograd.Function与反向自动求导机制

pytorch 与 autograd.numpy

PyTorch入门学习:Autogard之自动求梯度