VGG-16详解

发布时间:2023-05-19

VGG-16介绍

VGG-16是一个深度学习模型,由Karen Simonyan和Andrew Zisserman在2014年提出。它是一个16层的卷积神经网络,因其作者都毕业于牛津大学Visual Geometry Group(VGG)而得名。VGG-16在ImageNet分类比赛中表现优秀,成为深度学习领域的经典模型。

VGG-16结构

VGG-16的网络结构如下所示:

Input (224x224x3)
|
Conv3-64
|
Conv3-64
|
MaxPool2x2
|  
Conv3-128
|
Conv3-128
|
MaxPool2x2
|
Conv3-256
|
Conv3-256
|
Conv3-256
|
MaxPool2x2
|
Conv3-512
|
Conv3-512
|
Conv3-512
|
MaxPool2x2
|
Conv3-512
|
Conv3-512
|
Conv3-512
|
MaxPool2x2
|
FC4096
|
FC4096
|
FC1000
|
Softmax

VGG-16包含13个卷积层和3个全连接层。前面的卷积层不断加深网络的深度,后面的全连接层将卷积层的输出转化为分类结果。最后的Softmax函数用于计算每个类别的概率。

卷积层详解

1. 滤波器大小

在VGG-16中,卷积层的滤波器大小都是3x3。这个尺寸被广泛认为是最优的尺寸,因为它既能够捕捉空间细节,又能够避免计算复杂度过高。此外,使用小的滤波器尺寸可以减少过拟合的风险。

2. 填充方式

VGG-16中的卷积层都使用了相同的填充方式——对称填充(same padding)。这种填充方式可以保持卷积后图像的尺寸不变,因此可以在不丢失空间信息的情况下增加网络深度。

3. 步幅大小

在VGG-16中,所有的卷积层步幅大小都是1。这种设置可以使卷积层能够更好地捕捉到图像的空间细节,但代价是计算复杂度会增加。

全连接层详解

1. 输出层

VGG-16的最后一层是一个全连接层,将卷积层的输出转换为分类结果。在ImageNet分类比赛中,VGG-16需要分类1000个类别,因此全连接层的输出大小为1000。

2. Dropout

VGG-16在全连接层中使用了Dropout技术,以减少过拟合的风险。Dropout技术会随机删除一定比例的神经元,从而使网络强制性地学习多种特征组合。

3. 激活函数

VGG-16的全连接层使用了ReLU激活函数。ReLU能够更好地克服梯度消失的问题,并且在很多情况下可以提高模型的精度。

代码示例

1. 使用Keras加载并训练VGG-16模型

from keras.applications import vgg16
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
# 加载VGG-16模型,去掉最后一层
base_model = vgg16.VGG16(weights='imagenet', include_top=False)
# 添加全局平均池化层
x = base_model.output
x = GlobalAveragePooling2D()(x)
# 添加全连接层和输出层
x = Dense(1024, activation='relu')(x)
predictions = Dense(1000, activation='softmax')(x)
# 构建新模型
model = Model(inputs=base_model.input, outputs=predictions)
# 编译模型
model.compile(optimizer='rmsprop', loss='categorical_crossentropy')
# 加载数据
img_path = 'cat.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = preprocess_input(x)
x = np.expand_dims(x, axis=0)
# 预测分类
preds = model.predict(x)

2. 冻结部分层的权重,fine-tuning VGG-16模型

from keras.applications import vgg16
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
# 加载VGG-16模型
base_model = vgg16.VGG16(weights='imagenet', include_top=False)
# 冻结前面的13层
for layer in base_model.layers[:13]:
    layer.trainable = False
# 控制器
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
# 新的输出层
predictions = Dense(1, activation='sigmoid')(x)
# 构建新的模型
model = Model(inputs=base_model.input, outputs=predictions)
# 编译模型
model.compile(optimizer='rmsprop', loss='binary_crossentropy')
# 加载数据
img_path = 'cat_or_dog.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = preprocess_input(x)
x = np.expand_dims(x, axis=0)
# 训练模型
model.fit(x, y)

总结

VGG-16是一种经典的深度学习模型,其卷积层和全连接层都具有一定的特点和设计思路,使其在ImageNet分类比赛中表现出色。在实际应用中,可以使用VGG-16的预训练模型进行特征提取,也可以根据具体问题进行fine-tuning,得到更好的效果。