一,贡献:
① 使用很小的卷积核(3×3)构建各种深度的卷积神经网络结构,并对这些网络结构进行了评估,最终证明16-19层的网络深度,能够取得较好的识别精度。 这也就是常用来提取图像特征的VGG-16和VGG-19。
② 与AlexNet比较:VGG可以看成是加深版的AlexNet,整个网络由卷积层和全连接层叠加而成,和AlexNet不同的是,VGG中使用的都是小尺寸的卷积核(3×3)。
③ 小卷积核增加了网络容量(model capacity),减少了网络参数
(两个3×3的核等于一个5×5的核,三个3×3的卷积核等于一个7×7的卷积核)。
④ 没有用LRN,因为LRN不会提高性能,而会带来内存的消耗。
二,网络架构:
补充:
- VGG-16网络中的16代表的含义为:含有参数的有16个层,有1.3亿多参数。
- 优点:简化了卷积神经网络的结构;缺点:训练的特征数量非常大。
- 随着网络加深,图像的宽度和高度都在以一定的规律不断减小,每次池化后刚好缩小一半,信道数目不断增加一倍。
卷积层:CONV=3X3 filters, s = 1, p = same convolution。
池化层:MAX_POOL = 2*2 , s = 2。
上图是VGG16的简图,整个结构只有3×3的卷积层,连续的卷积层后使用池化层隔开。虽然层数很多,但是很简洁。该模型可简单分为5个stage,类比AlexNet的5层卷积?
…
…
上图黑色(bold)字体表示新加的网络层,A到E代表不同深度的网络架构。实验证明,深度为16或19的时候取得最佳精度。
…
…
① 输入图片是尺寸为224 × 224 的RGB 图片,唯一做的预处理是从每个像素中减去在训练集计算的平均RGB值。
② 用堆叠的卷积层对输入图片进行卷积操作,strides=1,padding=1,填充使得卷积后图像空间分辨率不变,即图像大小不变;卷积核为3×3,这是捕获特征的最小卷积核。在某一配置我们还用了1×1的卷积核,这可看作输入通道的线性变换。
③ 在某些卷积层后做最大池化(max-pooling)处理,池化窗口为2×2,strides=2。共五个最大池化层。
④ 不同深度的架构最后连三个全连接层,前两个全连接层有4096个通道,最后是一个有1000个通道的softmax层。
三,代码实现:
以下是简单的网络架构的实现
from keras import layers,models
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# Step 1: Loading DataSet & Preprocessing
# Step 2: Model
model = models.Sequential()
# Five Convolutional Stage & Five Max-Pooling Layers
# stage 1:
model.add(layers.Conv2D(64, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same', input_shape=(224,224,1)))
model.add(layers.Conv2D(64, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.MaxPool2D(pool_size=(2,2), strides=(2,2)))
# stage 2:
model.add(layers.Conv2D(128, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.Conv2D(128, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.MaxPool2D(pool_size=(2,2), strides=(2,2)))
# stage 3:
model.add(layers.Conv2D(256, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.Conv2D(256, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.Conv2D(256, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.MaxPool2D(pool_size=(2,2), strides=(2,2)))
# stage 4:
model.add(layers.Conv2D(512, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.Conv2D(512, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.Conv2D(512, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.MaxPool2D(pool_size=(2,2), strides=(2,2)))
# stage 5:
model.add(layers.Conv2D(512, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.Conv2D(512, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.Conv2D(512, kernel_size=(3,3), activation='relu', strides=(1,1), padding='same'))
model.add(layers.MaxPool2D(pool_size=(2,2), strides=(2,2)))
model.add(layers.Flatten())
model.add(layers.Dense(4096,activation='relu'))
model.add(layers.Dense(4096,activation='relu'))
model.add(layers.Dense(1000, activation='softmax'))
model.summary()
…
…
1,这篇文章动机是啥,主要是在做啥?
加深网络深度,提高模型准确率。证明一定深度的(16-19层)的网络结构取得了较好的效果。
2,这篇论文相比于当前方法有啥优点?
3,这篇论文是如何实现的?为啥可以达到这样的效果?
使用3✖️3的小卷积核,大大减少了网络参数,通过不断加深网络的深度,比较不同深度的网络的准确率,得出结论。
4,这篇论文的亮点是啥?
使用3✖️3的小卷积核;证明随着网络一定程度的加深可以提高模型准确率。
5,这篇论文有哪些技术可以借用?
3✖️3的小卷积核;加深网络深度。