本节要点:
1 卷积层
2 池化层
3 非线性激活层
4 正则层
5 循环层
6 线性层
7 Dropout层
8 Sparse层
9 Veision层
10 Multi-GPU层
in_channels(int) – 输入信号的通道
out_channels(int) – 卷积产生的通道
kerner_size(int or tuple) - 卷积核的尺寸
stride(int or tuple, optional) - 卷积步长
padding (int or tuple, optional)- 输入的每一条边补充0的层数
dilation(int or tuple, optional
) – 卷积核元素之间的间距
groups(int, optional) – 从输入通道到输出通道的阻塞连接数。制输入和输出之间的连接, group=1,输出是所有的输入的卷积;group=2,此时相当于有并排的两个卷积层,每个卷积层计算输入通道的一半,并且产生的输出是输出通道的一半,随后将这两个输出连接起来。
bias(bool, optional) - 如果bias=True,添加偏置
输入: (N,C_in,L_in)
输出: (N,C_out,L_out)
输入输出的计算方式:
L o u t = f l o o r ( ( L i n + 2 p a d d i n g − d i l a t i o n ( k e r n e r l s i z e − 1 ) − 1 ) / s t r i d e + 1 ) L_{out}=floor((L_{in}+2padding-dilation(kernerl_size-1)-1)/stride+1) Lout=floor((Lin+2padding−dilation(kernerlsize−1)−1)/stride+1)
变量是模型训练过程中要学习的对象,在卷积层中涉及两类:
weight(tensor) - 卷积的权重,大小是(out_channels, in_channels, kernel_size)
bias(tensor) - 卷积的偏置系数,大小是(out_channel)
下面给出一个构建一维卷积层的例子,并且感受一下输入输出的维度变化。
import torch
import torch.nn as nn
import torch.autograd as autograd
# 构建一个卷积层,inchannel是16需要与输入数据的channel一致
conv = nn.Conv1d(16, 33, 3, stride=2)
# 构建一个输如数据(比如20个样本,每个样本是16个channel, 每个channel是长度为50的一维向量)
input = autograd.Variable(torch.randn(20, 16, 50))
# 将数据输入卷积层进行前向计算(输出任然是20个样本,channel变成了33, 因为stride=2,因此每个channel中是一个长度24的一维向量)
output = conv(input)
print(output.size())
torch.Size([20, 33, 24])
二维和一维卷积的区别在于输入数据每个channel中是二维的还是一维的。一般我们输入的图像数据都是hight*width的二维图像。
in_channels(int) – 输入信号的通道
out_channels(int) – 卷积产生的通道
kerner_size(int or tuple) - 卷积核的尺寸
stride(int or tuple, optional) - 卷积步长
padding(int or tuple, optional) - 输入的每一条边补充0的层数
dilation(int or tuple, optional) – 卷积核元素之间的间距
groups(int, optional) – 从输入通道到输出通道的阻塞连接数
bias(bool, optional) - 如果bias=True,添加偏置
二维中,参数kernel_size,stride,padding,dilation可以是一个int的数据,也可以是一个二元的tuple类型,里面分别是hight和width对应的数值。
input: (N,C_in,H_in,W_in)
output: (N,C_out,H_out,W_out)
H o u t = f l o o r ( ( H i n + 2 p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] ( k e r n e r l s i z e [ 0 ] − 1 ) − 1 ) / s t r i d e [ 0 ] + 1 ) H_{out}=floor((H_{in}+2padding[0]-dilation[0](kernerl_size[0]-1)-1)/stride[0]+1) Hout=floor((Hin+2padding[0]−dilation[0](kernerlsize[0]−1)−1)/stride[0]+1)
W o u t = f l o o r ( ( W i n + 2 p a d d i n g [ 1 ] − d i l a t i o n [ 1 ] ( k e r n e r l s i z e [ 1 ] − 1 ) − 1 ) / s t r i d e [ 1 ] + 1 ) W_{out}=floor((W_{in}+2padding[1]-dilation[1](kernerl_size[1]-1)-1)/stride[1]+1) Wout=floor((Win+2padding[1]−dilation[1](kernerlsize[1]−1)−1)/stride[1]+1)
weight(tensor) - 卷积的权重,大小是(out_channels, in_channels,kernel_size)
bias(tensor) - 卷积的偏置系数,大小是(out_channel)
# 构建一个二维卷积层, strie可以是Int值,表示height,width都对应1
conv = nn.Conv2d(16, 33, 3, stride=2)
# 也可以是tuple
conv = nn.Conv2d(16, 33, (3,5), stride=(2,1), padding=(4, 2), dilation=(3, 1))
# 构建输入数据,16个channel, 每个channel中是50*100的二维矩阵
input = autograd.Variable(torch.randn(20, 16, 50, 100))
# 前向计算,注意输出维度的变化
output = conv(input)
print(output.size())
torch.Size([20, 33, 26, 100])
input: (N,C_in,D_in,H_in,W_in)
output: (N,C_out,D_out,H_out,W_out)
D o u t = f l o o r ( ( D i n + 2 p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] ( k e r n e r l s i z e [ 0 ] − 1 ) − 1 ) / s t r i d e [ 0 ] + 1 ) D_{out}=floor((D_{in}+2padding[0]-dilation[0](kernerl_size[0]-1)-1)/stride[0]+1) Dout=floor((Din+2padding[0]−dilation[0](kernerlsize[0]−1)−1)/stride[0]+1)
H o u t = f l o o r ( ( H i n + 2 p a d d i n g [ 1 ] − d i l a t i o n [ 2 ] ( k e r n e r l s i z e [ 1 ] − 1 ) − 1 ) / s t r i d e [ 1 ] + 1 ) H_{out}=floor((H_{in}+2padding[1]-dilation[2](kernerl_size[1]-1)-1)/stride[1]+1) Hout=floor((Hin+2padding[1]−dilation[2](kernerlsize[1]−1)−1)/stride[1]+1)
W o u t = f l o o r ( ( W i n + 2 p a d d i n g [ 2 ] − d i l a t i o n [ 2 ] ( k e r n e r l s i z e [ 2 ] − 1 ) − 1 ) / s t r i d e [ 2 ] + 1 ) W_{out}=floor((W_{in}+2padding[2]-dilation[2](kernerl_size[2]-1)-1)/stride[2]+1) Wout=floor((Win+2padding[2]−dilation[2](kernerlsize[2]−1)−1)/stride[2]+1)
参数个变量与一维和二维都是一样的。
因为是三维的,参数kernel_size,stride,padding,dilation可以是一个int的数据,也可以是一个三元的tuple类型。
下面给出一个例子:
# With square kernels and equal stride
m = nn.Conv3d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.Conv3d(16, 33, (3, 5, 2), stride=(2, 1, 1), padding=(4, 2, 0))
input = autograd.Variable(torch.randn(20, 16, 10, 50, 100))
output = m(input)
print(output.size())
torch.Size([20, 33, 8, 50, 99])
与一维,二维,三维卷积层对应,解卷积也有一维,二维,三维,参数都是一样的,就是名字略有不同,分别是:
class torch.nn.ConvTranspose1d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True)
class torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True)
class torch.nn.ConvTranspose3d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True)
参数都是一样的,要注意的是:由于内核的大小,输入的最后的一些列的数据可能会丢失。因为输入和输出是不是完全的互相关。因此,用户可以进行适当的填充(padding操作)。
in_channels(int) – 输入信号的通道数
out_channels(int) – 卷积产生的通道
kernel_size(int or tuple) - 卷积核的大小
stride(int or tuple, optional) - 卷积步长
padding(int or tuple, optional) - 输入的每一条边补充0的层数
output_padding(int or tuple, optional) - 输出的每一条边补充0的层数
dilation(int or tuple, optional) – 卷积核元素之间的间距
groups(int, optional) – 从输入通道到输出通道的阻塞连接数
bias(bool, optional) - 如果bias=True,添加偏置
参数kernel_size,stride, padding,dilation数据类型: 一个int类型的数据,此时卷积height和width值相同; 也可以是一个tuple数组(包含来两个/三个int类型的数据),第一个int数据表示height的数值,tuple的第二个int类型的数据表示width的数值
变量也是一样的。
weight(tensor) - 卷积的权重,大小是(in_channels, in_channels,kernel_size)
bias(tensor) - 卷积的偏置系数,大小是(out_channel)
一维:
二维:
W o u t = ( W i n − 1 ) s t r i d e [ 1 ] − 2 p a d d i n g [ 1 ] + k e r n e l s i z e [ 1 ] + o u t p u t p a d d i n g [ 1 ] W_{out}=(W_{in}-1)stride[1]-2padding[1]+kernel_size[1]+output_padding[1] Wout=(Win−1)stride[1]−2padding[1]+kernelsize[1]+outputpadding[1]
三维:
H o u t = ( H i n − 1 ) s t r i d e [ 1 ] − 2 p a d d i n g [ 1 ] + k e r n e l s i z e [ 1 ] + o u t p u t p a d d i n g [ 0 ] H_{out}=(H_{in}-1)stride[1]-2padding[1]+kernel_size[1]+output_padding[0] Hout=(Hin−1)stride[1]−2padding[1]+kernelsize[1]+outputpadding[0]
W o u t = ( W i n − 1 ) s t r i d e [ 2 ] − 2 p a d d i n g [ 2 ] + k e r n e l s i z e [ 2 ] + o u t p u t p a d d i n g [ 2 ] W_{out}=(W_{in}-1)stride[2]-2padding[2]+kernel_size[2]+output_padding[2] Wout=(Win−1)stride[2]−2padding[2]+kernelsize[2]+outputpadding[2]
给出三维的例子:
# With square kernels and equal stride
m = nn.ConvTranspose3d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.Conv3d(16, 33, (3, 5, 2), stride=(2, 1, 1), padding=(0, 4, 2))
input = autograd.Variable(torch.randn(20, 16, 10, 50, 100))
output = m(input)
print(output.size())
torch.Size([20, 33, 4, 54, 103])
池化层根据计算方式不同可以分为:最大池化,平均池化。
根据操作方式不同可以分为:普通池化、分数池化、幂池化、自适应池化。
根据维度不同可分为:一维、二维、三维。
和卷积层一样,普通的最大池化中也是分为一维,二维,三维的。除了名字不一样,参数是一样的。
在二维和三维中,参数kernel_size,stride, padding,dilation数据类型: 可以是一个int类型的数据,此时卷积height和width值相同; 也可以是一个tuple数组(包含来两个int类型的数据),第一个int数据表示height的数值,tuple的第二个int类型的数据表示width的数值
一维:
二维:
W o u t = f l o o r ( ( W i n + 2 p a d d i n g [ 1 ] − d i l a t i o n [ 1 ] ( k e r n e l s i z e [ 1 ] − 1 ) − 1 ) / s t r i d e [ 1 ] + 1 W_{out}=floor((W_{in} + 2padding[1] - dilation[1](kernel_size[1] - 1) - 1)/stride[1] + 1 Wout=floor((Win+2padding[1]−dilation[1](kernelsize[1]−1)−1)/stride[1]+1
三维:
H o u t = f l o o r ( ( H i n + 2 p a d d i n g [ 1 ] − d i l a t i o n [ 1 ] ( k e r n e l s i z e [ 0 ] − 1 ) − 1 ) / s t r i d e [ 1 ] + 1 ) H_{out}=floor((H_{in} + 2padding[1] - dilation[1](kernel_size[0] - 1) - 1)/stride[1] + 1) Hout=floor((Hin+2padding[1]−dilation[1](kernelsize[0]−1)−1)/stride[1]+1)
W o u t = f l o o r ( ( W i n + 2 p a d d i n g [ 2 ] − d i l a t i o n [ 2 ] ( k e r n e l s i z e [ 2 ] − 1 ) − 1 ) / s t r i d e [ 2 ] + 1 ) W_{out}=floor((W_{in} + 2padding[2] - dilation[2](kernel_size[2] - 1) - 1)/stride[2] + 1) Wout=floor((Win+2padding[2]−dilation[2](kernelsize[2]−1)−1)/stride[2]+1)
import torch
import torch.nn as nn
import torch.autograd as autograd
# 1. 创建一个一维最大池化层
p1 = nn.MaxPool1d(3, stride=2)
# 创建一个输入变量
input = autograd.Variable(torch.randn(20, 16, 50))
# 前向计算
output = p1(input)
print(output.size())
# 2. 创建一个二维最大池化层
p2 = nn.MaxPool2d((3,2), stride=(2,1))
# 创建一个输入变量
input = autograd.Variable(torch.randn(20, 16, 50, 32))
# 前向计算
output = p2(input)
print(output.size())
# 2. 创建一个三维最大池化层
p3 = nn.MaxPool3d((3,2, 1), stride=(2,1, 1))
# 创建一个输入变量
input = autograd.Variable(torch.randn(20, 16, 50, 32, 20))
# 前向计算
output = p3(input)
print(output.size())
torch.Size([20, 16, 24])
torch.Size([20, 16, 24, 31])
torch.Size([20, 16, 24, 31, 20])
与最大池化相对应的有最大逆池化。
MaxUnpool是Maxpool的逆过程,不过并不是完全的逆过程,因为在maxpool1d的过程中,一些最大值的已经丢失。 MaxUnpool1d输入MaxPool1d的输出,包括最大值的索引,并计算所有maxpool1d过程中非最大值被设置为零的部分的反向。
MaxPool1d可以将多个输入大小映射到相同的输出大小。因此,反演过程可能会变得模棱两可。 为了适应这一点,可以在调用中将输出大小(output_size)作为额外的参数传入。 具体用法,请参阅下面的输入和示例
同样也有三个维度:
一维:
二维:
H o u t = ( H i n − 1 ) s t r i d e [ 0 ] − 2 p a d d i n g [ 0 ] + k e r n e l s i z e [ 0 ] H_{out}=(H_{in}-1)stride[0]-2padding[0]+kernel_size[0] Hout=(Hin−1)stride[0]−2padding[0]+kernelsize[0]
W o u t = ( W i n − 1 ) s t r i d e [ 1 ] − 2 p a d d i n g [ 1 ] + k e r n e l s i z e [ 1 ] W_{out}=(W_{in}-1)stride[1]-2padding[1]+kernel_size[1] Wout=(Win−1)stride[1]−2padding[1]+kernelsize[1]
也可以使用output_size指定输出的大小
三维:
以一维池化举例:
# 创建一个池化层
p = nn.MaxPool1d(2, stride=2, return_indices=True)
# 创建一个逆池化层
up = nn.MaxUnpool1d(2, stride=2)
# 创建输入变量1*1*8
input = autograd.Variable(torch.Tensor([[[1, 2, 3, 4, 5, 6, 7, 8]]]))
# 池化层计算
output, indices = p(input)
# 逆池化
up_output = up(output, indices)
print(up_output)
tensor([[[ 0., 2., 0., 4., 0., 6., 0., 8.]]])
# 可以用output_size来指定输出的大小
# 逆池化
up_output = up(output, indices,output_size=input.size())
print(up_output)
tensor([[[ 0., 2., 0., 4., 0., 6., 0., 8.]]])
参考最大池化层
以一维为例,其他可参考最大池化层
import torch
import torch.nn as nn
import torch.autograd as autograd
# 1. 创建一个一维最大池化层
p1 = nn.AvgPool1d(3, stride=2)
# 创建一个输入变量
input = autograd.Variable(torch.randn(20, 16, 50))
# 前向计算
output = p1(input)
print(output.size())
torch.Size([20, 16, 24])
对输入的信号,提供2维的分数最大化池化操作 分数最大化池化的细节请阅读论文:https://arxiv.org/abs/1412.6071
由目标输出大小确定的随机步长,在 k H ∗ k W kH*kW kH∗kW区域进行最大池化操作。输出特征和输入特征的数量相同。
# 可以用确定的值来设定输出的大小
m = nn.FractionalMaxPool2d(3, output_size=(13, 12))
# 可以用分数比例来设定输出的大小
m = nn.FractionalMaxPool2d(3, output_ratio=(0.5, 0.5))
input = autograd.Variable(torch.randn(20, 16, 50, 32))
output = m(input)
print(output.size())
torch.Size([20, 16, 25, 16])
对输入信号提供2维的幂平均池化操作。 输出的计算方式: f(x)=pow(sum(X,p),1/p)
当p为无穷大的时候时,等价于最大池化操作
当p=1时,等价于平均池化操作
参数kernel_size, stride的数据类型:
# power-2 pool of square window of size=3, stride=2
m = nn.LPPool2d(2, 3, stride=2)
# pool of non-square window of power 1.2
m = nn.LPPool2d(1.2, (3, 2), stride=(2, 1))
input = autograd.Variable(torch.randn(20, 16, 50, 32))
output = m(input)
print(output.size())
torch.Size([20, 16, 24, 31])
对输入信号,提供1维或2维的自适应最大池化操作 对于任何输入大小的输入,可以将输出尺寸指定为H,但是输入和输出特征的数目不会变化。
# 一维,指定大小为5
m = nn.AdaptiveMaxPool1d(5)
input = autograd.Variable(torch.randn(1, 64, 8))
output = m(input)
print(output.size())
torch.Size([1, 64, 5])
# 二维,指定大小为(5,7)
m = nn.AdaptiveMaxPool2d((5,7))
input = autograd.Variable(torch.randn(1, 64, 8, 9))
# 二维,指定大小为(7,7)
m = nn.AdaptiveMaxPool2d(7)
input = autograd.Variable(torch.randn(1, 64, 10, 9))
output = m(input)
print(output.size())
torch.Size([1, 64, 7, 7])
自适应平均池化与自适应最大池化类似,但参数只有:
# target output size of 5x7
m = nn.AdaptiveAvgPool2d((5,7))
input = autograd.Variable(torch.randn(1, 64, 8, 9))
# target output size of 7x7 (square)
m = nn.AdaptiveAvgPool2d(7)
input = autograd.Variable(torch.randn(1, 64, 10, 9))
output = m(input)
print(output.size())
torch.Size([1, 64, 7, 7])
类名 | 参数 | 公式 |
---|---|---|
class torch.nn.ReLU(inplace=False) | inplace-选择是否进行覆盖运算 | R e L U ( x ) = m a x ( 0 , x ) {ReLU}(x)= max(0, x) ReLU(x)=max(0,x) |
class torch.nn.ReLU6(inplace=False) | inplace-选择是否进行覆盖运算 | R e L U 6 ( x ) = m i n ( m a x ( 0 , x ) , 6 ) {ReLU6}(x) = min(max(0,x), 6) ReLU6(x)=min(max(0,x),6) |
class torch.nn.ELU(alpha=1.0, inplace=False) | f ( x ) = m a x ( 0 , x ) + m i n ( 0 , a l p h a ∗ ( e x − 1 ) ) f(x) = max(0,x) + min(0, alpha * (e^x - 1)) f(x)=max(0,x)+min(0,alpha∗(ex−1)) | |
class torch.nn.PReLU(num_parameters=1, init=0.25) | num_parameters:需要学习的a的个数,默认等于1; init:a的初始值,默认等于0.25 |
P R e L U ( x ) = m a x ( 0 , x ) + a ∗ m i n ( 0 , x ) PReLU(x) = max(0,x) + a * min(0,x) PReLU(x)=max(0,x)+a∗min(0,x) |
class torch.nn.Threshold(threshold, value, inplace=False) | threshold:阈值 value:输入值小于阈值则会被value代替 inplace:选择是否进行覆盖运算 |
y = x , i f x > = t h r e s h o l d y = v a l u e , i f x < t h r e s h o l d y=x,if x>=threshold y=value,if x<threshold y=x,ifx>=thresholdy=value,ifx<threshold |
class torch.nn.Sigmoid | 无 | f ( x ) = 1 / ( 1 + e − x ) f(x)=1/(1+e−x) f(x)=1/(1+e−x) |
class torch.nn.Tanh | 无 | f ( x ) = e x − e − x e x + e x f(x)=ex−e−xex+ex f(x)=ex−e−xex+ex |
class torch.nn.LogSigmoid | 无 | L o g S i g m o i d ( x ) = l o g ( 1 / ( 1 + e − x ) ) LogSigmoid(x) = log( 1 / ( 1 + e^{-x})) LogSigmoid(x)=log(1/(1+e−x)) |
class torch.nn.Softplus(beta=1, threshold=20) | beta:Softplus函数的beta值 threshold:阈值 |
f ( x ) = 1 b e t a ∗ l o g ( 1 + e ( b e t a ∗ x i ) ) f(x)=1beta∗log(1+e(beta∗xi)) f(x)=1beta∗log(1+e(beta∗xi)) |
class torch.nn.Softshrink(lambd=0.5) | lambd:Softshrink函数的lambda值,默认为0.5 | f ( x ) = x − l a m b d a , i f x > l a m b d a f ( x ) = x + l a m b d a , i f x < − l a m b d a f ( x ) = 0 , o t h e r w i s e f(x)=x−lambda,if x>lambda f(x)=x+lambda,if x<−lambda f(x)=0,otherwise f(x)=x−lambda,ifx>lambdaf(x)=x+lambda,ifx<−lambdaf(x)=0,otherwise |
class torch.nn.Softsign | 无 | $f(x) = x / (1 + |
class torch.nn.Tanhshrink | 无 | T a n h s h r i n k ( x ) = x − T a n h ( x ) Tanhshrink(x)=x−Tanh(x) Tanhshrink(x)=x−Tanh(x) |
class torch.nn.Softmin | 无 | f i ( x ) = e ( − x i − s h i f t ) / ∑ j e ( − x j − s h i f t ) , s h i f t = m a x ( x i ) fi(x)=e(−xi−shift)/∑je(−xj−shift),shift=max(xi) fi(x)=e(−xi−shift)/∑je(−xj−shift),shift=max(xi) |
class torch.nn.Softmax | 无 | f i ( x ) = e ( x i − s h i f t ) / ∑ j e ( x j − s h i f t ) , s h i f t = m a x ( x i ) fi(x)=e(xi−shift)/∑je(xj−shift),shift=max(xi) fi(x)=e(xi−shift)/∑je(xj−shift),shift=max(xi) |
class torch.nn.LogSoftmax | 无 | f i ( x ) = l o g e ( x i ) / a , a = ∑ j e ( x j ) fi(x)=loge(xi)/a,a=∑je(xj) fi(x)=loge(xi)/a,a=∑je(xj) |
下面举一个例子,其他以此类推。
# 创建一个激活函数Module
m = nn.Softmax()
# 创建输入变量
input = autograd.Variable(torch.randn(2, 3))
print(input)
print(m(input))
tensor([[ 1.7255, -0.2483, -0.4758],
[ 0.2217, 1.4740, -1.6893]])
tensor([[ 0.8003, 0.1112, 0.0886],
[ 0.2152, 0.7529, 0.0318]])
/Users/wangxiaocao/miniconda3/lib/python3.6/site-packages/ipykernel_launcher.py:8: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.
对输入数据做线性变换:y=Ax+b
# 创建一个线性激活层module
m = nn.Linear(20, 30)
# 创建输入变量
input = autograd.Variable(torch.randn(128, 20))
# 线性计算
output = m(input)
print(output.size())
torch.Size([128, 30])
对小批量(mini-batch)输入进行批标准化(Batch Normalization)操作
在每一个小批量(mini-batch)数据中,计算输入各个维度的均值和标准差。gamma与beta是可学习的大小为C的参数向量(C为输入大小)
在训练时,该层计算每次输入的均值与方差,并进行移动平均。移动平均默认的动量值为0.1。
在验证时,训练求得的均值/方差将用于标准化验证数据。
一维:该期望输入的大小为’batch_size x num_features [x width]’
二维:该期望输入的大小为’batch_size x num_features x height x width’
三维:该期望输入的大小为’batch_size x num_features depth x height x width’
输入与输出相同。
# With Learnable Parameters
m = nn.BatchNorm3d(100)
# Without Learnable Parameters
m = nn.BatchNorm3d(100, affine=False)
input = autograd.Variable(torch.randn(20, 100, 35, 45, 10))
output = m(input)
print(output.size())
torch.Size([20, 100, 35, 45, 10])
目前提供三类最常用的循环网络:普通的RNN,LSTM,GRU。
RNN:
LSTM:
GRU:
input (seq_len, batch, input_size): 保存输入序列特征的tensor。input可以是被填充的变长的序列。细节请看torch.nn.utils.rnn.pack_padded_sequence()
h_0 (num_layers * num_directions, batch, hidden_size): 保存着初始隐状态的tensor
weight_ih_l[k] – 第k层的 input-hidden 权重, 可学习,形状是(input_size x hidden_size)。
weight_hh_l[k] – 第k层的 hidden-hidden 权重, 可学习,形状是(hidden_size x hidden_size)
bias_ih_l[k] – 第k层的 input-hidden 偏置, 可学习,形状是(hidden_size)
bias_hh_l[k] – 第k层的 hidden-hidden 偏置, 可学习,形状是(hidden_size)
以GRU为例,其他二者可参考:
# 创建一个GRU循环神经网络,输入维度=10,hiden_size=20,hiden_layer=2
rnn = nn.GRU(10, 20, 2)
# 构建2个输入数据
# 3个样本,每个样本的序列长度是5,序列中每个元素的特征长度是10
input = autograd.Variable(torch.randn(5, 3, 10))
# GRU层数2,3个样本,隐层的输出维度是20
h0 = autograd.Variable(torch.randn(2, 3, 20))
# 计算,有2个输出
output, hn = rnn(input, h0)
print(output.size())
print(hn.size())
torch.Size([5, 3, 20])
torch.Size([2, 3, 20])
注意,6.1可以一次性构建多层的整个循环神经网络,这一节讲的是构建一个循环单元,可以通过for循环将多个单元组合起来。也就是说多个时间维度上的cell组合起来才是完整的循环网络。
input_size – 输入 x x x,特征的维度。
hidden_size – 隐状态特征的维度。
bias – 如果为False,RNN cell中将不会加入bias,默认为True。
nonlinearity – 用于选择非线性激活函数 [tanh|relu]. 默认值为: tanh。在LSTM和GRU中没有该参数。
RNN:
input (batch, input_size): 包含输入特征的tensor。
hidden (batch, hidden_size): 保存着初始隐状态值的tensor。
LSTM和GRU:将hidden换成一下两个输入:
h_0 ( batch, hidden_size):保存着batch中每个元素的初始化隐状态的Tensor
c_0 (batch, hidden_size): 保存着batch中每个元素的初始化细胞状态的Tensor
RNN,GRU:
LSTM:
weight_ih – input-hidden 权重, 可学习,形状是(input_size x hidden_size)。
weight_hh – hidden-hidden 权重, 可学习,形状是(hidden_size x hidden_size)
bias_ih – input-hidden 偏置, 可学习,形状是(hidden_size)
bias_hh – hidden-hidden 偏置, 可学习,形状是(hidden_size)
以GRU为例,其他二者可参考:
# 构建GRUcell,input_feature_size = 10, hidden_size=20
rnn = nn.GRUCell(10, 20)
# 构造输入变量,
# 序列长度=6,batch_size=3, input_size=10
input = autograd.Variable(torch.randn(6, 3, 10))
# batch_size=3, hidden_size=20
hx = autograd.Variable(torch.randn(3, 20))
output = []
for i in range(6):
# 输出隐层
hx = rnn(input[i], hx)
output.append(hx)
print(len(output))
6
1d:
2d:
3d:
# 创建一个dropout层module
m = nn.Dropout(p=0.2)
input = autograd.Variable(torch.randn(20, 16))
output = m(input)
print(output.size())
torch.Size([20, 16])
# 创建一个dropout2d层module
m = nn.Dropout(p=0.2)
input = autograd.Variable(torch.randn(20, 16, 32,32))
output = m(input)
print(output.size())
torch.Size([20, 16, 32, 32])
# 创建一个dropout3d层module
m = nn.Dropout(p=0.2)
input = autograd.Variable(torch.randn(20, 16, 4,32,32))
output = m(input)
print(output.size())
torch.Size([20, 16, 4, 32, 32])
一个保存了固定字典和大小的简单查找表。
这个模块常用来保存词嵌入和用下标检索它们。模块的输入是一个下标的列表,输出是对应的词嵌入。
# 创建一个Sparse层module,10个词,每个词向量长度为3
embedding = nn.Embedding(10, 3)
# 创建一批数据,包含两个样本,每个样本的fetaure长度为4
input = autograd.Variable(torch.LongTensor([[1,2,3,4],[5,6,7,8]]))
input_emb = embedding(input)
print(input_emb)
tensor([[[ 0.1388, 1.0344, 0.4986],
[ 1.2887, -0.2868, 1.8511],
[-0.2473, 0.3659, -2.0664],
[ 0.4521, -0.3340, 1.0321]],
[[ 1.0713, 0.8976, -0.1969],
[-0.4481, -0.7756, 0.5349],
[ 2.1492, 1.2860, 1.2949],
[ 1.1719, -1.3687, -1.8749]]])
# example with padding_idx
embedding = nn.Embedding(10, 3, padding_idx=0)
input = autograd.Variable(torch.LongTensor([[0,2,0,5]]))
print(embedding(input))
tensor([[[ 0.0000, 0.0000, 0.0000],
[ 1.0288, 1.4577, -0.4938],
[ 0.0000, 0.0000, 0.0000],
[ 1.5563, -1.6282, -0.2595]]])