目录
迁移学习:是利用之前训练好的模型,在当前的任务上进行提升。
Fine_tune 训练较少次数即可以得到较好的模型
1. fine_tune实战
使用10 monkeys数据集
1.1 读取数据
# 通过height, width 参数来将输入的图片规整为统一的尺寸
height = 224 # 图片的长
width = 224 # 图片的宽
channels= 3 # 图片的通道数,R,G,B 3通道
batch_size= 24
num_classes = 10 # 类别数目
# 通过ImageDataGenerator 对数据进行增强
# 训练数据
train_datagen= keras.preprocessing.image.ImageDataGenerator(
preprocessing_function = keras.applications.resnet50.preprocess_input, # 相当于 rescale = 1./255
rotation_range = 40, # 图像增强的一种方式,比如 ratation_range = 40, 表示将图像随机旋转的角度为-40——40度之间。
width_shift_range = 0.2, # 水平方向上的位移,小于1,表示的就是位移的比例;大于1,就是移动的像素值。width_shift_range = 0.2,表示图像随机平移0——20%
height_shift_range = 0.2, # 竖直方向上的位移
shear_range = 0.2, # 剪切强度
zoom_range = 0.2, # 缩放强度
horizontal_flip = True, # 是否在水平方向上做随机反转
fill_mode = 'nearest') # 对图片做处理时,需要填充像素时使用。比如,对图像做放大操作,有些像素点需要填充。
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size = (height, width),
batch_size = batch_size,
seed = 7,
shuffle = True,
class_mode = "categorical")
# 验证数据
valid_datagen= keras.preprocessing.image.ImageDataGenerator(
preprocessing_function = keras.applications.resnet50.preprocess_input # 相当于 rescale = 1./255
)
valid_generator = train_datagen.flow_from_directory(
valid_dir,
target_size = (height, width),
batch_size = batch_size,
seed = 7,
shuffle = False,
class_mode = "categorical")
1.2 构建模型
在resnet50的基础上迁移学习
对resetnet模型有一个大致的了解
resnet50 = keras.applications.ResNet50(include_top = False,
pooling = 'avg',
weights = 'imagenet')
resnet50.summary()
1.2.1 resnet模型不训练
resnet50_fine_tune = keras.models.Sequential()
resnet50_fine_tune.add(keras.applications.ResNet50(include_top = False,
pooling = 'avg',
weights = 'imagenet'))
resnet50_fine_tune.add(keras.layers.Dense(num_classes, activation = 'softmax'))
resnet50_fine_tune.layers[0].trainable = False
resnet50_fine_tune.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
resnet50_fine_tune.summary()
训练模型
epochs = 10 # fine_tune 训练较少次数即可以得到较好的模型
history = resnet50_fine_tune.fit(train_generator,
steps_per_epoch = train_num // batch_size,
epochs = epochs,
validation_data = valid_generator,
validation_steps = valid_num // batch_size)
print(history.history.keys())
画图(准确率和损失)
# 将loss 和 acc 分开两个图画,plot_key 可取 loss 或 acc
def plot_learning_curves(history, plot_key, epochs, min_value, max_value):
data = {}
data[plot_key] = history.history[plot_key]把
data['val_' + plot_key] = history.history['val_' + plot_key]
pd.DataFrame(data).plot(figsize=(8, 5))
plt.grid(True)
plt.axis([0, epochs, min_value, max_value])
plt.show()
plot_learning_curves(history, 'accuracy', epochs, 0, 1)
plot_learning_curves(history, 'loss', epochs, 0, 2.5)
1.2.2 resnet模型部分层次训练
for layer in resnet50.layers[0:-5]:
layer.trainable = False
resnet50_new = keras.models.Sequential([
resnet50,
keras.layers.Dense(num_classes, activation = 'softmax'),
])
resnet50_new.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
resnet50_new.summary()
训练模型和画图,同上
1.2.3 效果对比
1.2.2 对resnet模型部分层次训练,效果变差?
(1)可训练的参数变多了,导致如果要训练出一个比较好的效果需要一定的时间
(2)resnet最后几层也本来都是训练好的,比较好的参数。若再进行训练,在较大的learning_rate的情况下,可能会跳出“最优值”,导致情况变差。