一、AlexNet和VGG
AlexNet 于 2012 年问世,是一次革命性的进步。它改进了传统的卷积神经网络 (CNN),并成为图像分类的最佳模型之一。
当 AlexNet 发布时,它轻松赢得了 ImageNet 大规模视觉识别挑战赛 (ILSVRC),并证明自己是目前最强大的对象检测模型之一。它的主要特点包括使用relu代替tanh函数、针对多个GPU的优化、以及对于池化的重叠使用。它通过使用dropout来解决过度拟合问题。
VGG模型是2014年ILSVRC竞赛的第二名,第一名是GoogLeNet。但是VGG模型在多个迁移学习任务中的表现要优于googLeNet。而且,从图像中提取CNN特征,VGG模型是首选算法。
如下图,VGG的架构有四部分组成:
1. 输入。 VGG接收224x224像素的RGB图像。
2. 卷积层。 VGG中的卷积层使用非常小的感受野(3x3,捕获左/右和上/下的最小可能尺寸)。还有1x1卷积滤波器充当输入的线性变换,其后是relu单元。卷积步幅固定为1个像素,以便在卷积后保留空间分辨率。
3. 全连接层。 VGG有三个全连接层:前两个各有4096个通道,第三个有1000个通道,每个类1个。
4. 隐藏层。 VGG的所有隐藏层都使用relu(AlexNet的一项巨大创新,可以缩短训练时间)。VGG通常不使用局部响应归一化 (LRN),因为LRN会增加内存消耗和训练时间,而准确率并没有特别提高。
VGG和AlexNet的主要区别如下:
1. VGG没有使用像AlexNet(11x11,步幅为4)这样的大感受野,而是使用非常小的感受野(3x3,步幅为1)。因为现在有三个ReLU单元而不是一个,所以决策函数更具判别力。参数也更少。
2. VGG结合了1x1卷积层,在不改变感受野的情况下使决策函数更加非线性。
3. 小尺寸卷积滤波器使得VGG有更多层。
二、VGG模型实现
选择VGG架构如下,主要实现模型,忽略数据处理和训练部分,开发平台为TensorFlow:
通过观察模型,可以发现VGG是由5个conv2D+maxPooling的块(block)组成的,为了简化代码,先定义Block类,通过入参控制conv2D的个数,如下:
class Block(tf.keras.Model):
def __init__(self, filters, kernel_size, repetitions, pool_size=2, strides=2):
super(Block, self).__init__()
self.filters = filters
self.kernel_size = kernel_size
self.repetitions = repetitions
# 循环初始化conv2D layer
for i in range(self.repetitions):
vars(self)[f'conv2D_{i}'] = tf.keras.layers.Conv2D(self.filters, self.kernel_size, activation='relu', padding='same')
self.max_pool = tf.keras.layers.MaxPooling2D(pool_size=(pool_size, pool_size), strides=(strides, strides))
def call(self, inputs):
conv2D_0 = vars(self)['conv2D_0']
x = conv2D_0(inputs)
for i in range(1, self.repetitions):
conv2D_i = vars(self)[f'conv2D_{i}']
x = conv2D_i(x)
max_pool = self.max_pool(x)
return max_pool
最后定义MyVGG类,将Block组合成VGG模型,如下:
class MyVGG(tf.keras.Model):
def __init__(self, num_classes):
super(MyVGG, self).__init__()
self.block_a = Block(64, 3, 2)
self.block_b = Block(128, 3, 2)
self.block_c = Block(256, 3, 3)
self.block_d = Block(512, 3, 3)
self.block_e = Block(512, 3, 3)
self.flatten = tf.keras.layers.Flatten()
self.fc = tf.keras.layers.Dense(256, activation='relu')
self.classifier = tf.keras.layers.Dense(num_classes, activation='softmax')
def call(self, inputs):
x = self.block_a(inputs)
x = self.block_b(x)
x = self.block_c(x)
x = self.block_d(x)
x = self.block_e(x)
x = self.flatten(x)
x = self.fc(x)
x = self.classifier(x)
return x
至此,基于以上VGG模型的源码,可以自行构造输入样本,并训练模型。