【火爐煉AI】深度學習010-Keras微調提高性能(多分類問題)

【火爐煉AI】深度學習010-Keras微調提高性能(多分類問題)

(本文所使用的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


1. 準備數據集

和文章【火爐煉AI】深度學習008-Keras解決多分類問題如出一轍,在使用flow_from_directory時須要將class_mode修改成'categorical'。網絡


2. 對VGG16的後半部分進行Fine-tune

此處咱們創建的模型是使用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)上,歡迎下載。

相關文章
相關標籤/搜索