一.遷移學習的概念
什麼是遷移學習呢?遷移學習能夠由下面的這張圖來表示:網絡
這張圖最左邊表示了遷移學習也就是把已經訓練好的模型和權重直接歸入到新的數據集當中進行訓練,可是咱們只改變以前模型的分類器(全鏈接層和softmax/sigmoid),這樣就能夠節省訓練的時間的到一個新訓練的模型了!架構
可是爲何能夠這麼作呢?app
二.爲何可使用遷移學習?
通常在圖像分類的問題當中,卷積神經網絡最前面的層用於識別圖像最基本的特徵,好比物體的輪廓,顏色,紋理等等,然後面的層纔是提取圖像抽象特徵的關鍵,所以最好的辦法是咱們只須要保留卷積神經網絡當中底層的權重,對頂層和新的分類器進行訓練便可。那麼在圖像分類問題當中,咱們如何使用遷移學習呢?通常使用遷移學習,也就是預訓練神經網絡的步驟以下;dom
1.凍結預訓練網絡的卷積層權重性能
2.置換舊的全鏈接層,換上新的全鏈接層和分類器學習
3.解凍部分頂部的卷積層,保留底部卷積神經網絡的權重fetch
4.同時對卷積層和全鏈接層的頂層進行聯合訓練,獲得新的網絡權重spa
既然咱們知道了遷移學習的基本特色,何不試試看呢?3d
三.遷移學習的代碼實現
咱們使用遷移學習的方法來進行貓狗圖像的分類識別,貓貓的圖像在個人文件夾裏以下圖所示:code
而後導包:
import tensorflow as tf from tensorflow import keras import matplotlib.pyplot as plt import numpy as np import glob import os
獲取圖片的路徑,標籤,製做batch數據,圖片的路徑我存放在了F盤下的train文件夾下,路徑爲:F://UNIVERSITY STUDY/AI/dataset/catdog/train/。
代碼以下:
keras=tf.keras layers=tf.keras.layers #獲得圖片的全部label train_image_label=[int(p.split("\\")[1]=='cat') for p in train_image_path ] #如今咱們的jpg文件進行解碼,變成三維矩陣 def load_preprosess_image(path,label): #讀取路徑 image=tf.io.read_file(path) #解碼 image=tf.image.decode_jpeg(image,channels=3)#彩色圖像爲3個channel #將圖像改變爲一樣的大小,利用裁剪或者扭曲,這裏應用了扭曲 image=tf.image.resize(image,[360,360]) #隨機裁剪圖像 image=tf.image.random_crop(image,[256,256,3]) #隨機上下翻轉圖像 image=tf.image.random_flip_left_right(image) #隨機上下翻轉 image=tf.image.random_flip_up_down(image) #隨機改變圖像的亮度 image=tf.image.random_brightness(image,0.5) #隨機改變對比度 image=tf.image.random_contrast(image,0,1) #改變數據類型 image=tf.cast(image,tf.float32) #將圖像進行歸一化 image=image/255 #如今還須要對label進行處理,咱們如今是列表[1,2,3], #須要變成[[1].[2].[3]] label=tf.reshape(label,[1]) return image,label train_image_ds=tf.data.Dataset.from_tensor_slices((train_image_path,train_image_label)) AUTOTUNE=tf.data.experimental.AUTOTUNE#根據計算機性能進行運算速度的調整 train_image_ds=train_image_ds.map(load_preprosess_image,num_parallel_calls=AUTOTUNE) #如今train_image_ds就讀取進來了,如今進行亂序和batchsize的規定 BATCH_SIZE=32 train_count=len(train_image_path) #如今設置batch和亂序 train_image_ds=train_image_ds.shuffle(train_count).batch(BATCH_SIZE) train_image_ds=train_image_ds.prefetch(AUTOTUNE)#預處理一部分處理,準備讀取 imags,labels=iter(train_image_ds).next()#放到生成器裏,單獨取出數據 plt.imshow(imags[30])
顯示出製做batch數據當中的貓貓圖片:
搭建網絡架構,引入經典圖像分類模型VGG16,同時調用VGG16預訓練網絡的權重。最後調整卷積層的最後三層爲可訓練的,也就是說頂層的卷積神經網路能夠和全鏈接層分類器一塊兒進行聯合訓練:
conv_base=keras.applications.VGG16(weights='imagenet',include_top=False) #weights設置爲imagenet表示使用imagebnet訓練出來的權重,若是填寫False表示不使用權重 #僅適用網絡架構,include_top表示是否使用用於分類的全鏈接層 #咱們在這個卷積層上添加全鏈接層和輸出層便可 model=keras.Sequential() model.add(conv_base) model.add(layers.GlobalAveragePooling2D()) model.add(layers.Dense(512,activation='relu')) model.add(layers.Dense(1,activation='sigmoid')) conv_base.trainable=True#一共有19層 for layer in conv_base.layers[:-3]: layer.trainable=False #從第一層到倒數第三層從新設置爲是不可訓練的,如今卷積的頂層已經解凍,開始聯合訓練 #編譯這個網絡 model.compile(optimizer=keras.optimizers.Adam(lr=0.001), loss='binary_crossentropy', metrics=['acc']) history=model.fit( train_image_ds, steps_per_epoch=train_count//BATCH_SIZE, epochs=1 )
僅僅訓練一個epoch的結果以下所示;
Train for 62 steps 62/62 [==============================] - 469s 8s/step - loss: 0.6323 - acc: 0.6159
一次迭代準確率已經達到了百分之六十。怎麼樣呢?你如今對遷移學習有必定的感受了嗎?