张量tensor类似于numpy中的narray,是一个多维数组,两者可以相互转换
import torch
import numpy as np
x = np.array([1., 2., 3.],dtype=float)
x = torch.from_numpy(x)
注意:PyTorch的梯度只能计算浮点张量,所有从numpy转化为tensor时,需要将numpy数据格式设置为float。
这个类是一个计算导数的引擎(更精确地说是雅克比向量积)。它记录了梯度张量上所有操作的一个图,并创建了一个称为动态计算图的非循环图。这个图的叶节点是输入张量,根节点是输出张量。梯度是通过跟踪从根到叶的图形,并使用链式法则将每个梯度相乘来计算的
它是记录了梯度张量上所有操作的一个图
X = 1 , Y = 2 Z = X*Y
其中,X的requires_grad = True,Y的requires_grad = False
图中的每个点轮廓框是一个变量,紫色矩形框是一个操作
每个变量对象都有几个成员,其中一些成员是:
1. Data:它是一个变量持有的数据。x持有一个1x1张量,其值等于1.0,而y持有2.0。z持有两个的乘积,即2.0
2. requires_grad:这个成员(如果为true)开始跟踪所有的操作历史,并形成一个用于梯度计算的向后图。对于任意张量a,可以按如下方式对其进行原地处理:a.requires_grad_(True)
3. grad: grad保存梯度值。如果requires_grad 为False,它将持有一个None值。即使requires_grad 为真,它也将持有一个None值,除非从其他节点调用.backward()函数。例如,如果你对out关于x计算梯度,调用out.backward(),则x.grad的值为dout/dx
4. grad_fn:这是用来计算梯度的向后函数,例如: MulBackward
5. is_leaf:在以下情况时为True:
- 它被一些函数显式地初始化,比如x = torch.tensor(1.0)
- 它是在张量的操作之后创建的,且所有张量都有requires_grad = False
- 它是通过对某个张量调用.detach()方法创建的
在调用backward()时,只计算requires_grad和is_leaf同时为真的节点的梯度
当打开 requires_grad = True时,PyTorch将开始跟踪操作,并在每个步骤中存储梯度函数,如下所示:
Backward()函数实际上是通过传递参数(默认情况下是1x1单位张量)来计算梯度的,它通过Backward图一直到每个叶节点,每个叶节点都可以从调用的根张量追溯到叶节点。然后将计算出的梯度存储在每个叶节点的.grad中
请记住,在正向传递过程中已经动态生成了后向图。backward函数仅使用已生成的图形计算梯度,并将其存储在叶节点中
import torch
x = torch.tensor(1.0, requires_grad = True)
z = x ** 3
z.backward()
print(x.grad.data)
#Prints '3' which is dz/dx
当调用z.backward()时,一个张量会自动传递为z.backward(torch.tensor(1.0))。torch.tensor(1.0)是用来终止链式法则梯度乘法的外部梯度。这个外部梯度作为输入传递给MulBackward函数,以进一步计算x的梯度。传递到.backward()中的张量的维数必须与正在计算梯度的张量的维数相同。例如,如果梯度支持张量x和y如下
x = torch.tensor([0.0, 2.0, 8.0], requires_grad = True)
y = torch.tensor([5.0 , 1.0 , 7.0], requires_grad = True)
z = x * y
然后,要计算z关于x或者y的梯度,需要将一个外部梯度传递给z.backward()函数,如下所示:
z.backward(torch.FloatTensor([1.0, 1.0, 1.0])
z.backward() 会给出 RuntimeError: grad can be implicitly created only for scalar outputs
反向函数传递的张量就像梯度加权输出的权值。因此它几乎总是一个维度的单位张量,size与 backward张量相同,除非需要计算加权输出。
从数学上讲,autograd类只是一个雅可比向量积计算引擎
如果一个向量X = [x1, x2,…xn]通过f(X) = [f1, f2,…fn]来计算其他向量,则雅可比矩阵(J)包含以下所有偏导组合:
上面的矩阵表示f(X)相对于X的梯度
假设一个启用PyTorch梯度的张量X:
X = [x1,x2,…,xn] (假设这是某个机器学习模型的权值)
X经过一些运算形成一个向量Y
Y = f(X) = [y1, y2,…,ym]
然后使用Y计算标量损失l。假设向量v恰好是标量损失l关于向量Y的梯度,如下:
向量v称为grad_tensor,并作为参数传递给backward() 函数
为了得到损失的梯度l关于权重X的梯度,雅可比矩阵J是向量乘以向量v(链式求导法则)
这种计算雅可比矩阵并将其与向量v相乘的方法使PyTorch能够轻松地为非标量输出提供外部梯度