Pytorch,什么是梯度参数

问题描述 投票:86回答:3

我正在阅读PyTorch的文档,并找到了他们编写的示例

gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(x.grad)

其中x是一个初始变量,从中构造y(一个3向量)。问题是,渐变张量的0.1,1.0和0.0001参数是什么?文档不是很清楚。

neural-network gradient pytorch torch gradient-descent
3个回答
82
投票

Explanation

对于神经网络,我们通常使用loss来评估网络学习对输入图像(或其他任务)进行分类的程度。 loss术语通常是标量值。为了更新网络的参数,我们需要计算loss wrt到参数的梯度,这实际上是计算图中的leaf node(顺便说一句,这些参数主要是各种层的权重和偏差,如卷积,线性等)。

根据链规则,为了计算loss w.r.t到叶节点的梯度,我们可以计算loss w.r.t的一些中间变量的导数,并将中间变量w.r.t的梯度计算到叶变量,做一个点积并将所有这些加起来。

gradientVariable方法的backward()论证用于计算变量w.r.t leaf Variable的每个元素的加权和。这些权重只是最终loss w.r.t中间变量的每个元素的推导。

A concrete example

让我们用一个具体而简单的例子来理解这一点。

from torch.autograd import Variable
import torch
x = Variable(torch.FloatTensor([[1, 2, 3, 4]]), requires_grad=True)
z = 2*x
loss = z.sum(dim=1)

# do backward for first element of z
z.backward(torch.FloatTensor([[1, 0, 0, 0]]), retain_graph=True)
print(x.grad.data)
x.grad.data.zero_() #remove gradient in x.grad, or it will be accumulated

# do backward for second element of z
z.backward(torch.FloatTensor([[0, 1, 0, 0]]), retain_graph=True)
print(x.grad.data)
x.grad.data.zero_()

# do backward for all elements of z, with weight equal to the derivative of
# loss w.r.t z_1, z_2, z_3 and z_4
z.backward(torch.FloatTensor([[1, 1, 1, 1]]), retain_graph=True)
print(x.grad.data)
x.grad.data.zero_()

# or we can directly backprop using loss
loss.backward() # equivalent to loss.backward(torch.FloatTensor([1.0]))
print(x.grad.data)    

在上面的例子中,第一个print的结果是

2 0 0 0 [火炬.FloatTensor大小1x4]

这正是z_1 w.r.t到x的导数。

第二个print的结果是:

0 2 0 0 [火炬.FloatTensor大小1x4]

这是z_2 w.r.t到x的导数。

现在,如果使用[1,1,1,1]的权重来计算z w.r.t到x的导数,则结果为1*dz_1/dx + 1*dz_2/dx + 1*dz_3/dx + 1*dz_4/dx。所以毫不奇怪,第3个print的输出是:

2 2 2 2 [火炬.FloatTensor大小1x4]

应该注意的是,权重向量[1,1,1,1]恰好是loss w.r.t到z_1,z_2,z_3和z_4的导数。 loss w.r.t到x的导数计算如下:

d(loss)/dx = d(loss)/dz_1 * dz_1/dx + d(loss)/dz_2 * dz_2/dx + d(loss)/dz_3 * dz_3/dx + d(loss)/dz_4 * dz_4/dx

因此第4个print的输出与第3个print相同:

2 2 2 2 [火炬.FloatTensor大小1x4]


36
投票

通常,您的计算图有一个标量输出,如loss。然后你可以计算loss w.r.t的梯度。 w的重量(loss.backward())。 backward()的默认参数是1.0

如果您的输出具有多个值(例如loss=[loss1, loss2, loss3]),则可以计算w.r.t的损失梯度。 loss.backward(torch.FloatTensor([1.0, 1.0, 1.0]))的重量。

此外,如果您想为不同的损失添加权重或重要性,您可以使用loss.backward(torch.FloatTensor([-0.1, 1.0, 0.0001]))

这意味着同时计算-0.1*d(loss1)/dw, d(loss2)/dw, 0.0001*d(loss3)/dw


25
投票

这里,forward()的输出,即y是3矢量。

这三个值是网络输出的梯度。如果y是最终输出,它们通常设置为1.0,但也可以设置其他值,尤其是如果y是更大网络的一部分。

例如。如果x是输入,y = [y1,y2,y3]是一个中间输出,用于计算最终输出z,

然后,

dz/dx = dz/dy1 * dy1/dx + dz/dy2 * dy2/dx + dz/dy3 * dy3/dx

所以这里,向后的三个值是

[dz/dy1, dz/dy2, dz/dy3]

然后向后()计算dz / dx

© www.soinside.com 2019 - 2024. All rights reserved.