【Keras版本】:2.2.2,推薦閱讀下官方中文網站的 Demo :https://keras-cn.readthedocs.io/en/latest/other/application/#inceptionv3
【適用場合】:
沒有硬件:例如眾所周知的Inception v3模型,此模型在一台配有 8 Tesla K40 GPUs,大概價值$30,000的野獸級計算機上,訓練了幾個星期。你有這樣的硬件么?
沒有數據:針對特定問題,訓練模型的前提是數據!以太陽能電池板隱裂缺陷檢測為例,太陽能電池板整體缺陷率為0.2%左右,包括10+種缺陷,訓練一個能滿足工業需求的模型需要多少數據?1千,1萬,10萬還是多少,假設需要1000張缺陷數據,那就要從至少50萬片圖像中選取,你能得到這么多數據么?
那怎么辦?——用別人訓練好的模型+少量數據進行模型訓練,在短時間內訓練得出滿意的效果。這便是遷移學習。
【遷移學習分類】:分為兩種
1 第一種 Transfer Learning:訓練時,移掉最頂層,換上新的頂層,比如輸出為10的全連接層。訓練時只訓練最后兩層,其它層設置為不可訓練,把下載的模型當成一個特征提取器。
【疑問】:傳言具有相同分布的數據可以使用遷移學習獲得很好的效果,不同分布效果不好!那么,怎么判斷數據具有相同分布?
2 第二種 Fine Tune,換一個新的頂層,但在訓練的過程中,所有的或大部分層都會經過訓練。
【遷移學習的基本過程】
典型的遷移學習過程:首先通過Transfer Learning對新的數據集進行訓練,訓練過一定epoch之后,改用Fine Tune方法繼續訓練,同時降低學習率。
這樣做是因為如果一開始就采用Fine Tune方法的話,后段網絡還沒有適應新的數據,那么在進行參數更新的時候,比較大的梯度可能會導致原本訓練的比較好的參數被污染,反而導致效果下降。
【導入相應的模塊】
1 import keras 2 from keras.datasets import cifar10 3 from keras.preprocessing.image import ImageDataGenerator #導入圖像數據預處理模塊中的圖像增強類 ImageDataGenerator 4 from keras.applications.inception_v3 import InceptionV3 5 from keras.layers import Dense, Input, GlobalAveragePooling2D 6 from keras.models import Model
【數據增強與准備數據集】:下載地址:https://download.csdn.net/download/tsyccnh/10641502 ,網友辛苦整理的,我就不把我下載的分享了
當數據集較大時,不適合一次將全部數據載入到內存中,所以使用了Keras 框架中圖像增強部分的ImageDataGenerator
類的flow_from_directory方法構建了一個生成器,按批次從硬盤讀取圖像數據,並實時進行圖像增強。
flow_from_directory以文件夾路徑為參數,生成經過數據提升/歸一化后的數據,在一個無限循環中無限產生batch數據。
1 #數據增強設置 2 train_datagen = ImageDataGenerator( 3 rescale=1./255, 4 shear_range=0.2, 5 zoom_range=0.2, 6 horizontal_flip=True) 7 vali_datagen = ImageDataGenerator(rescale=1./255) 8 9 #使用文件夾下的數據作為數據集 10 train_generator = train_datagen.flow_from_directory(directory=r'C:\Users\Administrator\Downloads\flowers17\train', 11 target_size=(299,299),#Inception V3規定大小 12 batch_size=64) 13 vali_generator = vali_datagen.flow_from_directory(directory=r'C:\Users\Administrator\Downloads\flowers17\validation', 14 target_size=(299,299), 15 batch_size=64)
【模式設置】:GAP_LAYER 設置請參考 https://blog.csdn.net/tsyccnh/article/details/78889838
1 #兩種模式 2 #設置模型參數不可更新 3 def set_model_to_transfer_learning(model,base_model):#base_model 4 for layer in base_model.layers: 5 layer.trainable = False 6 #from keras.optimizers import SGD 7 #model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy') #官方示例工程中設置的優化器 8 model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy']) 9 #***********************************************************************# 10 # 編譯時指定優化器 11 # 優化器可以定制,學習率在優化器定制時可以設置 12 #***********************************************************************# 13 #設置模型為全局調優 14 def set_model_to_fine_tune(model,base_model): 15 GAP_LAYER = 17 # max_pooling_2d_2 16 for layer in base_model.layers[:GAP_LAYER+1]: 17 layer.trainable = False 18 for layer in base_model.layers[GAP_LAYER+1:]: 19 layer.trainable = True 20 model.compile(optimizer=Adagrad(lr=0.0001),loss='categorical_crossentropy',metrics=['accuracy'])
【定義模型】
1 #構建定制的Inception v3 模型:分三步 2 3 #第一步:導入基礎模型和模型參數 4 5 #前方高能,下載超慢!80多兆,我這要下載34小時! 6 #解決辦法,使用迅雷下載下來,替換掉 C:\Users\Administrator\.keras\models下的同名文件 7 #下載路徑會在下載超時報錯時顯示 8 base_model = InceptionV3(weights='imagenet',include_top=False) #加載模型,weights 表示下載模型參數,include 設置表示不包含頂層,即后面的全連接層 9 #base_model.summary();#先看下basemodel的結構 10 11 #第二步:更改最后幾層 12 # 增加新的輸出層 13 # 首先獲得base_model的輸出 14 # 增加 15 base_output = base_model.output 16 global_average= GlobalAveragePooling2D()(base_output) # 全局平均池化[*]這里會將前面 M*N*C 的張量轉變為1*N的張量。全局平均池化的目的是為了替換全連接層,簡化模型 17 # 18 dense = Dense(1024,activation='relu')(global_average) 19 output = Dense(17,activation='softmax')(dense) 20 model = Model(inputs=base_model.input,outputs=output)# 創建最終的模型 21 # plot_model(model,'tlmodel.png')
【第一輪訓練】
1 #首先:使用第一種遷移學習方式,base_model參數保持不變,只有增加的最后一層參數更新 2 set_model_to_transfer_learning(model,base_model) 3 #在新的數據集上迭代訓練 4 model.fit_generator(generator=train_generator, 5 steps_per_epoch=800,#800 6 epochs=2,#2 7 validation_data=vali_generator, 8 validation_steps=12,#12 9 class_weight='auto' 10 )
【第二輪訓練】
1 #然后:使用第二種遷移學習方式,全局調優 2 set_model_to_fine_tune(model,base_model) 3 #繼續迭代訓練 4 model.fit_generator(generator=train_generator, 5 steps_per_epoch=800, 6 epochs=2, 7 validation_data=vali_generator, 8 validation_steps=1, 9 class_weight='auto') 10 11 model.save('./flowers17_iv3_ft.h5') #保存模型
【注意】:CPU訓練太慢,建議使用GPU訓練