1 问题
了解VGG网络并利用pytorch来实现VGG网络
探索1x1卷积核的作用
2 方法
问题一
什么是VGG网络
VGG也称为VGGNet,是一种经典的卷积神经网络架构。它探索了卷积神经网络的深度与其性能之间的关系。
VGG网络通过反复堆叠3 3的小型卷积核和2 2的最大池化层,成功地构筑了16~19层深的卷积
VGG网络的特点是具有深层的结构,它采用了连续多个卷积层和池化层的堆叠。VGG网络的核心思想是通过多次堆叠3x3的卷积核和2x2的池化操作来增加网络的深度,从而提高特征提取的能力。
VGG网络的结构非常简洁,包含了卷积层池化层和全连接层,没有使用任何复杂的操作。
VGG网络的原理
在VGG中,使用了3个3x3卷积核来代替7x7卷积核,使用了2个3x3卷积核来代替5*5卷积核,这样做的主要目的是在保证具有相同感知野的条件下,提升了网络的深度,在一定程度上提升了神经网络的效果。利用pytorch来实现VGG网络
下面的代码定义了一个名为VGG16的类,继承自nn.Module。在__init__函数中,定义了VGG16网络的各个层次,包括5段卷积层和3个全连接层。在forward函数中,将输入数据通过各个层次进行前向传播,输出最终的预测结果。
问题二
1、升维、降维:由于 1×1 并不会改变 height 和 width,改变通道的第一个最直观的结果,就是可以将原本的数据量进行增加或者减少。可以称之为升维、降维。但我觉得维度并没有改变,改变的只是 height × width × channels 中的 channels 这一个维度的大小而已,也即是说对于channels这个维度的升高与降低。
2、增加非线性:1*1卷积核,可以在保持feature map尺度不变的(即不损失分辨率)的前提下大幅增加非线性特性(利用后接的非线性激活函数),把网络做的很深入。
3、增加网络容量:通过增加1x1卷积层,你可以增加网络的容量,使其能够更好地适应数据。这对于一些复杂的任务非常有用
Courier New字体,23磅行间距,单击右键选择无格式粘贴代码。 import torch import torch.nn as nn class VGG16(nn.Module): def __init__(self, num_classes=1000): super(VGG16, self).__init__() # 第一段卷积层 self.conv1 = nn.Sequential( nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2) ) # 第二段卷积层 self.conv2 = nn.Sequential( nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2) ) # 第三段卷积层 self.conv3 = nn.Sequential( nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2) ) # 第四段卷积层 self.conv4 = nn.Sequential( nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2) ) # 第五段卷积层 self.conv5 = nn.Sequential( nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2) ) # 全连接层 self.fc = nn.Sequential( nn.Linear(in_features=512*7*7, out_features=4096), nn.ReLU(inplace=True), nn.Dropout(), nn.Linear(in_features=4096, out_features=4096), nn.ReLU(inplace=True), nn.Dropout(), nn.Linear(in_features=4096, out_features=num_classes) ) def forward(self, x): x = self.conv1(x) x = self.conv2(x) x = self.conv3(x) x = self.conv4(x) x = self.conv5(x) x = x.view(x.size(0), -1) x = self.fc(x) return x |
3 结语
通过本次的学习,了解了VGG网络的原理和特点并且学会了利用pytorch来实现VGG网络
如果卷积的输出输入都只是一个平面,那么1x1卷积核并没有什么意义,它是完全不考虑像素与周边其他像素关系。 但卷积的输出输入是长方体,所以1x1卷积实际上是对每个像素点进行精细化的操作,在不同的channels上进行线性组合(信息整合),且保留了图片的原有平面结构,调控depth,从而完成升维或降维的功能。个人觉得,1*1卷积核就像是一个基础性的操作,是理解更高channels卷积核的基础,有它自己独特的用法,是一个基础性的知识。