Pytorch相关函数详解

一、backward()

pytorch中的自动求导函数。一个神经网络有N个样本,经过这个网络把N个样本分为M类,那么此时backward参数的维度应该是【N * M】。正常来说backward()函数是不需要传入函数的,有时候也需要传入参数,现在来了解backward()需要传入的参数具体含义。

不需要传入参数的例子

如果out.backward()中的out是一个标量的话(相当于一个神经网络有一个样本,这个样本有两个属性,神经网络有一个输出)那么此时我的backward函数是不需要输入任何参数的。

import torch
from torch.autograd import Variable
a=Variable(torch.Tensor([2,3]),requires_grad=True)
b=a+3
c=b*3
out=c.mean()
out.backward()
print('input:{}'.format(a.data))
print('output:{}'.format(out.data.item()))
print('input grads are:{}'.format(a.grad))

输出:input:tensor([2., 3.])
output:16.5
input grads are:tensor([1.5000, 1.5000])

不难看出,我们构建了这样的一个函数:

     

所以其求导也很容易看出:

    

这是对其进行标量自动求导的结果。

需要传入参数的backward()

如果out.backward()中的out是一个向量(或者理解成1xN的矩阵)的话,我们对向量进行自动求导,看看会发生什么?

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

import torch
from torch.autograd import Variable
a=Variable(torch.FloatTensor([[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]**2+a[0,0]
out=2*b
#其参数要传入和out维度一样的矩阵
out.backward(torch.FloatTensor([[1.,1.]]))
print('input:{}'.format(a.data))
print('output:{}'.format(out.data))
print('input gradients are:{}'.format(a.grad))

输出:input:tensor([[2., 4.]])
output:tensor([[16., 36.]])
input gradients are:tensor([[10., 18.]])

上面的a.grad输出为什么是[[10.,18.]]呢?其实跟backward的输入参数torch.FloatTensor[[1.,1.,]]有关。k.backward(parameters)接受的参数parameters必须要和k的大小一模一样,然后作为k的系数传回去,什么意思呢,我们通过上面的例子来解释这个问题你就知道了。

我们已经知道我们得到的out=(out1,out2)k=(k1,k2),以及传入的参数是1和1,那么是如何得到这10和18这两个结果的呢?

其实第一个结果是通过1*\frac{\mathrm{dk1} }{\mathrm{d} x1}+1*\frac{\mathrm{dk2} }{\mathrm{d} x1}=2*(2*x1+1)=10这样得到的,2是out=2*b中的2。是不是有点理解这个操作是怎么完成的了,我们再来看看第二个结果,1*\frac{\mathrm{dk1} }{\mathrm{d} x2}+1*\frac{\mathrm{dk2} }{\mathrm{d} x2}=2*(1+2*x2)=18,这样我们就得到了这两个结果,原来我们传入的参数是每次求导的一个系数。

二、torch.gather()

函数torch.gather(input, dim, index, out=None) → Tensor沿给定轴 dim ,将输入索引张量 index 指定位置的值进行聚合.
对一个 3 维张量,输出可以定义为:

out[i][j][k] = input[index[i][j][k]][j][k]  # if dim == 0
out[i][j][k] = input[i][index[i][j][k]][k]  # if dim == 1
out[i][j][k] = input[i][j][index[i][j][k]]  # if dim == 2

三、nn.functional()

nn中还有一个很常用的模块:nn.functional,nn中的大多数layer,在functional中都有一个与之相对应的函数。比如conv2d,max_poll2d等等layer。nn.functional中的函数和nn.Module的主要区别在于,用nn.Module实现的layers是一个特殊的类,都是由class layer(nn.Module)定义,会自动提取可学习的参数。而nn.functional中的函数更像是纯函数,由def function(input)定义。

四、view()

view函数的作用为重构张量的维度,相当于numpy中resize()的功能,但是用法可能不太一样。如下例所示

import torch
tt1=torch.tensor([-0.3623, -0.6115,  0.7283,  0.4699,  2.3261,  0.1599])
result=tt1.view(3,2)
print(result)

tensor([[-0.3623, -0.6115],
        [ 0.7283,  0.4699],
        [ 2.3261,  0.1599]])

 1、torch.view(参数a,参数b,...)

在上面例子中参数a=3和参数b=2决定了将一维的tt1重构成3x2维的张量。

2、有的时候会出现torch.view(-1)或者torch.view(参数a,-1)这种情况。

import torch
tt2=torch.tensor([[-0.3623, -0.6115],
            [ 0.7283,  0.4699],
            [ 2.3261,  0.1599]])
result=tt2.view(-1)
>>> result
tensor([-0.3623, -0.6115,  0.7283,  0.4699,  2.3261,  0.1599])

 由上面的代码可以看到,如果是torch.view(-1),则原张量会变成一维的结构。

import torch
>>> tt3=torch.tensor([[-0.3623, -0.6115],
            [ 0.7283,  0.4699],
            [ 2.3261,  0.1599]])
result=tt3.view(2,-1)
>>> result
tensor([[-0.3623, -0.6115,  0.7283],
        [ 0.4699,  2.3261,  0.1599]])

由上面的代码可以看到,如果是torch.view(参数a,-1),则表示在参数b未知,参数a已知的情况下自动补齐列向量长度,在这个例子中a=2,tt3总共由6个元素,则b=6/2=3。 

五、scatter_()

scatter_(input, dim, index, src)将src中数据根据index中的索引按照dim的方向填进input中。

>>> x = torch.rand(2, 5)
>>> x

 0.4319  0.6500  0.4080  0.8760  0.2355
 0.2609  0.4711  0.8486  0.8573  0.1029
[torch.FloatTensor of size 2x5]

LongTensor的shape刚好与x的shape对应,也就是LongTensor每个index指定x中一个数据的填充位置。dim=0,表示按行填充。举例LongTensor中的第0行第2列index=2,表示在第2行(从0开始)进行填充填充,对应到zeros(3, 5)中就是位置(2,2);LongTensor中的第0行第0列index=0,表示在第零行开始填充。所以此处要求zeros(3, 5)的列数要与x列数相同,而LongTensor中的index最大值应与zeros(3, 5)行数相一致。如下代码所示:

>>> torch.zeros(3, 5).scatter_(0, torch.LongTensor([[0, 1, 2, 0, 0], [2, 0, 0, 1, 2]]), x)

 0.4319  0.4711  0.8486  0.8760  0.2355
 0.0000  0.6500  0.0000  0.8573  0.0000
 0.2609  0.0000  0.4080  0.0000  0.1029
[torch.FloatTensor of size 3x5]

六、torch.clamp()

torch.clamp(input, min, max, out=None)

将输入input张量每个元素的范围限制到区间 [min,max],返回结果到一个新张量。

input (Tensor) – 输入张量
min (Number) – 限制范围下限
max (Number) – 限制范围上限
out (Tensor, optional) – 输出张量

当输入值小于min时,输出为min;当输入值大于max时,输出为max;当输入值介于两者之间时,输出输入的值。

a=torch.randint(low=0,high=10,size=(10,1))
print(a)
a=torch.clamp(a,3,9)
print(a)

输出为:

发布了139 篇原创文章 · 获赞 49 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/xiewenrui1996/article/details/104325260