利用Pytorch从头开始搭建一个神经网络需要涉及到卷积层到池化层以及全连接层参数的计算。
本文以CIFAR10数据集为例介绍参数的计算过程(主要涉及到torch.nn.Conv2d、torch.nn.Linear、torch.nn.functional.maxpool2d)
下面是用来处理CIFAR10数据集的一个简单的神经网络
#input:[batch_size,channel,height,width]
# for CIFAR10: TRAINING_DATA[50000,3,32,32]
# NOTICE THAT [CHANNEL,HEIGHT,WIDTH] ACCORDS WITH THE REQUIREMENT OF
#PIL_IMAGE, NET_INPUT AND CIFAR_DATA_FORMAT
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
self.conv1=nn.Conv2d(3,6,5)
self.conv2=nn.Conv2d(6,16,5)
self.fc1=nn.Linear(16*5*5,120) # use linear mapping as fully-connection layer
self.fc2=nn.Linear(120,84)
self.fc3=nn.Linear(84,10)
def forward(self, x):
x = F.max_pool2d(F.relu(self.conv1(x)),2)
x = F.max_pool2d(F.relu(self.conv2(x)),2)
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
下面是三个API:
torch.nn.functional.max_pool3d(input, kernel_size, stride=None,
padding=0, dilation=1, ceil_mode=False, return_indices=False)
# NOTICE THAT THE DEFAULT VALUE OF STRIDE IS SET AS
#THE SAME AS KERNEL_SIZE
class torch.nn.Linear(in_features, out_features, bias=True)
class torch.nn.Conv2d(in_channels, out_channels, kernel_size,
stride=1, padding=0, dilation=1, groups=1, bias=True)
# Notice that padding 0 means that there is no padding
o u t _ s i z e = i n p u t _ s i z e − k e r n e l _ s i z e + p a d d i n g ∗ 2 s t r i d e + 1 out\_size = \frac{input\_size-kernel\_size+ padding*2}{stride}+1 out_size=strideinput_size−kernel_size+padding∗2+1
注意上面的公式是在没有采用空洞卷积的前提下进行计算的公式
关于stride
如果在横向和纵向的步长一样的话取int值即可;(k,m)代表纵向和横向的步长
关于padding
padding默认四周都补,增补值为0,默认padding=0不增补。当然也可以使用(k,m)分别代表在高度和宽度上的padding
padding值的含义:代表的是增补的列/行的数量,乘以2是因为这是对称的。例如padding=3,实际上在宽度上增加了3*2(左右两边)
注:上面的公式适用于对卷积/池化操作之后的height或是width的计算
示例
def __init__(self):
super(Net,self).__init__()
self.conv1=nn.Conv2d(3,6,5)
self.conv2=nn.Conv2d(6,16,5)
self.fc1=nn.Linear(16*5*5,120) # use linear mapping as fully-connection layer
self.fc2=nn.Linear(120,84)
self.fc3=nn.Linear(84,10)
本例中:经过第一层卷积之后width和height都变成28,之后经过kernel-size为2的池化后,width和height都变成14,再经过一层卷积,变成10。最后经过一层池化都变成5。
因此,最后第一层Linear的in_feature为上一层卷积的out_channel * height* width
[1] pytorch的padding的理解和操作
[2]PyTorch学习笔记(9)——nn.Conv2d和其中的padding策略
[3]Pytorch-学习记录 卷积操作——Tensor.size()