文章来源:https://medium.com/@14prakash/transfer-learning-using-keras-d804b2e04ef8
本文主要演示了使用Keras进行Transfer Learning的步骤,以及不同类型的数据应该选择什么样的“迁移方式(文字需斟酌)”
注意:Keeping in mind that convnet features are more generic in early layers and more original-dataset-specific in later layers。即神经网络前端的features通用性更强,越往后端features更专,泛化性减弱。
1、若新数据集小,与原数据集相似
小数据集暴露的问题是容易过拟合,既然两个数据集相似,我们认为神经网络后端的features是相关的,可以用来训练新数据集。做法:保留原有的卷积层结构和权重,只训练最后的全连接层。
for layer in model.layers:
layer.trainable = False
#冻结了卷积层的结构和权重
#Now we will be training only the classifiers (FC layers)
#问题:👆的这个layer默认不包括全连接层???
2、新数据集大,与原数据集相似
既然数据集足够大,我们就不用担心过拟合问题,可以走通整个神经网络来调参,训练更好的模型。
for layer in model.layers:
layer.trainable = True
#默认值就是可以训练的。 The default is already set to True.
因为前几层神经网络识别的是边缘(edges & blobs),通用性较高,可以选择冻结前几层,减少计算量
for layer in model.layers[:5]:
layer.trainable = False
#例如冻结前5层
3、若新数据集小,与原数据集差异大
既然差异大,我们可能只想获取神经网络前几层的features,并且在这个基础上直接训练classfier(而不会再加几层卷积层)。
注:这里使用的不是Sequential,而是Model
from keras.models import Model
from keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense, Dropout
img_width, img_height = 256, 256
###Build the network
img_input = Input(shape=(256, 256, 3))
x = Conv2D(64, (3,3), padding='same', activation='relu', name='block1_conv1')(img_input)
x = Conv2D(64, (3,3), padding='same', activation='relu', name='block1_conv2')(x)
x = MaxPooling2D(pool_size=2, name='block1_pool')(x)
#block2
x = Conv2D(128, (3,3), padding='same', activation='relu', name='block2_conv1')(x)
x = Conv2D(128, (3,3), padding='same', activation='relu', name='block2_conv2')(x)
x = MaxPooling2D(pool_size=2, name='block2_pool')(x)
model = Model(input=img_input, output=x)
model结构
然后将original dataset对应这几层的参数传过来(在Udacity的项目中,transfer learning似乎不需要这么麻烦)










网友评论