内容简介:(本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, Keras 2.1.6, Tensorflow 1.9.0)本文是仿照前面的文章同时,在我前面的文章中
(本文所使用的 Python 库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, Keras 2.1.6, Tensorflow 1.9.0)
本文是仿照前面的文章 【火炉炼AI】深度学习006-移花接木-用Keras迁移学习提升性能 ,原文是针对二分类问题,使用迁移学习的方式来提升准确率,此处我用迁移学习的方式来提升多分类问题的准确率。
同时,在我前面的文章中 【火炉炼AI】深度学习008-Keras解决多分类问题 ,使用普通的小型3层卷积网络+2层全连接层实现了多分类的85%左右的准确率, 此处我将用迁移学习的方式来进一步提升性能。
1. 准备数据集
与上一篇文章相同。
2. 模型的构建和训练
使用迁移学习包括两个步骤:第一步是用VGG16网络提取bottleneck features,然后保存这些特征,第二步建立自己的分类器,然后用用保存的特征来训练分类器,优化weights。下面是第一步的代码,只注意一个地方:要修改为:class_mode='categorical'
# 此处的训练集和测试集并不是原始图片的train set和test set,而是用VGG16对图片提取的特征,这些特征组成新的train set和test set
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import applications
def save_bottlebeck_features():
datagen = ImageDataGenerator(rescale=1. / 255) # 不需图片增强
# build the VGG16 network
model = applications.VGG16(include_top=False, weights='imagenet')
# 使用imagenet的weights作为VGG16的初始weights,由于只是特征提取,故而只取前面的卷积层而不需要DenseLayer,故而include_top=False
generator = datagen.flow_from_directory( # 产生train set
train_data_dir,
target_size=(IMG_W, IMG_H),
batch_size=batch_size,
class_mode='categorical', # 这个地方要修改,要不然出错
shuffle=False) # 必须为False,否则顺序打乱之后,和后面的label对应不上。
bottleneck_features_train = model.predict_generator(
generator, train_samples_num // batch_size)
np.save(os.path.join(save_folder,'bottleneck_features_train.npy'), bottleneck_features_train)
print('bottleneck features of train set is saved.')
generator = datagen.flow_from_directory(
val_data_dir,
target_size=(IMG_W, IMG_H),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
bottleneck_features_validation = model.predict_generator(
generator, val_samples_num // batch_size)
np.save(os.path.join(save_folder,'bottleneck_features_val.npy'),bottleneck_features_validation)
print('bottleneck features of test set is saved.')
复制代码
第二步: 定义自己的分类器,专门适用于本项目的多分类问题,要将最后的Dense层修改为:model.add(Dense(class_num, activation='softmax')),并且loss使用'categorical_crossentropy'。
def my_model():
'''
自定义一个模型,该模型仅仅相当于一个分类器,只包含有全连接层,对提取的特征进行分类即可
:return:
'''
# 模型的结构
model = Sequential()
model.add(Flatten(input_shape=train_data.shape[1:])) # 将所有data进行flatten
model.add(Dense(256, activation='relu')) # 256个全连接单元
model.add(Dropout(0.5)) # dropout正则
model.add(Dense(class_num, activation='softmax')) # 与二分类不同之处:要用Dense(class_num)和softmax
# 模型的配置
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy']) # model的optimizer等
return model
复制代码
然后使用保存的特征对该分类器进行训练,训练时有一个地方要注意:在二分类问题时,我们直接将labels定义为np.array([0]*80+[1]*80),但是多分类问题,需要用to_categorical进行转换,然后再放入到fit中。
from keras.utils import to_categorical
# 只需要训练分类器模型即可,不需要训练特征提取器
train_data = np.load(os.path.join(save_folder,'bottleneck_features_train.npy')) # 加载训练图片集的所有图片的VGG16-notop特征
train_labels = np.array([0] * 80 + [1] * 80+ [2]*80+[3]*80+[4]*80)
# label是每个类别80张图片,共5个类别
# 设置标签,并规范成Keras默认格式
train_labels = to_categorical(train_labels, class_num)
validation_data = np.load(os.path.join(save_folder,'bottleneck_features_val.npy'))
validation_labels = np.array([0] * 20 + [1] * 20+ [2]*20+[3]*20+[4]*20)
validation_labels = to_categorical(validation_labels, class_num)
# 构建分类器模型
clf_model=my_model()
history_ft = clf_model.fit(train_data, train_labels,
epochs=epochs,
batch_size=batch_size,
validation_data=(validation_data, validation_labels))
复制代码
-------------------------------------输---------出--------------------------------
Train on 400 samples, validate on 100 samples Epoch 1/50 400/400 [==============================] - 1s 2ms/step - loss: 4.8496 - acc: 0.4725 - val_loss: 3.4864 - val_acc: 0.6900 Epoch 2/50 400/400 [==============================] - 0s 878us/step - loss: 3.4436 - acc: 0.7400 - val_loss: 3.3577 - val_acc: 0.7400 Epoch 3/50 400/400 [==============================] - 0s 845us/step - loss: 0.6014 - acc: 0.9300 - val_loss: 0.1798 - val_acc: 0.9600
...
Epoch 48/50 400/400 [==============================] - 0s 860us/step - loss: 5.4962e-06 - acc: 1.0000 - val_loss: 0.3184 - val_acc: 0.9500 Epoch 49/50 400/400 [==============================] - 0s 853us/step - loss: 0.0438 - acc: 0.9850 - val_loss: 0.2470 - val_acc: 0.9600 Epoch 50/50 400/400 [==============================] - 0s 855us/step - loss: 5.5508e-04 - acc: 1.0000 - val_loss: 0.2798 - val_acc: 0.9700
--------------------------------------------完-------------------------------------
最后将acc和loss绘图,如下:
可以看出最后的test acc达到了0.96以上。
########################小**********结###############################
1,多分类的迁移学习问题需要注意几个地方:提取bottleneck features时要设置class_mode='categorical'。构建自己的分类器时要把输出层的Dense修改,然后把激活函数和损失函数修改为多分类对应的函数。在做labels时,要先用to_categorical转变为one-hot形式再输入到模型中进行fit.
#################################################################
注:本部分代码已经全部上传到( 我的github )上,欢迎下载。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Zen of CSS Design
Dave Shea、Molly E. Holzschlag / Peachpit Press / 2005-2-27 / USD 44.99
Proving once and for all that standards-compliant design does not equal dull design, this inspiring tome uses examples from the landmark CSS Zen Garden site as the foundation for discussions on how to......一起来看看 《The Zen of CSS Design》 这本书的介绍吧!