深度学习 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/

 

posted @ 2020-10-12 21:30  我脑子不好  阅读(399)  评论(0编辑  收藏  举报