Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neural network Pytorch,梯度参数是什么_Neural Network_Gradient_Pytorch_Torch_Gradient Descent - Fatal编程技术网

Neural network Pytorch,梯度参数是什么

Neural network Pytorch,梯度参数是什么,neural-network,gradient,pytorch,torch,gradient-descent,Neural Network,Gradient,Pytorch,Torch,Gradient Descent,我正在阅读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参数是什么?文档对此不是很清楚。这里,forward()的输出,即y是一个3向量 这三个值是网络输出处的渐变。如果y是最终输出,它们通常设置为1.0,但也可以有其他值,特别是

我正在阅读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参数是什么?文档对此不是很清楚。

这里,forward()的输出,即y是一个3向量

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

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

那么

在这里,向后的三个值是

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

然后backward()计算dz/dx

通常,您的计算图形有一个标量输出,表示
损失
。然后您可以通过
loss.backward()
计算
损耗的梯度
w.r.t.。权重(
w
)。其中
backward()
的默认参数为
1.0

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


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

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

解释 对于神经网络,我们通常使用
loss
来评估网络对输入图像(或其他任务)进行分类的能力。
损失
项通常是一个标量值。为了更新网络的参数,我们需要计算
loss
w.r.t对参数的梯度,这实际上是计算图中的
leaf node
(顺便说一下,这些参数主要是卷积、线性等各层的权重和偏差)

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

变量
方法的
梯度
参数用于计算变量w.r.t的每个元素的加权和。这些权重只是最终
损失
w.r.t中间变量的每个元素的导数

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

来自torch.autograd导入变量的

进口火炬
x=变量(torch.FloatTensor([[1,2,3,4]]),需要_grad=True)
z=2*x
损失=z.总和(dim=1)
#对z的第一个元素向后执行
z、 向后(torch.FloatTensor([[1,0,0,0]]),retain\u graph=True)
打印(x级数据)
x、 grad.data.zero#删除x.grad中的梯度,否则它将累积
#对z的第二个元素进行反向运算
z、 向后(torch.FloatTensor([[0,1,0,0]]),retain_graph=True)
打印(x级数据)
x、 grad.data.zero_uz()
#对z的所有元素进行反向计算,权重等于
#损失w.r.t z_1、z_2、z_3和z_4
z、 向后(torch.FloatTensor([[1,1,1,1]]),retain_graph=True)
打印(x级数据)
x、 grad.data.zero_uz()
#或者我们可以直接用损失来支持
loss.backward()#相当于loss.backward(torch.FloatTensor([1.0]))
打印(x级数据)
在上面的示例中,第一次打印的结果是

200
[torch.FLOTTENSOR,尺寸为1x4]

这就是z_1 w.r.t对x的导数

第二次
打印的结果是:

0200
[torch.FLOTTENSOR,尺寸为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
。因此,第三次
print
的输出是:

2
[torch.FLOTTENSOR,尺寸为1x4]

应该注意的是,权重向量[1,1,1,1]正好是
损耗
w.r.t对z_1、z_2、z_3和z_4的导数。
损失
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
因此,第四次
打印
的输出与第三次
打印
的输出相同:

2
[torch.FLOTTENSOR,尺寸为1x4]

我在PyTorch网站上再也找不到原始代码了

上面代码的问题是没有基于什么计算梯度的函数。这意味着我们不知道有多少参数(函数采用的参数)和参数的维数

为了充分理解这一点,我创建了一个与原文相近的示例:

例1:

我假设我们的函数是
y=3*a+2*b*b+torch.log(c)
,参数是张量,里面有三个元素

你可以想象梯度=torch.FloatTensor([0.1,1.0,0.0001])
就像这是累加器一样

正如您可能听说的,Pyrotch autograd系统计算相当于雅可比积

如果你有一个函数,就像我们做的那样:

y=3*a + 2*b*b + torch.log(c)
雅可比将是
[3,4*b,1/c]
。然而,Pytork并不是这样计算某个点的梯度的

PyTorch使用向前传球和(AD)串联

不涉及符号数学,也不涉及数值微分

数值微分是计算
δy/δb
,对于
b=1
b=1+ε
,其中ε很小

如果在
y.backward()中不使用渐变,请执行以下操作:

例2

您将在某一点上获得结果,具体取决于您如何设置
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(x.grad)
a = torch.tensor([1.0, 2.0, 3.0], requires_grad = True)
b = torch.tensor([3.0, 4.0, 5.0], requires_grad = True)
c = torch.tensor([6.0, 7.0, 8.0], requires_grad = True)

y=3*a + 2*b*b + torch.log(c)    
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients,retain_graph=True)    

print(a.grad) # tensor([3.0000e-01, 3.0000e+00, 3.0000e-04])
print(b.grad) # tensor([1.2000e+00, 1.6000e+01, 2.0000e-03])
print(c.grad) # tensor([1.6667e-02, 1.4286e-01, 1.2500e-05])
y=3*a + 2*b*b + torch.log(c)
a = torch.tensor(0.1, requires_grad = True)
b = torch.tensor(1.0, requires_grad = True)
c = torch.tensor(0.1, requires_grad = True)
y=3*a + 2*b*b + torch.log(c)

y.backward()

print(a.grad) # tensor(3.)
print(b.grad) # tensor(4.)
print(c.grad) # tensor(10.)
a = torch.empty(1, requires_grad = True, pin_memory=True)
b = torch.empty(1, requires_grad = True, pin_memory=True)
c = torch.empty(1, requires_grad = True, pin_memory=True)

y=3*a + 2*b*b + torch.log(c)

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

print(a.grad) # tensor([3.3003])
print(b.grad) # tensor([0.])
print(c.grad) # tensor([inf])
a = torch.tensor(1.0, requires_grad = True)
b = torch.tensor(1.0, requires_grad = True)
c = torch.tensor(1.0, requires_grad = True)
y=3*a + 2*b*b + torch.log(c)

y.backward(retain_graph=True)
y.backward()

print(a.grad) # tensor(6.)
print(b.grad) # tensor(8.)
print(c.grad) # tensor(2.)