目录
1.标准卷积Standard/Plain Convolution
1.1.卷积演示Convolution Demo。
1.2.卷积的特征提取
2.实例:PyTorch卷积实现代码
CNNs[1]中的卷积,也称为滤波器,其本质上是由一组带参数的卷积核所组成,它是通过卷积核来提取出图片中的局部特征。如下图所示,卷积的过程其实就是通过将滤波器从上到下,从左到右进行遍历,每匹配一次即对相应位置的元素进行加权求和输出.
红色示例输入体积(例如 32x32x3 CIFAR-10 图像),以及第一个卷积层中的神经元示例体积。卷积层中的每个神经元在空间上仅连接到输入体积中的局部区域,但连接到全深度(即所有颜色通道)。请注意,沿深度有多个神经元(本例中为 5 个),它们都在输入中的同一区域:连接这列 5 个神经元的线不代表权重(即这 5 个神经元不共享相同的权重)权重,但它们与 5 个不同的过滤器相关联),它们只是表明这些神经元连接到或查看输入体积的相同感受野或区域,即它们共享相同的感受野但不同的权重。神经网络章节中的神经元保持不变:它们仍然计算权重与输入的点积,然后是非线性,但它们的连接性现在被限制为局部空间。
卷积运算本质上就是在滤波器和输入数据的局部区域间做点积。
下面是一个 CONV 层的运行演示。由于 3D 体积难以可视化,因此所有体积(输入体积(蓝色)、权重体积(红色)、输出体积(绿色))都被可视化,每个深度切片堆叠成行。输入体积大小W1= 5 ,H1= 5 ,D1= 3W1=5,H1=5,D1=3, CONV 层参数为ķ= 2 , F= 3 , S= 2 , P= 1ķ=2,F=3,小号=2,磷=1. 也就是说,我们有两个大小为3 × 33×3,并且它们以 2 的步幅应用。因此,输出体积大小的空间大小为 (5 - 3 + 2)/2 + 1 = 3。此外,请注意填充为1,应用于输入体积,使输入体积的外边界为零。下面的可视化迭代了输出激活(绿色),并显示每个元素是通过将突出显示的输入(蓝色)与过滤器(红色)相乘,相加,然后用偏差抵消结果来计算的。
计算过程如下:(蓝色数字指蓝框内的值,红色为卷积核内的值,绿色为输出值)
卷积核是自带核参数的,它可以基于诸如梯度下降的方法进行参数的更新,以更好的适应输入图像的分布。通过不断的堆叠卷积层,网络便可以提取到丰富的分层特征表示(Hierarchical feature representation)
从函数映射的角度来理解,卷积的过程好比是对图像上的每个位置都进行线性变换并将其映射成一个新的数值的过程。那么多层卷积也不过是在进行逐层地映射,其整体构造成一个复杂的函数。网络在训练的过程其实是在学习每个局部映射所需要的权重,训练结果可以看成是网络拟合输入分布的过程。
从模板匹配的角度来理解,卷积核本质上可以定义为某种模式,卷积操作则是通过计算图像中当前位置与该模板(卷积核)的匹配程度,若匹配度越高,则响应(激活值)越强。因此,提取到更具有判别力的特则是卷积运算的关键,
Pytorch深度学习框架中,实现卷积最长使用的是torch.nn.Conv2d来实现卷积。
#卷积参数
torch.nn.Conv2d(
in_channels, #输入的通道数
out_channels, #输出的通道数
kernel_size, #卷积核大小
stride=1, #卷积核移动步长
padding=0, #填充多少
dilation=1, #
groups=1, #卷积核个数
bias=True
)
from torch import nn
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(1, 25, kernel_size=3),
nn.BatchNorm2d(25),
nn.ReLU(inplace=True)
)
self.layer2 = nn.Sequential(
nn.MaxPool2d(kernel_size=2, stride=2)
)
self.layer3 = nn.Sequential(
nn.Conv2d(25, 50, kernel_size=3),
nn.BatchNorm2d(50),
nn.ReLU(inplace=True)
)
self.layer4 = nn.Sequential(
nn.MaxPool2d(kernel_size=2, stride=2)
)
self.fc = nn.Sequential(
nn.Linear(50 * 5 * 5, 1024),
nn.ReLU(inplace=True),
nn.Linear(1024, 128),
nn.ReLU(inplace=True),
nn.Linear(128, 10)
)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
x = x.view(x.size(0), -1)
x = self.fc(x)
return x