搭建个人网站的步骤,温州专业微网站制作价格,郑州网站建设制作,网站的差异.backward()
.backward() 是 PyTorch 中用于自动求导的函数#xff0c;它的主要作用是计算损失函数对模型参数的梯度#xff0c;从而实现反向传播算法。 在深度学习中#xff0c;我们通常使用梯度下降算法来更新模型参数#xff0c;使得模型能够逐步逼近最优解。 在梯度下….backward()
.backward() 是 PyTorch 中用于自动求导的函数它的主要作用是计算损失函数对模型参数的梯度从而实现反向传播算法。 在深度学习中我们通常使用梯度下降算法来更新模型参数使得模型能够逐步逼近最优解。 在梯度下降算法中我们需要计算损失函数关于模型参数的梯度以便确定参数更新的方向和大小。 这个计算过程就是反向传播算法而 loss.backward() 就是反向传播算法的实现。 官方官方文档
Tensor.backward(gradientNone, retain_graphNone, create_graphFalse, inputsNone)[source] . 当前Variable(理解成函数Y)对leaf variable理解成变量X[x1,x2,x3]求偏导。 Computes the gradient of current tensor wrt graph leaves. 计算当前张量相对于图中叶子节点的梯度。 The graph is differentiated using the chain rule. If the tensor is non-scalar (i.e. its data has more than one element) and requires gradient, the function additionally requires specifying gradient. It should be a tensor of matching type and location, that contains the gradient of the differentiated function w.r.t. self. “使用链式法则对图进行微分。如果张量是非标量即其数据具有多个元素并且需要梯度则该函数还需要指定梯度。它应该是相同类型和位置的张量其中包含相对于自身的微分函数的梯度。” This function accumulates gradients in the leaves - you might need to zero .grad attributes or set them to None before calling it. See Default gradient layouts for details on the memory layout of accumulated gradients. 这个函数在叶子节点中累积梯度可能需要在调用它之前将 .grad 属性清零或设置为 None。有关累积梯度的内存布局详情请参阅默认梯度布局。 Parameters
gradient (Tensor or None) – 计算图可以通过链式法则求导。如果Tensor是 非标量(non-scalar)的(即是说Y中有不止一个y即Y[y1,y2,…])且requires_gradTrue。那么此函数需要指定gradient它的形状应该和Variable的长度匹配这个就很好理解了gradient的长度体与Y的长度一直才能保存每一个yi的梯度值啊里面保存了Variable的梯度。 原文链接https://blog.csdn.net/weixin_43763731/article/details/88982979
retain_graph (bool, optional) – 这个参数默认是False。计算梯度所必要的buffer在经历过一次backward过程后不会被释放。如果你想多次计算某个子图的梯度的时候设置为True。
create_graph (bool, optional) – If True, graph of the derivative will be constructed, allowing to compute higher order derivative products. Defaults to False.
inputs (sequence of Tensor) – Inputs w.r.t. which the gradient will be accumulated into .grad. All other Tensors will be ignored. If not provided, the gradient is accumulated into all the leaf Tensors that were used to compute the attr::tensors.
看到一篇比较清楚地讲解我把结论写在这里具体的参看原文 参考https://blog.csdn.net/witnessai1/article/details/79763596 Tensor必须是一个一维标量 如a v(t.FloatTensor([2, 3]), requires_gradTrue) m v(t.FloatTensor([[2, 3]]), requires_gradTrue) 则不行 会有如下报错 报错信息backward只能被应用在一个标量上也就是一个一维tensor或者传入跟变量相关的梯度。 特别注意Tensor里面默认的参数requires_gradFalserequires_grad True , 则表示它可以参与求导也可以从它向后求导。 requires_grad True 具有传递性如果x.requires_grad True y.requires_grad False zf(x,y)则z.requires_grad True Tensor.backward(parameters)接受的 参数parameters必须要和Tensor的大小一模一样然后作为Tensor的系数传回去 如果Tensor不是一个一维标量想要获取对应梯度需要计算jacobian矩阵。
loss.backward()和torch.autograd.grad的区别
参考loss.backward()和torch.autograd.grad的区别
loss.backward()会将求导结果累加在grad上。这也是为什么在训练每个batch的最开始需要对梯度清零的原因。torch.autograd.grad不会将求导结果累加在grad上。loss.backward()后非叶子节点的导数计算完成之后就会被清空。不过可以在非叶子节点之后加上 “非叶子节点.retain_grad()” 来解决这个问题。作用同requires_grad True torch.autograd.grad可以获取非叶子节点的梯度。PSPytorch中的张量有一个is_leaf的属性。若一个张量为叶子节点则其is_leaf属性就为True若这个张量为非叶子节点则其is_leaf属性就为False。一般地由用户自己创建的张量为叶子节点。另外神经网络中各层的权值weight和偏差bias对应的张量也为叶子节点。由叶子节点得到的中间张量为非叶子节点。在反向传播中叶子节点可以理解为不依赖其它张量的张量。
Pytorch中的自动求导机制会根据输入和前向传播过程自动构建计算图(节点就是参与运算的变量图中的边就是变量之间的运算关系)然后根据计算图进行反向传播计算每个节点的梯度值。
Pytorch提供了两种求梯度的方法分别是backward()和torch.autograd.grad()。
backward()方法可以计算根节点对应的所有叶子节点的梯度。如果不需要求出当前张量对所有产生该张量的叶子节点的梯度则可以使用torch.autograd.grad()。
不过需要注意的是这两种梯度方法都会在反向传播求导的时候释放计算图如果需要再次做自动求导因为计算图已经不再了就会报错。如果要在反向传播的时候保留计算图可以设置retain_graphTrue。
pytorch的计算图
参考https://zhuanlan.zhihu.com/p/33378444 pytorch是动态图机制所以在训练模型时候每迭代一次都会构建一个新的计算图。而计算图其实就是代表程序中变量之间的关系。举个列子 y ( a b ) ( b c ) y (ab)(bc) y(ab)(bc) 在这个运算过程就会建立一个如下的计算图 注意图中的 leaf_node叶子结点就是由用户自己创建的Variable变量在这个图中仅有abc 是 leaf_node。为什么要关注leaf_node因为在网络backward时候需要用链式求导法则求出网络最后输出的梯度然后再对网络进行优化如下就是网络的求导过程。 x Variable(torch.FloatTensor([[1, 2]]), requires_gradTrue) # 定义一个输入变量
y Variable(torch.FloatTensor([[3, 4], [5, 6]]))
loss torch.mm(x, y) # 变量之间的运算
loss.backward(torch.FloatTensor([[1, 0]]), retain_graphTrue) # 求梯度保留图
print(x.grad.data) # 求出 x_1 的梯度x.grad.data.zero_() # 最后的梯度会累加到叶节点所以叶节点清零loss.backward(torch.FloatTensor([[0, 1]])) # 求出 x_2的梯度
print(x.grad.data) # 求出 x_2的梯度这里有一点不太理解为什么loss.backward(torch.FloatTensor([[1, 0]]), retain_graphTrue)是对 x 1 x_1 x1求导而loss.backward(torch.FloatTensor([[0, 1]])) 是对 x 2 x_2 x2求导。
好像有一点明白了torch.FloatTensor([[1, 0]])中 x 2 x_2 x2为0