Hello,又是一个分享的日子,上期博主介绍了CNN神经网络图像分类---全流程,并介绍了图像在进入神经网络前的预处理工作。今天博主给大家分享的是利用迁移学习对图像数据的分类,不可避免的,这也同样需要对图像数据进行预处理,因此还没有熟悉图像预处理的可以花上几分钟看一看博主的上一期推文。
当然啦,说到图像分类,就离不开CNN卷积神经网络,这一期我们采用的VGG16迁移学习模型就是由CNN网络加全连接层组成的。博主也在往期的推文中也介绍了CNN卷积神经网络的原理,还不熟悉CNN卷积神经网络原理的小伙伴可以翻一下:什么?卷积层会变胖?人工智能之光---CNN卷积神经网络(原理篇),这里博主就不进行过多的赘述了。
迁移学习
原理
迁移学习讲诉了一个站在巨人肩膀的故事。随着越来越多的深度学习应用场景的出现,人们不可避免会去想,如何利用已训练的模型去完成相类似的任务,毕竟重新训练一个优秀的模型需要耗费大量的时间和算力, 而在前人的模型上修修补补,举一反三无疑是最好的办法。
我们这一期将选择VGG16这个模型来做迁移学习,如下图。我们可以看到VGG16最多的网络层是CNN网络,所以,我们不用把问题想得太过于复杂,这其实就是一个CNN卷积神经网络模型,只是我们借用了别人已经训练好的模型来完成我们的任务罢了。
那对于这个模型,我们应该如何去利用它来完成我们的任务呢?由于我们这期采用的数据集和上一期CNN图像分类的数据集是一样的,因此我们的任务也是一样的,即对图像进行十分类。因此我们只需要将VGG16的输出层(全连接层)拆掉,换成我们想要的输出层(10分类的输出层)即可,其余层保持不变,将图像数据导入模型中训练就可以了。
图像预处理
数据集
这一期,我们同样是基于fashion MNIST数据的图像分类去做实验。在2017年8月份,德国研究机构Zalando Research在GitHub上推出了一个全新的数据集,其中训练集包含60000个样例,测试集包含10000个样例,分为10类,每一类的样本训练样本数量和测试样本数量相同。样本都来自日常穿着的衣裤鞋包,每个都是28×28的灰度图像,其中总共有10类标签,每张图像都有各自的标签。
值得注意的是,因为VGG16只能识别尺寸大于48×48的彩色图片,而我们的数据集是28×28的灰色图片,因此我们在将数据集灌入迁移学习模型前,要对图片数据集进行适当地转换,也就是比上一期传统CNN神经网络的图像预处理多了一步:将图片转换成48×48大小的彩色图片。
对于图像生成器ImageDataGenerator,博主上一期已进行了简单的介绍,主要是让大家知道这么个东西。等到大家需要用的时候,去翻阅官网查询即可。博主每次用的时候也是要翻阅的,因为参数比较多,不可能都记住的。这里只附上它的链接,就不进行过多的赘述了。
Keras图像生成器参数含义
https://keras.io/zh/preprocessing/image/
上述的图像预处理操作均会在后面的代码有所体现。
实验
实验环境
Anaconda Python 3.7
Jupyter Notebook
Keras
开发环境安装在之前的推文中已经介绍,还没安装的小伙伴可以翻一下。
Python开发环境---Windows与服务器篇
Python深度学习开发环境---Keras
图像数据集
提取码:ffbp
https://pan.baidu.com/s/1D4EKsd3GpWXcjRnmJtFGXw
实验流程
加载图像数据
图像数据预处理
训练模型
保存模型与模型可视化
训练过程可视化
代码
核心代码
# 使用VGG16模型
base_model = applications.VGG16(include_top=False, weights='imagenet', input_shape=x_train.shape[1:]) # 第一层需要指出图像的大小
# # path to the model weights files.
# top_model_weights_path = 'bottleneck_fc_model.h5'
print(x_train.shape[1:])
model = Sequential()
print(base_model.output)
model.add(Flatten(input_shape=base_model.output_shape[1:]))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
# add the model on top of the convolutional base
model = Model(inputs=base_model.input, outputs=model(base_model.output)) # VGG16模型与自己构建的模型合并
# 保持VGG16的前15层权值不变,即在训练过程中不训练
for layer in model.layers[:15]:
layer.trainable = False
# initiate RMSprop optimizer
opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)
# Let's train the model using RMSprop
model.compile(loss='categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'])
正如前面所说,上述代码就是拆掉了输出层,并在VGG16中换成了我们想要的输出层,并保持训练过程中VGG16模型前15层的权值不变,我们就能得到我们想要的训练模型了,其余的和上一期传统的CNN卷积神经网络模型并没有太大区别。
参数
Dense: 全连接层。
CNN2D:2维卷积神经网络,常用于处理图像。
Dropout: 以一定概率放弃两层之间的一些神经元链接,防止过拟合,可以加在网络层与层之间。
optimizer: 优化器,梯度下降的优化方法
这些都在之前的推文中有所介绍,小伙伴们可以去翻阅一下。
码前须知---TensorFlow超参数的设置
activation: 激励函数,‘linear’一般用在回归任务的输出层,而‘softmax’一般用在分类任务的输出层。
validation_split: 切分一定比例的训练集作为验证集
loss: 拟合损失方法,这里用到了多分类损失函数交叉熵
如果你的label 是 数字编码 ,用 sparse_categorical_crossentropy,
如果你的 label是 one-hot 编码,用 categorical_crossentropy
keras还有别的误差函数,在后续的推文会一一介绍。
epochs 与 batch_size:前者是迭代次数,后者是用来更新梯度的批数据的大小,iteration = epochs / batch_size, 也就是完成一个epoch需要跑多少个batch。这这两个参数可以用控制变量法来调参,控制一个参数,调另外一个,看损失曲线的变化。
小伙伴们可以去keras官网查看更多的参数含义与用途,博主也会在后续的课程中通过实验的方法将这些参数涉及进来,让大家的知识点串联起来。
Keras官网
https://keras.io/
Git链接
代码
https://github.com/ChileWang0228/DeepLearningTutorial/blob/master/Transfer_learning/Transfer_learning_cnn_image.ipynb
训练结果
训练过程
结果分析
这里只跑了5个epoch,结果已经可以到0.90了。对比上一期,我们同样跑了5个epoch,结果却只在0.81左右。因此,借用迁移学习的力量,我们能更加出色地完成了图像分类任务。
代码实践视频
视频卡顿?bilibili值得拥有~(っ•̀ω•́)っ✎⁾⁾ 我爱学习
https://www.bilibili.com/video/av60711762/
总结
好了,到这里,我们就已经将迁移学习---图像分类的知识点讲完了。大家在掌握了整个流程之后,就可以在博主的代码上修修补补,训练自己的迁移学习模型来做图像分类任务了。
下一期,博主就带领大家用迁移学习来做回归,敬请期待吧~
图片来源于网络,侵删
留言