Transfer Learning based on inceptionV3 using Keras, step by step

Step1. import 相關套件
#import建構模型所需使用的函式與套件
import keras
from keras import backend as K
from keras.models import Sequential
from keras.layers import Activation,GlobalAveragePooling2D,Dropout,InputLayer
from keras.layers.core import Dense, Flatten
from keras.optimizers import Adam
from keras.metrics import categorical_crossentropy
from keras.preprocessing.image import ImageDataGenerator
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import *
from sklearn.metrics import confusion_matrix
from keras.models import load_model
#import callbacks(用來監看訓練過程中所產生的數據)
from keras import callbacks
from keras.callbacks import EarlyStopping
from keras.callbacks import ModelCheckpoint
from keras.callbacks import TensorBoard
from keras.callbacks import CSVLogger
#其他相關套件
import os
import numpy as np


Step2. 依格式擺放訓練/驗證資料
用以擺放訓練圖片的路徑(./725kerasFormat/train),其下要擺放欲訓練類別的資料夾(clear與dirty),其下再擺放圖片:

if __name__=='__main__':
    train_path = './725kerasFormat/train'
    valid_path = './725kerasFormat/valid'
Step3. 設計模型參數
    imgHeight=89#
    imgWidth=175#
    input_shapew=(imgHeight,imgWidth,3) #依後續模型需求可能要有不同的輸入樣本
                                       #格式,這邊以channel last格式為例
    nb_train_samples=443#包含所有類別的訓練樣本總數
    nb_validation_samples=40#包含所有類別的驗證樣本總數
    batch_size_train=443#training set的batch size大小,等同訓練樣本數表示一次epoch只更新一次。
    batch_size_valid=40#validation set的batch size大小
    epochs = 80 #所有訓練樣本利用完一次,便稱為一次epoch
    #下述horizontal_flip=True表示可以水平方向進行data augmentation
    train_generator = ImageDataGenerator(rescale=1. / 255,horizontal_flip=True).flow_from_directory(train_path, target_size=(imgHeight,imgWidth), batch_size=batch_size_train)
    valid_generator = ImageDataGenerator(rescale=1. / 255,horizontal_flip=True).flow_from_directory(valid_path, target_size=(imgHeight,imgWidth), batch_size=batch_size_valid)
 此時若輸出test_generator.class_indices亦可知,內部其實自動標註clear為類別0而dirty為類別1:
print('train_generator.class_indices=', train_generator.class_indices)

Step4. 建構模型(利用transfer learning)
    #預載InceptionV3模型及其權重
    #include_top表示刪除該模型最"後面"(keras中模型建構是先進後出的概念)幾層的
    #fully connected layer。而模型最後面幾層的fully connected layer權重是
    #依據(299, 299, 3)的input size訓練而得,故只有在include_top=False時
    #input_shape參數才有用
    modelGet = keras.applications.InceptionV3(include_top=False,input_shape=input_shapew)
    
    #建構模型(下面InputLayer部分不寫亦可,因InceptionV3已給input_shape了)
    model = Sequential()
    main_input = InputLayer(input_shape=input_shapew, name='input_layer')
    model.add(main_input)
    model.add(modelGet)
    model.add(GlobalAveragePooling2D())
    #被drop out的比例(不是保留的比例)
    model.add(Dropout(0.3))
    #2表示輸出只有兩個類別
    model.add(Dense(2,activation='softmax'))
    #不必freeze 預載的權重。表示訓練時初始權重來自inceptionV3,且可繼續更新其權重
    for layer in model.layers:
        layer.trainable=True
    
    #show出模型
    model.summary()

Step5. 編譯模型
    #這邊採用Adam形式的gradient descent且learning rate設為0.00005。
    #loss function則設為categorical_crossentropy
    model.compile(Adam(lr=.00005), loss='categorical_crossentropy', metrics=['accuracy'])
 
Step6. 設計如何監看訓練過程(keras.callbacks)
這邊主要用到三個函式:TensorBoard, ModelCheckpoint與CSVLogger
    #設定TensorBoard與ModelCheckpoint會用到的路徑
    log_dir ='./tf-log0.3/'
    filepath='./bestmodel/weights0.3.epoNum:{epoch:02d}-val_loss:{val_loss:.3f}-val_acc:{val_acc:.3f}.hdf5'

    #----TensorBoard----
    #寫出一個以events.out開頭的log file(內含訓練過程的數據)供tensorboard(可視化工具)日後開啟
    tb=TensorBoard(log_dir=log_dir, histogram_freq=0)
    #----EarlyStopping----
    #val_loss只要連續patience次都沒有進步(一次變動大於min_delta即有進步)就停止訓練
    early_stopping = EarlyStopping(monitor='val_loss',patience=30,min_delta=0.001)
    #----ModelCheckpoint----
    #save_best_only=True表示訓練過程中有進步的模型便儲存起來
    ckp = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=True, mode='auto')
    #將訓練過程的數據都存成csv檔
    csv_logger = CSVLogger('log.csv', append=True, separator=';')

    #將上述函式組起來
    callbacks_list = [tb, early_stopping,ckp,csv_logger]

Step7. 訓練模型
    fit_generator會batch by batch地更新模型,且將過程中的數據依據Step6所述的callbacks紀錄。
    model.fit_generator(train_generator,
                        steps_per_epoch=nb_train_samples // batch_size_train,
                        epochs=epochs,
                        validation_data=valid_generator,
                        validation_steps=nb_validation_samples // batch_size_valid,
                        callbacks=callbacks_list
                        )
 


 

留言

這個網誌中的熱門文章

[Android] TextView 換行

[Android]android Global variable 寫法

[Android] build the JAR file in Android Studio