首页 > 编程知识 正文

pytorch中文教程,r语言predict函数

时间:2023-05-04 11:27:17 阅读:175221 作者:3547

通常,backward ) )函数是传递参数的,虽然不知道backward应该传递的参数的详细含义,但没关系。 生命在辛苦。 试着辛苦一下吧。 嘿嘿。

对标量的自动诱导

首先,如果out.backward ()的out是标量(神经网络有一个样本,这个样本有两个属性,神经网络有一个输出) )

导入种子

from torch.autogradimportvariable

a=variable (torch.tensor ([ 2,3 ],requires_grad=True ) ) ) ) ) ) ) ) ) )。

b=a 3

c=b * 3

out=c.mean ()

out.backward (

打印(input : ) )

打印(a.data ) )。

打印(输出: ) )

print(out.data.item ) )

打印(inputgradientsare : ) )

打印(a.grad ) )。

执行结果:

构建了这样的函数

所以,寻求其指引也很容易。

这是自动导出标量的结果。

向向量自动求导

如果out.backward () (out为向量) (或称为1xN矩阵),请自动引导向量以查看发生了什么。

首先构建这样的模型。 (神经网络有一个样本,这个样本有两个属性,相当于神经网络有两个输出。 )

导入种子

from torch.autogradimportvariable

a=variable(torch.tensor([2.4.] )、requires_grad=True ) ) )。

b=torch.zeros (1,2 ) ) ) ) ) ) ) ) b ) ) ) ) ) ) ) )。

b [ 0,0 ]=a [ 0,0 ] * * 2

b [ 0,1 ]=a [ 0,1 ] * * 3

out=2 * b

#其参数传递与out维相同的矩阵

out.backward (torch.float tensor ([1.1.] ) )

打印(input : ) )

打印(a.data ) )。

打印(输出: ) )

是打印(out.data )

打印(inputgradientsare : ) )

打印(a.grad ) )。

模型也很简单,out导出的雅可比应该如下。

因为a1=2,a2=4,所以上面的矩阵应该是:

执行结果:

嗯,确实是8和96,但是仔细想想,和我们想要的雅可比矩阵的形状也不一样啊。 是backward自动省略了0吗?

试着继续吧。 这次在前面的模型的基础上做如下稍微的变更。

导入种子

from torch.autogradimportvariable

a=variable(torch.tensor([2.4.] )、requires_grad=True ) ) )。

b=torch.zeros (1,2 ) ) ) ) ) ) ) ) b ) ) ) ) ) ) ) )。

b [ 0,0 ]=a [ 0,0 ] * * 2a [ 0,1 ]

b [ 0,1 ]=a [ 0,1 ] * * 3a [ 0,0 ]

out=2 * b

#其参数传递与out维相同的矩阵

out.backward (torch.float tensor ([1.1.] ) )

打印(输入: ) )

打印(a.data ) )。

打印(输出: ) )

是打印(out.data )

打印(inputgradientsare : ) )

打印(a.grad ) )。

这种型号的雅可比应该如下所示。

运行一下吧:

等等,什么事? 一般不是这样的

还是? 我是谁? 我已经在哪里了? 为什么给我两个数,而且82=10,962=98? 都是加2吗? 想想看。 刚才在我们backward上传递的参数是[ [ 1,1 ] ],是安装了这个关系并对应合计的吗? 换个参数试试吧。 在程序中,只有传入的参数是[]

1 , 2 ] ]:

import torch

from torch.autograd import Variable

a = Variable(torch.Tensor([[2.,4.]]),requires_grad=True)

b = torch.zeros(1,2)

b[0,0] = a[0,0] ** 2 + a[0,1]

b[0,1] = a[0,1] ** 3 + a[0,0]

out = 2 * b

#其参数要传入和out维度一样的矩阵

out.backward(torch.FloatTensor([[1.,2.]]))

print('input:')

print(a.data)

print('output:')

print(out.data)

print('input gradients are:')

print(a.grad)

嗯,这回可以了解了,我们传入的参数,是对原来模型正常求导出来的雅克比矩阵进行线性操作,可以把我们传进的参数(设为arg)看成一个列向量,那么我们得到的结果就是:

在这个题目中,我们得到的实际是:

看起来一切完美的解释了,但是就在我刚刚打字的一刻,我意识到官方文档中说k.backward()传入的参数应该和k具有相同的维度,所以如果按上述去解释是解释不通的。哪里出问题了呢?

仔细看了一下,原来是这样的:在对雅克比矩阵进行线性操作的时候,应该把我们传进的参数(设为arg)看成一个行向量(不是列向量),那么我们得到的结果就是:

也就是:

这回我们就解释的通了。

现在我们来输出一下雅克比矩阵吧,为了不引起歧义,我们让雅克比矩阵的每个数值都不一样(一开始分析错了就是因为雅克比矩阵中有相同的数据),所以模型小改动如下:

import torch

from torch.autograd import Variable

a = Variable(torch.Tensor([[2.,4.]]),requires_grad=True)

b = torch.zeros(1,2)

b[0,0] = a[0,0] ** 2 + a[0,1]

b[0,1] = a[0,1] ** 3 + a[0,0] * 2

out = 2 * b

#其参数要传入和out维度一样的矩阵

out.backward(torch.FloatTensor([[1,0]]),retain_graph=True)

A_temp = copy.deepcopy(a.grad)

a.grad.zero_()

out.backward(torch.FloatTensor([[0,1]]))

B_temp = a.grad

print('jacobian matrix is:')

print(torch.cat( (A_temp,B_temp),0 ))

如果没问题的话咱们的雅克比矩阵应该是 [ [ 8 , 2 ] , [ 4 , 96 ] ]

好了,下面是见证奇迹的时刻了,不要眨眼睛奥,千万不要眨眼睛… 3 2 1 砰…

好了,现在总结一下:因为经过了复杂的神经网络之后,out中每个数值都是由很多输入样本的属性(也就是输入数据)线性或者非线性组合而成的,那么out中的每个数值和输入数据的每个数值都有关联,也就是说【out】中的每个数都可以对【a】中每个数求导,那么我们backward()的参数[k1,k2,k3…kn]的含义就是:

也可以了解成每个out分量对an求导时的权重。

对矩阵自动求导

现在,如果out是一个矩阵呢?

下面的例子也可以了解为:相当于一个神经网络有两个样本,每个样本有两个属性,神经网络有两个输出。

import torch

from torch.autograd import Variable

from torch import nn

a = Variable(torch.FloatTensor([[2,3],[1,2]]),requires_grad=True)

w = Variable( torch.zeros(2,1),requires_grad=True )

out = torch.mm(a,w)

out.backward(torch.FloatTensor([[1.],[1.]]),retain_graph=True)

print("gradients are:{}".format(w.grad.data))

如果前面的例子了解了,那么这个也很好了解,backward输入的参数k是一个2x1的矩阵,2代表的就是样本数量,就是在前面的基础上,再对每个样本进行加权求和。结果是:

如果有兴趣,也可以拓展一下多个样本的多分类问题,猜一下k的维度应该是【输入样本的个数 * 分类的个数】

好啦,纠结我好久的pytorch自动求导原理算是彻底搞懂啦~~~

以上这篇浅谈Pytorch中的自动求导函数backward()所需参数的含义就是小编共享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持乐购源码。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。