要设计卷积神经网络的结构,必须匹配层与层之间的输入与输出的尺寸,这就需要较好的计算输出尺寸
1. 卷积
卷积层的作用是提取输入图片中的信息,这些信息被称为图像特征,这些特征是由图像中的每个像素通过组合或者独立的方式所体现,比如图片的纹理特征,颜色特征。
卷积层有很多卷积核,通过做越来越多的卷积,提取到的图像特征会越来越抽象。
卷积后,图像尺寸计算公式为:**(图像大小 - 卷积核大小 + 2填充值) / 步长 + 1*
即:
其中:
N:输出矩阵的大小,N x N
W:输入图片的大小,W x W
K:卷积核kernel_size大小,K x K
P:填充值padding大小
S:步长stride大小
以resnet50为例,输入为[1, 3, 224, 224],其中1为 batchsize,3为通道数,224为height和width。
经过第一层卷积后,其大小为[1,64,112,112]
in_channels= 3 //输入通道,RGB图像作为输入时channels为3
out_channels= 64 //输出通道
nn.Conv2d(in_channels, out_channels, kernel_size=7, stride=2, padding=3, bias=False)
N = (W − K + 2P ) / S + 1 = (224 - 7 + 2 x 3) / 2 + 1 = 112
对矩阵和公式的理解:
1为batchsize,不改变。
对于通道数,会生成与设定的输出通道个数相同个数的卷积核,对图片进行卷积,即卷积核的个数等于输出特征图的通道数。
得到最终输出大小为[1,64,112,112]
(W − K + 2P )相当于计算除了第一次卷积后剩下的可用来卷积的大小
(W − K + 2P ) / S为按照S大小的步长在刚刚得到的大小上可以向后移动多少次,即:还可以做几次卷积
因为不包括第一次卷积,所以再加上一个1,
即N = (W − K + 2P )/S+1
输出大小 = (图片宽或高 - 卷积核大小 + padding大小)/ 步长 + 1
对于宽和高不同的图片可分别用上述公式计算,得到最终的输出大小
卷积动态图解参考:
https://cs231n.github.io/assets/conv-demo/index.html
2. 池化
池化层的作用是对卷积层中提取的特征进行挑选,分为最大池化和平均池化,就是对所有相应位置的数求最大或平均值,一般用来将高和宽降维。而1*1卷积中的降维降的是通道数的维度。
最大池化:Max Pooling,取窗口内的最大值作为输出
平均池化:Avg Pooling,去窗口内所有值的平均值作为输出
池化后,图像尺寸的计算公式为:**(图像大小 - 池化核大小 + 2填充值) / 步长 + 1*
即:
其中:
N:输出矩阵的大小,N x N
W:输入图片的大小,W x W
K:池化核kernel_size大小,K x K
P:填充值padding大小。池化一般不使用填充padding。
S:步长stride大小
池化会对特征进行降维,但是不会改变通道数
示例:
import torch
import torch.nn as nn
# 四维分别对应:(batch_size,channel,H,W)
im = torch.randn(1, 64, 112, 112)
# 卷积核为3*3,步长为2,上下左右各填充1行
c = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
output = c(im)
print("原张量尺寸:")
print(im.shape)
print("经最大池化处理后的张量尺寸:")
print(output.shape)
原张量尺寸为:[1, 64, 112, 112]
池化后张量尺寸为:[1, 64, 56, 56]