TensorFlow 2.0 深度学习实战 —— 浅谈卷积神经网络 CNN


前言

上一章为大家介绍过深度学习的基础和多层感知机 MLP 的应用,本章开始将深入讲解卷积神经网络的实用场景。
卷积神经网络 CNN(Convolutional Neural Networks,ConvNet)是一种特殊的深度学习神经网络,近年来在物体识别、图像重绘、视频分析等多个层面得到了广泛的应用。
本文将以VGG16预训练模型为例子,从人脸识别、预训练模型、图片风格迁移、滤波分析、热力图等多过领域介绍 CNN 的应用。

一、卷积神经网络的原理

二、构建第一个 CNN 对 MNIST 数字进行分类

三、利用 CNN 进行人脸识别

四、使用 VGG16 框架的预训练模型

五、CNN 中间激活层输出图

六、CNN  滤波器的可视化输出

七、CNN 热力图

回到目录

 回到目录

回到目录

https://www.kaggle.com/muhammadshahzadkhan/dogvscat 下载图片资源,当中包括了 train 图片 2000 张,validation 图片 1000 张,test 图片 1000 张。 
建立 VGG 16 模型,把 include_top 设置为False 以使用自定义全连接,把 input_shape 输入张量设置 (256,256,3)。
为了在训练时不影响卷积层,必须先把 VGG16 的 trainable 设置为 False。
利用 ImageDataGenerator 增加训练数据集,对卷积层输出数据使用 Flatten 拉直,经过二层全连接,使用 Adam 优化器 sigmoid 激活函数输出。
测试数据集准确率可达到 93% 以上

 1 def getModel():
 2     # 获取 VGG16 模型,把 include_top 设置为 False,使用自定义全连接
 3     conv_base=applications.VGG16(weights='imagenet',include_top=False,
 4                                  input_shape=(256,256,3))
 5     # 把 trainable 属性设计为 False,冻结卷积层权重
 6     conv_base.trainable=False
 7     # 新建模型,使用 VGG16 的卷积层,拉直后,自定义二层全连接层
 8     model=models.Sequential()
 9     model.add(conv_base)
10     model.add(layers.Flatten())
11     model.add(layers.Dense(256,activation='relu'))
12     model.add(layers.Dense(1,activation='sigmoid'))
13     # 显示模型层特征
14     model.summary()
15     return model
16 
17 def test():
18     # 猫狗图路径
19     path='E://Python_Projects/data_test/DogVSCatLit/'
20     # 训练数据集使用增强数据
21     train=ImageDataGenerator(rescale=1./255,rotation_range=20,
22                     width_shift_range=0.2,height_shift_range=0.2,
23                     shear_range=0.2,zoom_range=0.2,
24                     horizontal_flip=True,fill_mode='nearest')
25     # 验证数据集和测试数据使用原数据
26     test=ImageDataGenerator(rescale=1./255)
27     # 图片统一转换成 256*256,每批 50个
28     trainData=train.flow_from_directory(path+'train',target_size=(256,256),
29                     batch_size=50,class_mode='binary')
30     validationData=test.flow_from_directory(path+'validation',target_size=(256,256),
31                     batch_size=50,class_mode='binary')
32     testData=test.flow_from_directory(path+'test',target_size=(256,256),
33                     batch_size=50,class_mode='binary')
34     # 获取模型
35     model=getModel()
36     # 使用 adam 优化器,binary_crossentropy 二进制交叉熵损失函数
37     model.compile(optimizer=optimizers.Adam(3e-4),
38                   loss=losses.binary_crossentropy,
39                   metrics=['acc'])
40     # 日志记录
41     callback=callbacks.TensorBoard(log_dir='logs/091902')
42     # 训练数据 2000 个,每批 50 个,所以 steps_per_epoch 训练批次为 40
43     # 验证数据 1000 个,每批 50 个,所以 validation_steps 训练批次为 20
44     # 重复训练 30 次
45     model.fit(trainData,steps_per_epoch=40,epochs=30,
46               validation_data=validationData,validation_steps=20,
47               callbacks=callback)
48     print('---------------------------------test---------------------------------------')
49     # 测试结果
50     model.fit(testData,steps_per_epoch=20)
51 
52 if __name__=='__main__':
53     test()

模型层次图

运行结果

 tensorboard 

4.4 微调 VGG16 模型

前一节的例子训练时会将 VGG16 卷积层的模型完全冻结,是为了避免在数据训练期间,错误信息对已有的模型造成影响。而事实上应用更广泛的是对模型的最顶的卷积层进行微调,使模型更匹配新输入的数据。但注意微调一般只针对最顶层的抽象模型,而不适合用于底层,因为这样做对模型影响过大从而造成误判。
下面的例子就是对顶层的卷积层 [ 'block5_conv1','block5_conv2','block5_conv3' ,‘block5_pool’] 进行解冻,加入微调训练,输出后拉直进入三层全连接层,防止过拟合加入 dropout 层,丢失率设置为 0.3,运行后测试数据的准确率上升到 95%以上。

 1 def getModel():
 2     # 获取 VGG16 模型,把 include_top 设置为 False,使用自定义全连接, 平均值池化
 3     conv_base=applications.VGG16(weights='imagenet',include_top=False,
 4                                  input_shape=(256,256,3))
 5     # 把 trainable 属性设计为 False,冻结卷积层权重
 6     conv_base.trainable=True
 7     # 把顶层卷积层进行解冻
 8     layer_names=['block5_conv1','block5_conv2','block5_conv3','block5_pool']
 9     for layer in conv_base.layers:
10         if layer.name in layer_names:
11             layer.trainable = True
12         else:
13             layer.trainable=False
14 
15     # 新建模型,使用 VGG16 的卷积层,拉直后,自定义三层全连接层
16     model=models.Sequential()
17     model.add(conv_base)
18     model.add(layers.Flatten())
19     model.add(layers.Dense(256,activation='relu'))
20     model.add(layers.Dropout(0.3))
21     model.add(layers.Dense(1,activation='sigmoid'))
22     # 显示模型层特征
23     model.summary()
24     return model
25 
26 def test():
27     # 猫狗图路径
28     path='E://Python_Projects/data_test/DogVSCatLit/'
29     # 训练数据集使用增强数据
30     train=ImageDataGenerator(rescale=1./255,rotation_range=20,
31                     width_shift_range=0.2,height_shift_range=0.2,
32                     shear_range=0.2,zoom_range=0.2,
33                     horizontal_flip=True,fill_mode='nearest')
34     # 验证数据集和测试数据使用原数据
35     test=ImageDataGenerator(rescale=1./255)
36     # 图片统一转换成 256*256,每批 50个
37     trainData=train.flow_from_directory(path+'train',target_size=(256,256),
38                     batch_size=50,class_mode='binary')
39     validationData=test.flow_from_directory(path+'validation',target_size=(256,256),
40                     batch_size=50,class_mode='binary')
41     testData=test.flow_from_directory(path+'test',target_size=(256,256),
42                     batch_size=50,class_mode='binary')
43     # 获取模型
44     model=getModel()
45     # 使用 adam 优化器,binary_crossentropy 二进制交叉熵损失函数
46     model.compile(optimizer=optimizers.Adam(3e-4),
47                   loss=losses.binary_crossentropy,
48                   metrics=['acc'])
49     # 日志记录
50     callback=callbacks.TensorBoard(log_dir='logs/091903')
51     # 训练数据 2000 个,每批 50 个,所以 steps_per_epoch 训练批次为 40
52     # 验证数据 1000 个,每批 50 个,所以 validation_steps 训练批次为 20
53     # 重复训练 30 次
54     model.fit(trainData,steps_per_epoch=40,epochs=30,
55               validation_data=validationData,validation_steps=20,
56               callbacks=callback)
57     print('---------------------------------test---------------------------------------')
58     # 测试结果
59     model.fit(testData,steps_per_epoch=20)
60 
61 if __name__=='__main__':
62     test()

运行结果

回到目录

回到目录

回到目录

回到目录

本章总结

本文主要介绍 CNN 卷积神经网络的基本原理和基础概念,卷积层与池化层的作用,并以常用的 VGG16 为例子,介绍常用模型的使用方式。把中间激活层输出图,滤波器,热力图等进行可视化分析,让大家进一步了解 CNN 的结构特征。文章内容受偶像 Keras 之父 Francois 博客和 Antonio 论文的启发很深。 
后面的文章里将会进一步讲解 DeepDream,风格迁移,音频 / 视频处理等高级 CNN 的应用,敬请留意。
希望本篇文章对相关的开发人员有所帮助,由于时间仓促,错漏之处敬请点评。

对 .Python  开发有兴趣的朋友欢迎加入QQ群:790518786 共同探讨 !
对 JAVA 开发有兴趣的朋友欢迎加入QQ群:174850571 共同探讨!
对 .NET  开发有兴趣的朋友欢迎加入QQ群:162338858 共同探讨 !

AI人功智能相关文章

作者:风尘浪子

原创作品,转载时请注明作者及出处