这次实验的主角并不是猫狗大战,而是AlexNet网络,只不过数据集为猫狗大战数据集。本次实验利用自己搭建的AlexNet网络实现猫狗大战,测试一下AlexNet网络的性能。
AlexNet网络作为LeNet网络之后得到的网络模型,在很多地方都有了重大的创新,而这些创新就目前来看仍有重大的意义。
1.创新点
1.ReLU非线性函数(ReLU Nonlinearity)
在AlexNet网络之前的网络模型中,大多采用sigmoid或者tanh作为激活函数,但是Alex(AlexNet网络的发明者)发现在训练时间的梯度衰减方面,这些非线性饱和函数比非线性非饱和函数慢很多。在AlexNet中用的非线性非饱和函数:ReLU。实验表明,ReLU比tanh快6倍。
2.利用GPU进行运算
实现高效的GPU卷积运算结构,也使得此后GPU成为深度学习的主要工具。
3.LRN(局部响应归一化)
增加LRN的想法是之前的网络模型中不曾有的,虽然它的作用在后面的网络中没有体现出来,不过也是一次重要的创新。公式如下:
4.Overlapping Pooling
使用重叠的最大池化,以前在卷积神经网络中大部分都采用平均池化,在AlexNet中都是使用最大池化,最大池化可以避免平均池化的模糊化效果。重叠的最大池化是指卷积核的尺寸要大于步长,这样池化层的输出之间会有重叠和覆盖,提升特征的丰富性。在AlexNet中使用的卷积核大小为3×3,横向和纵向的步长都为2。
5.Data Augmentation(数据扩充)
也就是数据增强,使用Random Crop、flip从而上千倍的扩充训练样本的数量,也使得随机裁剪成为通用方法。
6.DropOut
简而言之,这种方法是用来减少过拟合的风险,经过若干次实验发现,创新点5(Data Augmentation)也可以做到防止过拟合。Dropout的原理是通过训练时随机使得一部分结点失效,不贡献连接权重而减少过拟合风险。同时强迫这些神经元去学习互补的一些特征。
2.网络结构
AlexNet网络结构以及各层训练参数的计算如下图所示:
3.AlexNet网络搭建
与原始的AlexNet网络不同的是去除了两层Dropout层,最终的输出参数设置为了分类的类别数2,并且利用BN(BatchNormalization)代替了LRN(并没有太大的作用)。
def AlexNet(nb_classes, input_shape):
input_tensor = Input(shape=input_shape)
# 1st block
x = Conv2D(96, (11, 11), activation='relu', strides=4, name='block1_conv1')(input_tensor)
x = BatchNormalization()(x)
x = MaxPooling2D((3, 3), strides=2, name='block1_pool')(x)
# 2nd block
x = Conv2D(256, (5, 5), activation='relu', padding='same', name='block2_conv1')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((3, 3), strides=2, name='block2_pool')(x)
# 3rd block
x = Conv2D(384, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
# 4th block
x = Conv2D(384, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
# 5th block
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
x = MaxPooling2D((3, 3), strides=2, name='block5_pool')(x)
# full connection
x = Flatten()(x)
x = Dense(4096, activation='relu', name='fc1')(x)
# x = Dropout(0.5)(x)
x = Dense(4096, activation='relu', name='fc2')(x)
# x = Dropout(0.5)(x)
output_tensor = Dense(nb_classes, activation='softmax', name='predictions')(x)
model = Model(input_tensor, output_tensor)
return model
model = AlexNet(2,(height,width,3))
在对猫狗大战数据集进行分类识别时,网络的优化器采用的随机梯度下降法SGD,一开始采用的优化器是Adam,但是效果并不好。
model.compile(
optimizer="sgd",
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy']
)
实验结果如下所示:
经过40个epochs之后,模型的准确率在90%左右,效果不错。
总结:本文主要是对AlexNet网络进行的分析,至于数据集的处理,并没有给出相应的代码,在博主之前的博客中,是有详细的代码的,与本文的代码相同。至于Dropout层的处理,路过的大佬可以试验一下效果。
努力加油a啊