关键词:
5.3 使用预训练的卷积神经网络
预训练网络(pretrained network):
- 是一个之前已在大型数据集(通常是大规模图像分类任务)上 训 练 好 、 保 存 好 的 网 络 \\colorred训练好、保存好的网络 训练好、保存好的网络。
- 预训练网络 学 到 的 特 征 的 空 间 层 次 结 构 \\colorred学到的特征的空间层次结构 学到的特征的空间层次结构可以有效地作为视觉世界的通用模型,在不同问题之间具有 可 移 植 性 \\colorred可移植性 可移植性。
- 由于预训练网络,使得深度学习 对 小 数 据 问 题 非 常 有 效 \\colorred对小数据问题非常有效 对小数据问题非常有效。
使用预训练网络有两种方法: 特 征 提 取 ( f e a t u r e e x t r a c t i o n ) \\colorred特征提取(feature\\;extraction) 特征提取(featureextraction)和 微 调 模 型 ( f i n e − t u n i n g ) \\colorred微调模型(fine-tuning) 微调模型(fine−tuning)。
5.3.1 特征提取
-
定义:
特 征 提 取 是 使 用 之 前 网 络 学 到 的 表 示 来 从 新 样 本 中 提 取 出 有 趣 的 特 征 。 \\colorred特征提取是使用之前网络学到的表示来从新样本中提取出有趣的特征。 特征提取是使用之前网络学到的表示来从新样本中提取出有趣的特征。 -
卷 积 基 \\colorred卷积基 卷积基:
- 图像分类的卷积神经网络包含两部分:首先是一系列池化层和卷积层,最后是一个密集连接分类器。第一部分叫作模型的 卷 积 基 ( c o n v o l u t i o n a l b a s e ) \\colorred卷积基(convolutional\\;base) 卷积基(convolutionalbase)。
- 特征提取就是取出之前训练好的网络的卷积基,在上面运行新数据,然后
在
输
出
上
面
训
练
一
个
新
的
分
类
器
\\colorred在输出上面训练一个新的分类器
在输出上面训练一个新的分类器。
- 为什么不用密集层:密集连接层的表示不再包含物体在输入图像中的 位 置 信 息 \\colorred位置信息 位置信息。密集连接层舍弃了空间的概念,而物体位置信息仍然由卷积特征图所描述。
- 某个卷积层提取的
表
示
的
通
用
性
\\colorred表示的通用性
表示的通用性(以及可复用性)取决于
该
层
在
模
型
中
的
深
度
\\colorred该层在模型中的深度
该层在模型中的深度。
模型型中更靠近底部的层提取的是局部的、高度通用的特征图(比如视觉边缘、颜色和纹理),而更靠近顶部的层提取的是更加抽象的概念(比如“猫耳朵”或“狗眼睛”)。
- 如果你的新数据集与原始模型训练的数据集有很大差异,那么最好只使用模型的前几层来做特征提取,而不是使用整个卷积基。
- 常用的模型内置于Keras 中。你可以从
keras.applications
模块中导入。
-
VGG16模型
from tensorflow.keras.applications import VGG16 conv_base = VGG16(weights='imagenet', include_top=False, input_shape=(150, 150, 3))
这里向构造函数中传入了三个参数。
weights
指定模型初始化的权重检查点。include_top
指定模型最后是否包含密集连接分类器。默认情况下,这个密集连接分类器对应于 ImageNet 的 1000 个类别。因为我们打算使用自己的密集连接分类器(只有两个类别: cat 和 dog),所以不需要包含它。input_shape
是输入到网络中的图像张量的形状。这个参数完全是可选的,如果不传入这个参数,那么网络能够处理任意形状的输入。
conv_base.summary()
最后的特征图形状为
(4, 4, 512)
。我们将在这个特征上添加一个密集连接分类器。下一步有两种方法可供选择。- 不使用数据增强的快速特征提取。
这种方法速度快,计算代价低,因为对于每个输入图像只需运行一次卷积基,而卷积基是目前流程中计算代价最高的。 - 使用数据增强的特征提取
在顶部添加Dense
层来扩展已有模型(即conv_base
),并在输入数据上端到端地运行整个模型。
5.3.1.1. 不使用数据增强的快速特征提取
首先,运行ImageDataGenerator
实例,将图像及其标签提取为Numpy
数组。调用 conv_base
模型的predict
方法来从这些图像中提取特征。第一种方法的代码:
保
存
你
的
数
据
在
\\colorred保存你的数据在
保存你的数据在 conv_base 中的输出
,
然
后
将
这
些
输
出
作
为
输
入
用
于
新
模
型
\\colorred然后将这些输出作为输入用于新模型
然后将这些输出作为输入用于新模型。
-
使用预训练的卷积基提取特征
import os import numpy as np from tensorflow.keras.preprocessing.image import ImageDataGenerator base_dir = 'C:\\\\Users\\\\Administrator\\\\deep-learning-with-python-notebooks-master\\\\cats_and_dogs_small' train_dir = os.path.join(base_dir, 'train') validation_dir = os.path.join(base_dir, 'validation') test_dir = os.path.join(base_dir, 'test') datagen = ImageDataGenerator(rescale=1./255) batch_size = 20 def extract_features(directory, sample_count): features = np.zeros(shape=(sample_count, 4, 4, 512)) labels = np.zeros(shape=(sample_count)) generator = datagen.flow_from_directory( directory, target_size=(150, 150), batch_size=batch_size, class_mode='binary') i = 0 for inputs_batch, labels_batch in generator: features_batch = conv_base.predict(inputs_batch) features[i * batch_size : (i + 1) * batch_size] = features_batch labels[i * batch_size : (i + 1) * batch_size] = labels_batch i += 1 if i * batch_size >= sample_count: break # 注意,这些生成器在循环中不断生成数据, # 所以你必须在读取完所有图像后终止循环 return features, labels train_features, train_labels = extract_features(train_dir, 4000) validation_features, validation_labels = extract_features(validation_dir, 2000) test_features, test_labels = extract_features(test_dir, 2000) # 提取的特征形状为 (samples, 4, 4, 512) 。我们要将其输入到密集连接分类器中, # 所以首先必须将其形状展平为 (samples, 8192) train_features = np.reshape(train_features, (4000, 4 * 4 * 512)) validation_features = np.reshape(validation_features, (2000, 4 * 4 * 512)) test_features = np.reshape(test_features, (2000, 4 * 4 * 512))
-
定义并训练密集连接分类器
需要使用dropout
正则化,并在刚刚保存的数据和标签上训练这个分类器。from tensorflow.keras import models from tensorflow.keras import layers from tensorflow.keras import optimizers model = models.Sequential() model.add(layers.Dense(256, activation='relu', input_dim=4 * 4 * 512)) model.add(layers.Dropout(0.5)) model.add(layers.Dense(1, activation='sigmoid')) model.compile(optimizer=optimizers.RMSprop(lr=2e-5), loss='binary_crossentropy', metrics=['acc']) history = model.fit(train_features, train_labels, epochs=30, batch_size=20, validation_data=(validation_features, validation_labels))
-
绘制结果
import matplotlib.pyplot as plt acc = history.history['acc'] val_acc = history.history['val_acc'] loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(1, len(acc) + 1) plt.plot(epochs, acc, 'bo', label='Training acc') plt.plot(epochs, val_acc, 'b', label='Validation acc') plt.title('Training and validation accuracy') plt.legend() plt.figure() plt.plot(epochs, loss, 'bo', label='Training loss') plt.plot(epochs, val_loss, 'b', label='Validation loss') plt.title('Training and validation loss') plt.legend() plt.show()
虽然 dropout 比率相当大,但模型几乎从一开始就过拟合。这是因为 本 方 法 没 有 使 用 数 据 增 强 \\colorred本方法没有使用数据增强 本方法没有使用数据增强,而 数 据 增 强 对 防 止 小 型 图 像 数 据 集 的 过 拟 合 非 常 重 要 \\colorred数据增强对防止小型图像数据集的过拟合非常重要 数据增强对防止小型图像数据集的过拟合非常重要。
5.3.1.2.使用数据增强的特征提取
它的速度更慢,计算代价更高,但在训练期间可以使用数据增强。这种方法就是:
扩
展
\\colorred扩展
扩展 conv_base 模型
,
然
后
在
输
入
数
据
上
端
到
端
地
运
行
模
型
\\colorred然后在输入数据上端到端地运行模型
然后在输入数据上端到端地运行模型。
本方法计算代价很高,只在有 GPU 的情况下才能尝试运行。它在 CPU 上是绝对难以运行的。如果你无法在
GPU
上运行代码,那么就采用第一种方法。
- 在卷积基上添加一个密集连接分类器
from tensorflow.keras import models from tensorflow.keras import layers model = models.Sequential() model.add(conv_base) model.add(layers.Flatten()) model.add(layers.Dense(256, activation='relu')) model.add(layers.Dense(1, activation='sigmoid'))
model.summary()
- VGG16 的卷积基有 14 714 688 个参数,非常多。在其上添加的分类器有 200 万个参数。
- 在编译和训练模型之前,一定要“冻结”卷积基。 冻 结 \\colorred冻结 冻结(freeze)一个或多个层是指在训练过程中保持其权重不变。如果不这么做,那么卷积基之前学到的表示将会在训练过程中被修改。因为其上添加的 Dense 层是随机初始化的,所以非常大的权重更新将会在网络中传播,对之前学到的表示造成很大破坏。
- 冻结模型
在 Keras 中, 冻 结 网 络 的 方 法 是 将 其 t r a i n a b l e 属 性 设 为 F a l s e \\colorred冻结网络的方法是将其 trainable 属性设为 False 冻结网络的方法是将其trainable属性设为False。
设置之后,只有添加的两个>>> print('This is the number of trainable weights ' 'before freezing the conv base:', len(model.trainable_weights)) This is the number of trainable weights before freezing the conv base: 30 >>> conv_base.trainable = False >>> print('This is the number of trainable weights ' 'after freezing the conv base:', len(model.trainable_weights)) This is the number of trainable weights after freezing the conv base: 4
Dense
层的权重才会被训练。总共有 4 个权重张量,每层2 个(主权重矩阵和偏置向量)。在编译之后修改了权重的 trainable 属性,那么应该重新编译模型,否则这些修改将被忽略。
- 利用冻结的卷积基端到端地训练模型
from tensorflow.keras.preprocessing.image import ImageDataGenerator from tensorflow.keras import optimizers train_datagen = ImageDataGenerator( rescale=1./255, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode='nearest') # 注意,不能增强验证数据 test_datagen = ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_directory( train_dir,#目标目录 target_size=(150, 150),#
《python深度学习》第五章-6(可视化类激活图)读书笔记(代码片段)
《Python深度学习》第五章-6(可视化类激活图)读书笔记卷积神经网络学到的表示非常适合可视化,很大程度上是因为它们是视觉概念的表示\\colorred视觉概念的表示视觉概念的表示。接下来介绍3种可视化方法。事中\\... 查看详情
《python深度学习》第五章-1(cnn简介)读书笔记(代码片段)
第五章深度学习用于计算机视觉5.1 卷积神经网络简介5.1.1卷积神经网络对MNIST分类使用卷积神经网络对MNIST数字进行分类,在第2章用密集连接网络做过(当时的测试精度为97.8%)。它是Conv2D层和MaxPooling2D层的堆叠。实... 查看详情
《python深度学习》第五章-5(可视化过滤器)读书笔记(代码片段)
5.4 卷积神经网络的可视化卷积神经网络学到的表示非常适合可视化,很大程度上是因为它们是视觉概念的表示\\colorred视觉概念的表示视觉概念的表示。接下来介绍3种可视化方法。事中\\colorblue事中事中:可视化卷积神... 查看详情
《python深度学习》第五章-4(可视化中间激活层)读书笔记(代码片段)
5.4 卷积神经网络的可视化卷积神经网络学到的表示非常适合可视化,很大程度上是因为它们是视觉概念的表示\\colorred视觉概念的表示视觉概念的表示。接下来介绍3种可视化方法。可视化卷积神经网络的中间输出(中间... 查看详情
2021第五届“达观杯”基于大规模预训练模型的风险事件标签识别2dpcnnhanrcnn等传统深度学习方案(代码片段)
文章目录相关链接1引言2方案实现2.1DPCNN2.2HAN2.3TextRCNN2.4CapsuleNet2.5TextRCNNAttention3提分技巧3.1多个模型的提交文件投票融合3.2多个模型投票生成为标签相关链接【2021第五届“达观杯”基于大规模预训练模型的风险事件标签识别】1初... 查看详情
2021第五届“达观杯”基于大规模预训练模型的风险事件标签识别2dpcnnhanrcnn等传统深度学习方案(代码片段)
...险事件标签识别】3Bert和Nezha方案1引言(1)环境python3.6+pytorch1.7.1+(2)重要方法词向量:word2vec(300维度)+fasttext(100维度)进行拼接,并未对此进行调参数据预处理:无。没有来得及去对比,... 查看详情
第五章学习小结
...:树、二叉树、完美二叉树、偏二叉树,节点关系,树的深度,叶节点等等的定义二,树(二叉树)的基本储存结构(1)用数组,适用于满二叉树(2)链式结构(3)数组加链表式:双亲孩子表示法(代码如下)tyepdefstructcNode ... 查看详情
javascript高级程序设计(第3版)第五章读书笔记
第五章引用类型创建Object实例的方式有两种,第一种是使用new操作符后跟Object构造函数,例如:varperson=newObject();person.name=“Nicholas”;person.age=29;第二种是使用对象字面量表示法。如:varperson={name:“Nicholas”,age:29};在最... 查看详情
第五章学习小结
...,也学习了什么是结点的度(即结点的孩子个数),树的深度(即结点度的最大值),但还是主要学习了二叉树,比如二叉树的性质:性质1在二叉树的第i层上至多有2^(i-l)个结点(i>=1)。性质2深度为K的二叉树至多有2^k-1个结点... 查看详情
bert预训练动手学深度学习v2
1.BERT预训练Transformer编码器2.BERT代码3.BERT预训练数据代码4.BERT预训练代码5.Q&A参考https://www.bilibili.com/video/BV1yU4y1E7Ns/?spm_id_from=autoNext 查看详情
2021第五届“达观杯”基于大规模预训练模型的风险事件标签识别3bert和nezha方案(代码片段)
...预训练模型的风险事件标签识别】2DPCNN、HAN、RCNN等传统深度学习方案【2021第五届“达观杯”基于大规模 查看详情
读书笔记之《headfirstservletandjsp》第五章属性和监听者
本章大纲1.servletConfig和servletContext的区别 1.servletConfig和servletContext的区别从部署位置来看,servletConfig是在servlet中,而servletContext是在web-app下从代码来说,getServletContext().getInitParameter("foo");getServletConfig( 查看详情
2021第五届“达观杯”基于大规模预训练模型的风险事件标签识别1初赛rank12的总结与分析
...预训练模型的风险事件标签识别】2DPCNN、HAN、RCNN等传统深度学习方案【2021第五届“达观杯”基于大规模预训练模型的风险事件标签识别】3Bert和Nezha方案1 查看详情
android深度探索(卷1)hal与驱动开发第五章 搭建s3c6410开发板的测试环境读书笔记
作为开发和学习嵌入式技术的主要硬件设备,开发板是机器重要的。因为即使可以在PC上开发Linux驱动,并重新编译成ARM架构的Linux驱动模块,但最终还是要在开发板上进行测试。有两个原因:因为ARM架构的开发板可基于X86架构的... 查看详情
如何构建深度学习预训练模型?
keras提供多种预训练的深度学习模型,可供迁移学习使用。如果我想要根据自己的数据集与训练模型,如何让去构建一个预训练模型用于后续的迁移学习?参考技术A可以直接先找到自己需要的训练模型,一般来说都可以找到的 查看详情
「深度学习一遍过」必修28:基于c3d预训练模型训练自己的视频分类数据集的设计与实现(代码片段)
本专栏用于记录关于深度学习的笔记,不光方便自己复习与查阅,同时也希望能给您解决一些关于深度学习的相关问题,并提供一些微不足道的人工神经网络模型设计思路。专栏地址:「深度学习一遍过」必修篇... 查看详情
「深度学习一遍过」必修28:基于c3d预训练模型训练自己的视频分类数据集的设计与实现(代码片段)
本专栏用于记录关于深度学习的笔记,不光方便自己复习与查阅,同时也希望能给您解决一些关于深度学习的相关问题,并提供一些微不足道的人工神经网络模型设计思路。专栏地址:「深度学习一遍过」必修篇... 查看详情
《自然语言处理实战入门》深度学习----预训练模型的使用(albert)
文章大纲简介bert回顾bert的问题ALBERT(ALiteBERT)改进1:将embedding的参数进行了因式分解改进2:跨层的参数共享改进3:抛弃了原来的NSP任务,现在使用SOP任务。albert的使用参考文献简介bert回顾bert两阶段模式:预训练+微调BERT的总体... 查看详情