keras-迁移学习(fine-tuning)

不同修改预训练模型方式的情况:

  1. 特征提取
    我们可以将预训练模型当做特征提取装置来使用。具体的做法是,将输出层去掉,然后将剩下的整个网络当做一个固定的特征提取机,从而应用到新的数据集中。
  2. 采用预训练模型的结构
    我们还可以采用预训练模型的结构,但先将所有的权重随机化,然后依据自己的数据集进行训练。
  3. 训练特定层,冻结其它层
    另一种使用预训练模型的方法是对它进行部分的训练。具体的做法是,将模型起始的一些层的权重保持不变,重新训练后面的层,得到新的权重。在这个过程中,我们可以多次进行尝试,从而能够依据结果找到frozen layers和retrain layers之间的最佳搭配。
    如何使用与训练模型,是由数据集大小和新旧数据集(预训练的数据集和我们要解决的数据集)之间数据的相似度来决定的。
    下图表展示了在各种情况下应该如何使用预训练模型:
    在这里插入图片描述
    原文:https://blog.csdn.net/u011268787/article/details/80170482

fine-tuning方式一:使用预训练网络的bottleneck特征

先看VGG-16的网络结构如下:
在这里插入图片描述
本节主要是通过已经训练好的模型,把bottleneck特征抽取出来,然后滚到下一个“小”模型里面,也就是全连接层。
实施步骤为:

1、把训练好的模型的权重拿来,model;
2、运行,提取bottleneck feature(网络在全连接之前的最后一层激活的feature
map,卷积-全连接层之间),单独拿出来,并保存
3、bottleneck层数据,之后 + dense全连接层,进行fine-tuning

1、导入预训练权重与网络框架

WEIGHTS_PATH = '/home/ubuntu/keras/animal5/vgg16_weights_tf_dim_ordering_tf_kernels.h5' 
WEIGHTS_PATH_NO_TOP = '/home/ubuntu/keras/animal5/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5' 
from keras.applications.vgg16_matt import VGG16 
model = VGG16(include_top=False, weights='imagenet')

其中WEIGHTS_PATH_NO_TOP 就是去掉了全连接层,可以用他直接提取bottleneck的特征

2、提取图片的bottleneck特征

需要步骤:

1. 载入图片;
2. 灌入pre-model的权重;
3. 得到bottleneck feature

代码:

#如何提取bottleneck feature 
from keras.models import Sequential 
from keras.layers import Conv2D, MaxPooling2D 
from keras.layers import Activation, Dropout, Flatten, Dense
# (1)载入图片 
# 图像生成器初始化 
from keras.preprocessing.image import ImageDataGenerator 
import numpy as np 
datagen = ImageDataGenerator(rescale=1./255)
# 训练集图像生成器 
generator = datagen.flow_from_directory( '/home/ubuntu/keras/animal5/train', 
				target_size=(150, 150), batch_size=32, class_mode=None, shuffle=False) 
# 验证集图像生成器 
generator = datagen.flow_from_directory( '/home/ubuntu/keras/animal5/validation', 
				target_size=(150, 150), batch_size=32, class_mode=None, shuffle=False)
				
#(2)灌入pre-model的权重
model.load_weights('/.../vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5')

#(3)得到bottleneck feature 
bottleneck_features_train = model.predict_generator(generator, 500) 
#核心,steps是生成器要返回数据的轮数,每个epoch含有500张图片,与model.fit(samples_per_epoch)相对 
np.save(open('bottleneck_features_train.npy', 'w'), bottleneck_features_train)

bottleneck_features_validation = model.predict_generator(generator, 100) 
#与model.fit(nb_val_samples)相对,一个epoch有800张图片,验证集 
np.save(open('bottleneck_features_validation.npy', 'w'), bottleneck_features_validation)

3、 fine-tuning - "小"网络

主要步骤:

(1)导入bottleneck_features数据;
(2)设置标签,并规范成Keras默认格式;
(3)写“小网络”的网络结构
(4)设置参数并训练

在这里插入图片描述

fine-tuning方式二:要调整权重

先来看看整个结构。
在这里插入图片描述
fine-tune分三个步骤:

  1. 搭建vgg-16并载入权重,将之前定义的全连接网络加在模型的顶部,并载入权重
  2. 冻结vgg16网络的一部分参数
  3. 模型训练

注意:

1、fine-tune,所有的层都应该以训练好的权重为初始值,例如,你不能将随机初始的全连接放在预训练的卷积层之上,这是因为由随机权重产生的大梯度将会破坏卷积层预训练的权重。
2、选择只fine-tune最后的卷积块,而不是整个网络,这是为了防止过拟合。整个网络具有巨大的熵容量,因此具有很高的过拟合倾向。由底层卷积模块学习到的特征更加一般,更加不具有抽象性,因此我们要保持前两个卷积块(学习一般特征)不动,只fine-tune后面的卷积块(学习特别的特征)
3、fine-tune应该在很低的学习率下进行,通常使用SGD优化而不是其他自适应学习率的优化算法,如RMSProp。这是为了保证更新的幅度保持在较低的程度,以免毁坏预训练的特征。

扫描二维码关注公众号,回复: 4808280 查看本文章

1、步骤一:搭建vgg-16并载入权重

在这里插入图片描述

2、冻结vgg16网络的一部分参数

然后将最后一个卷积块前的卷积层参数冻结:
在这里插入图片描述

3、模型训练

然后以很低的学习率进行训练:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/xys430381_1/article/details/84988352