目录
一. 开发背景
VGGNet在2014年由牛津大学计算机视觉组VGG (Visual Geometry Group) 提出,斩获该年ImageNet竞赛中Localization Task (定位任务) 第一名和Classification Task(分类任务)第二名(第一名是GoogLeNet)。
VGGNet探索了卷积神经网络的深度与其性能之间的关系,成功地构筑了16~19层深的卷积神经网络,证明了增加网络的深度能够在一定程度上影响网络最终的性能,使错误率大幅下降,同时拓展性又很强,迁移到其它图片数据上的泛化性也非常好。到目前为止,VGG仍然被用来提取图像特征。
二. 网络结构
VGGNet可以看成是加深版的AlexNet,把网络分成了5段,每段都把多个尺寸为3×3的卷积核串联在一起,每段卷积接一个尺寸2×2的最大池化层,最后面接3个全连接层和一个softmax层,所有隐层的激活单元都采用ReLU函数。
VGGNet包含很多级别的网络,深度从11层到19层不等。为了解决初始化(权重初始化)等问题,VGG采用的是一种Pre-training的方式,先训练浅层的的简单网络VGG11,再复用VGG11的权重初始化VGG13,如此反复训练并初始化VGG19,能够使训练时收敛的速度更快。比较常用的是VGGNet-16和VGGNet-19。VGGNet-16的网络结构如下图所示:
结构详解:VGG详解
三. 模型特点
- 使用多个小卷积核构成的卷积层代替较大的卷积层,两个3x3卷积核的堆叠相当于5x5卷积核的视野,三个3x3卷积核的堆叠相当于7x7卷积核的视野。一方面减少参数,另一方面拥有更多的非线性变换,增加了CNN对特征的学习能力;
- 引入1*1的卷积核,在不影响输入输出维度的情况下,引入更多非线性变换,降低计算量,同时,还可以用它来整合各通道的信息,并输出指定通道数;
- 训练时,先训练级别简单(层数较浅)的VGGNet的A级网络,然后使用A网络的权重来初始化后面的复杂模型,加快训练的收敛速度;
- 采用Multi-Scale方法来做数据增强,增加训练的数据量,防止模型过拟合;
- VGGNet不使用局部响应归一化(LRN),这种标准化并不能在ILSVRC数据集上提升性能,却导致更多的内存消耗和计算时间。
四. 代码实现
- model.py :定义VGGNet网络模型
- train.py:加载数据集并训练,计算loss和accuracy,保存训练好的网络参数
- predict.py:用自己的数据集进行分类测试
- spilit_data.py:划分给定的数据集为训练集和测试集
1. model.py
import torch.nn as nn
import torch
# 定义VggNet网络模型
class VGG(nn.Module):
# init():进行初始化,申明模型中各层的定义
# features:make_features(cfg: list)生成提取特征的网络结构
# num_classes:需要分类的类别个数
# init_weights:是否对网络进行权重初始化
def __init__(self, features, num_classes=1000, init_weights=False):
# super:引入父类的初始化方法给子类进行初始化
super(VGG, self).__init__()
# 生成提取特征的网络结构
self.features = features
# 生成分类的网络结构
# Sequential:自定义顺序连接成模型,生成网络结构
self.classifier = nn.Sequential(
# Dropout:随机地将输入中50%的神经元激活设为0,即去掉了一些神经节点,防止过拟合
nn.Dropout(p=0.5),
nn.Linear(512 * 7 * 7, 4096),
# ReLU(inplace=True):将tensor直接修改,不找变量做中间的传递,节省运算内存,不用多存储额外的变量
nn.ReLU(True),
nn.Dropout(p=0.5),
nn.Linear(4096, 4096),
nn.ReLU(True),
nn.Dropout(p=0.5),
nn.Linear(4096, num_classes)
)
# 如果为真,则对网络参数进行初始化
if init_weights:
self._initialize_weights()
# forward():定义前向传播过程,描述了各层之间的连接关系
def forward(self, x):
# 将数据输入至提取特征的网络结构,N x 3 x 224 x 224
x = self.features(x)
# N x 512 x 7 x 7
# 图像经过提取特征网络结构之后,得到一个7*7*512的特征矩阵,进行展平