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人功智能相关文章
作者:风尘浪子
原创作品,转载时请注明作者及出处