深度学习 Tensor flow(四)
预训练网路(迁移学习)
预训练网络是一个在大型数据集上训练好的卷积神经网络。
针对训练数据量比较少的情况;
当训练数据集足够大且够通用,预训练网络可以作为有效的提取视觉世界特征的模型。
keras 内置预训练网络:(分类)
VGG16、VGG19、ResNet50、Iception v3、Xception 等。
在 ImageNet 进行过训练的模型,它对日常见到的一千多种物品进行了分类,是一个分类数据集。
VGG 模型:
VGG 模型简单有效,前几层仅使用 3x3 卷积核增加网络深度,通过 max pooling 依次减少每层神经元数量,最后三层分别是 2 个有 4096 个神经元的全连接层和一个 softmax 层。
缺点:网络架构 weight 数量相当大,消耗磁盘空间;训练非常慢。
试验:
covn_base = keras.applications.VGG16(weights='imagenet', include_top=False) # weight参数表示是否使用预训练好的权重
# include_top参数表示是否包含最后的全连接层,False表示只包含卷积基
covn_base.summary()
model = keras.Sequential()
model.add(covn_base)
model.add(layers.GlobalAveragePooling2D()) # 功能类似于flatten,对上面最后输出进行扁平化,更高效,效果更好,训练参数比较少
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
covn_base.trainable = False # 把卷积基的权重设为不可训练,不进行改变
微调:
冻结模型库的底部的卷积层,共同训练新添加的分类器层和顶部部分卷积层。
底部的卷积层会提取一些通用的特征,顶部的卷积层随着视野的增大会形成一些抽象的图形,会更加的与特定的任务相关。
只有分类器已经训练好了,才可以微调卷积基的顶部的卷积层。否则刚开始训练误差很大,微调之前这些卷积层学到的表示会被破坏掉。
微调步骤:
一、在预训练卷积基上添加自定义层
二、冻结卷积基多有层
三、训练添加的分类层
四、解冻卷积基的一部分层
五、联合训练解冻的卷积层和添加的自定义层
实际操作:
covn_base.trainable = True
len(covn_base.layers) # 计算卷积基层数
fine_tune_at = -3 # 取最后三层进行微调
for layer in covn_base.layers[:fine_tune_at]:
layer.trainable = False # 除了最后三层,其余的都设为权值不改变
model.compile(optimizer=keras.optimizers.Adam(lr=0.0005/10), # 更低的学习速率,寻找loss的极值
loss='binary_crossentropy',
metrics=['acc'])
initial_epochs = 12 # 前面训练12次
fine_tune_epochs = 10 # 新的训练10次
total_epochs = initial_epochs + fine_tune_epochs
history = model.fit(
train_image_ds,
steps_per_epoch = train_count//BATCH_SIZE,
epochs = total_epochs,
initial_epoch = initial_epochs,
validation_data = test_image_ds,
validation_steps = test_count//BATCH_SIZE
)
常见的预训练网络模型
在 ImageNet 上与训练过的用于图像分类的模型:
VGG16、VGG19、ResNet50(用残差网络构建的模型)
InceptionV3、InceptionResNetV2、Xception(可分离卷积构建的模型)
MobileNet、MobileNetV2:适用于小模型
DenseNet、NASNet
以 Xception 为例:
tf.keras.applications.xception.Xception(
include_top=True, # 是否包含最后的全连接层
weights='imagenet', # None 表示随机初始化,imagenet 表示加载 ImageNet 上训练的权值
input_tensor=None,
input_shape=None, # 可选输入尺寸元组,仅当 include_top=False 有效,否则输入必须是(299,299,3),需拥有3个输入通道,宽高不小于71
pooling=None, # 可选,是否包含最后的全局池化
# 当 include_top=False,该参数指定了特征提取时的池化方式
# None 表示不池化,直接输出最后一层卷积层的输出,输出的是一个4D张量,需要人为的加一个 GlobalAveragePooling2D 层,输出变成2D张量
# 'avg' 代表全局平均池化(GlobalAveragePooling2D),相当于在最后一层卷积层后面加一层全局平均池化曾,输出 2D 张量
# 'max' 代表全局最大池化
classes=1000
)
该模型只支持 channels_last 的维度顺序(高度、宽度、通道)—— 一般情况,图片按照这个格式写,有些情况也会(通道、高度、宽度)
模型默认输入尺寸是 299x299
其他模型参考:https://keras.io/zh/applications/