论文全名:《Very Deep Convolutional Networks for Large-Scale Image Recognition》
2014年,牛津大学计算机视觉组(Visual Geometry Group)和Google
DeepMind公司的研究员一起研发出了新的深度卷积神经网络:VGGNet,并取得了ILSVRC2014比赛分类项目的第二名(第一名是GoogLeNet,也是同年提出的)和定位项目的第一名。
VGGNet探索了卷积神经网络的深度与其性能之间的关系,成功地构筑了16~19层深的卷积神经网络,证明了增加网络的深度能够在一定程度上影响网络最终的性能,使错误率大幅下降,同时拓展性又很强,迁移到其它图片数据上的泛化性也非常好。到目前为止,VGG仍然被用来提取图像特征。
VGGNet可以看成是加深版本的AlexNet,都是由卷积层、全连接层两大部分构成
以下是pytorch中对vgg的网络结构实现网络卷积和池化层嵌套规律
cfgs = {
'A vgg-11': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
'B vgg-13': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
'D vgg-16': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
'E vgg-19': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],
}
网络结构分析
卷积层
vgg中每一层卷积 kernel_size=[3,3], padding = [1,1], stride = [1,1],由卷积处理数据的公式可以,卷积层并不改变每层的featrue_map的尺寸
out
= [(input+2*padding-kernel_size)/s] +1
= [(input+2-3)] +1
= input
即当stride为1的情况下,kernel_size = 2*padding +1时,不改变处理的feature_map的尺寸
池化层
vgg中每层池化层的 kernel_size=[2] , padding = [0], stride = [2],可知,每层池化都会将feature的尺寸缩小为原来的1/2
out
= [(input+2*padding-kernel_size)/s] +1
= [(input-2)/2] +1
= input/2
全连接层
vgg最后一层的输出必须与第一层的全连接的输入相匹配,例如全连接层的输入为:
7
×
7
×
512
=
25088
7\times7\times512 = 25088
7×7×512=25088
则要求网络的输入为:
7
×
2
5
=
224
7\times2^5 = 224
7×25=224
其中5表示5层池化层;
反过来,如果你需要定制你自己的网络输入,则需要根据输入尺寸修改全连接层,计算公式为:
(
i
n
p
u
t
)
2
5
\text(input)\over 2^5
25(input)
计算出最后一层池化层输出的feature_map的尺寸,进而修改你的网络全连接层
例如:
net = vgg16(pretrained=False,progress=False).to(self.device)
# 定义一个新的classifier,其中包含3个全连接隐藏层,层之间使用ReLU函数进行激活,最后输出使用LogSoftMax函数,因为这是一个多分类。
classifier = nn.Sequential(OrderedDict([
('fc1',nn.Linear(25088,4096)),
('relu1',nn.ReLU()),
('fc2',nn.Linear(4096,1000)),
('relu2',nn.ReLU()),
('fc3',nn.Linear(1000,10)),
('output',nn.LogSoftmax(dim=1))
]))
网络输出和参数量
每层的参数量
如上图,每个卷积,都会与输入的每个通道的数据进行卷积计算,设置:
- F表示卷积的的尺寸
- D表示输入的feature_map的深度
由y = wx+b可知,每个卷积处理所有feature_map的参数个数为FxFxD +1,1表示bias偏置参数,则每层卷积层的参数格式为
卷积层的参数格式 = (F*F*D +1)*K,其中K表示,本层卷积核的个数
全连接层可以的每个值可以看成是1x1的卷积,因此计算公式如上,根据以上公式,我们可以计算出VGG16的每层的参数格式
以上是通过以上公式,计算的vgg16网络每层的输出尺寸,每层的参数量和显存占用。
vgg参数量达到了1.3亿个,其中第一层全连接层占了76%,第二层全连接层占了12%。
计算量
计算计算量,根据卷积计算公式可知,每一个输出的特征图的每一个特征值,都需要使用卷积与输入的特征图上点进行kxk个操作完成,因此计算量(乘积操作)的公式如下:
单个特征值的计算量
= (k*k)*n_in n_in 表示输入的特征图的维度,k表示卷积尺寸
单个特征图的计算量
=(k*k)*n_in *w_out*h_out
当前层特征图的计算量:
=(k*k)*n_in *w_out*h_out * m, 其中m表示,本层卷积核的个数
助理理解,每个卷积都会与每个输入的特征图分别计算,得到这个卷积代表的一个特征图,就像:
训练
我们使用口罩数据集进行训练,可以得到97%的准确率
###iteration[:1120],[Epoch:32],[Lr:0.00010000] train sum_loss: [0.267] -> avg loss[0.013]
###iteration[:1140],[Epoch:32],[Lr:0.00010000] train sum_loss: [1.000] -> avg loss[0.050]
test data avg accuracy:97%
###iteration[:1160],[Epoch:33],[Lr:0.00010000] train sum_loss: [0.403] -> avg loss[0.020]
###iteration[:1180],[Epoch:33],[Lr:0.00010000] train sum_loss: [1.354] -> avg loss[0.068]
test data avg accuracy:97%
###iteration[:1200],[Epoch:34],[Lr:0.00010000] train sum_loss: [0.666] -> avg loss[0.033]
###iteration[:1220],[Epoch:34],[Lr:0.00010000] train sum_loss: [1.012] -> avg loss[0.051]
test data avg accuracy:96%
###iteration[:1240],[Epoch:35],[Lr:0.00010000] train sum_loss: [0.750] -> avg loss[0.037]
###iteration[:1260],[Epoch:35],[Lr:0.00010000] train sum_loss: [1.113] -> avg loss[0.056]
test data avg accuracy:97%
###iteration[:1280],[Epoch:36],[Lr:0.00010000] train sum_loss: [1.083] -> avg loss[0.054]
源码参考
参考文档
vggnet相关:
https://www.cnblogs.com/aiblbns/p/11124656.html
https://blog.csdn.net/abc_138/article/details/80568450