imagenet在图像识别领域里面有着很高地知名度,数据量大,数据类别多,很多比赛也都是围绕着这个数据集展开的,我们今天并不是要使用这么大的数据集,因为的确是算力不太能达到要求,这里就退而求其次,使用网上公开的mini-imagenet数据集来进行实验,这个数据集里面一共有6w张图片,共分为100个类别,每个类别里面有600张图片。
数据集截图如下所示:
接下来随便看几个类别的数据集。
n01981276:
n02099601:
n02116738:
n13133613:
迁移学习是一种很强大的深度学习技术,在实际应用中解决图像分类等问题中效果卓越,用一句简单的话来说就是“站在巨人的肩膀山学习”,大多数针对图像分类任务而开源出来的迁移学习模型很多都是基于ImageNet数据集开发的,这些预训练的模型往往都是那些谷歌、亚马逊等大厂耗费大量的计算资源训练几周的时间跑出来的模型,在图像的特征提取计算上都有着非常不错的性能,以至于对于我们【小批量数据+简单神经网络】模式的实验来说,我们往往会选择使用【预训练模型+fine-tuning】的方式来高效地达到我们所需的效果,请注意,这里是高效。
首先我们来开发一个数据生成器,用于后续模型的训练:
def imageGenerator(h=224,w=224):
'''
由于深度学习模型所需数据较多,这里设计实现了图片生成器
'''
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')
validation_datagen=ImageDataGenerator(rescale=1./255)
train_generator=train_datagen.flow_from_directory(trainDir,target_size=(224,224),batch_size=bsize,
class_mode='categorical')
validation_generator=validation_datagen.flow_from_directory(testDir,target_size=(224, 224),
batch_size=bsize,class_mode='categorical')
return train_generator,validation_generator
接下来初始化模型:
def myVGGModel(freeze_num=11,h=224,w=224,way=3):
'''
初始化定义迁移学习模型
'''
conv_base=VGG19(input_shape=(h,w,3), include_top=False, weights='imagenet')
x=conv_base.output
x=Dense(512, activation='relu',kernel_regularizer=regularizers.l2(l=0.0001))(x)
x=Dropout(0.3)(x)
prediction=Dense(62,activation='softmax')(x)
model=Model(inputs=conv_base.input,outputs=prediction) #构造完新的FC层,加入custom层
model.summary()
print("layer nums:", len(model.layers))
for layer in model.layers[:freeze_num]:
layer.trainable = False
for layer in model.layers[freeze_num:]:
layer.trainable = True
for layer in model.layers:
print("layer.trainable:", layer.trainable)
#模型编译
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9),
loss='categorical_crossentropy', metrics=['accuracy'])
return model
接下来是模型的训练部分:
#模型训练拟合计算
history=model.fit_generator(train_generator,epochs=1000,validation_data=test_generator)
#训练数据曲线可视化
print(history.history.keys())
plt.clf()
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epochs')
plt.legend(['train','test'], loc='upper left')
plt.savefig(saveDir+'train_validation_acc.png')
plt.clf()
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epochs')
plt.legend(['train', 'test'], loc='upper left')
plt.savefig(saveDir+'train_validation_loss.png')
#保存模型结构+权重数据
model_json=model.to_json()
with open(saveDir+'structure.json','w') as f:
f.write(model_json)
model.save_weights(saveDir+'weight.h5')
print('Model Save Success.........................................')
训练结束后,我设定了自动存储模型的结构和权重信息,另外对整个训练过程的loss曲线和准确度曲线也进行了可视化。
train_validation_acc.png如下所示:
train_validation_loss.png如下所示:
默认训练了1000次,在验证集上达到了76%左右的精度,这个还没有调参,对于这个数据量应该还算可以的了: