(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, Keras 2.1.6, Tensorflow 1.9.0)git
前面的文章(【火爐煉AI】深度學習007-Keras微調進一步提高性能)咱們對二分類問題用Keras進行了Fine-tune,使得模型的準確率進一步提高,此處咱們看看對於多分類問題,怎麼使用Fine-tune來提高性能。github
和文章【火爐煉AI】深度學習008-Keras解決多分類問題如出一轍,在使用flow_from_directory時須要將class_mode修改成'categorical'。網絡
此處咱們創建的模型是使用VGG16的身子(inclue_top=False)做爲特徵提取器,和咱們本身定義的頭(前面文章【火爐煉AI】深度學習009-用Keras遷移學習提高性能(多分類問題)中訓練的模型和weights),這篇文章中已經達到了0.96的準確率。可是在前面這篇文章的遷移學習中,咱們並無修改VGG16這個網絡的weights參數,而是直接拿來提取特徵,此處的Fine-tune就是要調整VGG16網絡的較高層的卷積層的weights,使其更加適用於咱們本身的項目。app
以下是模型構建的函數:函數
# 4,構建模型
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import applications
from keras import optimizers
from keras.models import Model
def build_model():
base_model = applications.VGG16(weights='imagenet', include_top=False,input_shape=(IMG_W, IMG_H,IMG_CH))
# 此處咱們只須要卷積層不須要全鏈接層,故而inclue_top=False,必定要設置input_shape,不然後面會報錯
# 這一步使用applications模塊自帶的VGG16函數直接加載了模型和參數,做爲咱們本身模型的「身子」
# 下面定義咱們本身的分類器,做爲咱們本身模型的「頭」
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(class_num, activation='softmax')) # 多分類問題
top_model.load_weights(os.path.join(save_folder,'top_FC_model'))
# 上面定義了模型結構,此處要把訓練好的參數加載進來,
my_model = Model(inputs=base_model.input, outputs=top_model(base_model.output)) # 將「身子」和「頭」組裝到一塊兒
# my_model就是咱們組裝好的完整的模型,也已經加載了各自的weights
# 普通的模型須要對全部層的weights進行訓練調整,可是此處咱們只調整VGG16的後面幾個卷積層,因此前面的卷積層要凍結起來
for layer in my_model.layers[:15]: # 15層以前都是不需訓練的
layer.trainable = False
# 模型的配置
my_model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9), # 使用一個很是小的lr來微調
metrics=['accuracy'])
return my_model
複製代碼
-------------------------------------輸---------出--------------------------------性能
start to fine-tune my model Epoch 1/50 8/8 [==============================] - 124s 16s/step - loss: 0.0170 - acc: 0.9950 - val_loss: 0.2767 - val_acc: 0.9700 Epoch 2/50 8/8 [==============================] - 131s 16s/step - loss: 3.2684e-04 - acc: 1.0000 - val_loss: 0.2694 - val_acc: 0.9700 Epoch 3/50 8/8 [==============================] - 131s 16s/step - loss: 0.0175 - acc: 0.9950 - val_loss: 0.2593 - val_acc: 0.9700學習
。。。大數據
Epoch 48/50 8/8 [==============================] - 132s 16s/step - loss: 0.0025 - acc: 1.0000 - val_loss: 0.2758 - val_acc: 0.9700 Epoch 49/50 8/8 [==============================] - 130s 16s/step - loss: 0.0080 - acc: 0.9950 - val_loss: 0.2922 - val_acc: 0.9700 Epoch 50/50 8/8 [==============================] - 131s 16s/step - loss: 4.7076e-04 - acc: 1.0000 - val_loss: 0.2875 - val_acc: 0.9700優化
--------------------------------------------完-------------------------------------ui
acc 和loss圖爲:
能夠看出,test acc的準確率一直在0.97附近,在訓練開始和結束時的acc和loss變化不大,說明對於這個項目,微調的性能提高並不明顯,這是由於本項目所用的數據集過小,容易發生過擬合,經過增大數據集能夠解決這些問題。
########################小**********結###############################
1,使用Fine-Tune來解決多分類問題時,須要將loss改爲categorical_crossentropy,而且使用SGD優化器,使用很是小的learning rate,防止lr太大使得前面的卷積層網絡結構發生較大改變。
#################################################################
注:本部分代碼已經所有上傳到(個人github)上,歡迎下載。