五种卷积神经网络解决猫狗分类问题(五):V5 预训练-微调模型

版本描述epochs训练精度验证精度
V1.0简单线性卷积神经网络10099%75%
V2.0添加了数据增强和dropout层10083%83%
V3.0使用预训练-特征提取-分步式10099%90%
V4.0使用预训练-特征提取-合并式10090%90%
V5.0使用预训练-微调模型10099%94%

五种卷积神经网络解决猫狗分类问题(零):总概要
五种卷积神经网络解决猫狗分类问题(一):V1 简单线性网络
五种卷积神经网络解决猫狗分类问题(二):V2 简单线性网络上添加数据增强和dropout层
五种卷积神经网络解决猫狗分类问题(三):V3 预训练-特征提取-分步式
五种卷积神经网络解决猫狗分类问题(四):V4 预训练-特征提取-合并式
五种卷积神经网络解决猫狗分类问题(五):V5 预训练-微调模型

1. 微调模型

相对于特征提取冻结所有卷积基,微调模型则是冻结部分卷积基,剩余卷积基层和自定义分类器联合训练
在这里插入图片描述
一般分为卷积基和分类器:如上图,卷积基又分为5个块。
所谓的微调模型就是冻结部分卷积基(卷积块1~4),训练部分卷积基(卷积块5)和分类器

2. 微调模型步骤

1. 在预训练网络上添加自定义网络(分类器)
2. 冻结基网络
3. 训练添加的自定义网络
4. 解冻部分基网络的一些层(此时学习率低一点,不要有太大的更新,1e-5)
5. 联合训练解冻的这些层和添加的自定义网络

由上面的步骤可以看出,步骤1~3很想预训练网络-特征提取:即冻结全部卷积基,训练分类器,步骤4-5才是微调模型的独特步骤,即解冻部分卷积基,再次训练
步骤1~3类似粗调模型,使得精度达到一定水平,再解冻部分卷积基,再次训练经行细调(学习率很低,更新波动小)

3. 解冻多少层合适?

在这里插入图片描述
所以一般来讲解冻最后2~3就可以了

4. 代码

4.1 步骤1~3的代码

五种卷积神经网络解决猫狗分类问题(四):预训练-特征提取-合并式

#!/usr/bin/env python
# coding: utf-8

# ### 导入预训练网络
# - 设置导入的卷积基不可被训练,从而保护其在训练时不被更新
from keras.applications import VGG16
from keras import layers
from keras import models

conv_base=VGG16(include_top=False,
                weights='imagenet',
                input_shape=(150,150,3))
conv_base.trainable=False  # 冻结参数,使之不被更新


# ### 定义网络模型
# - 使用add()函数堆叠即可
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()


# ### 数据准备(数据生成器)
from keras.preprocessing.image import ImageDataGenerator

train_dir='../dogs-vs-cats_small/train/'
validation_dir='../dogs-vs-cats_small/validation/'
test_dir='../dogs-vs-cats_small/test/'

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),
                                                 batch_size=20,
                                                 class_mode='binary')
validation_generator=test_datagen.flow_from_directory(validation_dir,
                                                     target_size=(150,150),
                                                     batch_size=20,
                                                     class_mode='binary')


# ### 配置模型
from keras import optimizers
model.compile(loss='binary_crossentropy',
             optimizer=optimizers.RMSprop(lr=2e-5),
             metrics=['acc'])


# ### 开始训练
history=model.fit_generator(train_generator,
                           steps_per_epoch=100,
                           epochs=100,
                           validation_data=validation_generator,
                           validation_steps=50)


# 可视化
import matplotlib.pyplot as plt

train_acc=history.history['acc']
train_loss=history.history['loss']

val_acc=history.history['val_acc']
val_loss=history.history['val_loss']

epoch=range(1,len(train_acc)+1)

plt.plot(epoch,train_acc,'bo',label='Train_acc')
plt.plot(epoch,val_acc,'b',label='val_acc')
plt.title("training and validation accuracy")
plt.legend()

plt.figure()
plt.plot(epoch,train_loss,'bo',label='Train_losx')
plt.plot(epoch,val_loss,'b',label='val_loss')
plt.title("training and validation loss")
plt.legend()
plt.show()
4.2 步骤4:解冻部分卷积基

先看VGG16的卷积基:
在这里插入图片描述
我们将解冻block5_conv1~最后的总共4层(实际上卷积层只有3层)
通过每层的trainable属性来设定该层是否可训练:

conv_base.trainable=True

set_trainable=False
for layer in conv_base.layers:      # 一但name==block5_covn1,set_trainable就永远为True,后面的层都设置为True
    if layer.name=="block5_conv1":
        set_trainable=True
    if set_trainable:
        layer.trainable=True
    else:
        layer.trainable=False
4.3 步骤5:配置模型和开始训练
model.compile(loss='binary_crossentropy',
             optimizer=optimizers.RMSprop(lr=1e-5),
             metrics=['acc'])

history=model.fit_generator(train_generator,
                           steps_per_epoch=100,
                           epochs=100,
                           validation_data=validation_generator,
                           validation_steps=50)

在这里插入图片描述
可以看出验证集精度达到了94%,是V1~V5中最高的

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一个对称矩阵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值