深度学习-Tensorflow2.2-预训练网络{7}-迁移学习基础针对小数据集-19
使用預(yù)訓(xùn)練網(wǎng)絡(luò)(遷移學(xué)習(xí))
預(yù)訓(xùn)練網(wǎng)絡(luò)是一個(gè)保存好的之前已在大型數(shù)據(jù)集(大規(guī)模圖像分類任務(wù))上訓(xùn)練好的卷積神經(jīng)網(wǎng)絡(luò)
如果這個(gè)原始數(shù)據(jù)集足夠大且足夠通用,那么預(yù)訓(xùn)練網(wǎng)絡(luò)學(xué)到的特征的空間層次結(jié)構(gòu)可以作為有效的提取視覺世界特征的模型。
即使新問題和新任務(wù)與原始任務(wù)完全不同學(xué)習(xí)到的特征在不同問題之間是可移植的,這也是深度學(xué)習(xí)與淺層學(xué)習(xí)方法的一個(gè)重要優(yōu)勢。它使得深度學(xué)習(xí)對于小數(shù)據(jù)問題非常的有效。
Keras內(nèi)置預(yù)訓(xùn)練網(wǎng)絡(luò)Keras庫中包含VGG16、VGG19\ResNet50、Inception v3、Xception等經(jīng)典的模型架構(gòu)。
-
ImageNet
-
ImageNet是一個(gè)手動(dòng)標(biāo)注好類別的圖片數(shù)據(jù)庫(為了機(jī)器視
覺研究),目前已有22,000個(gè)類別。 -
當(dāng)我們在深度學(xué)習(xí)和卷積神經(jīng)網(wǎng)絡(luò)的背景下聽到“ImageNet”一詞時(shí),我們可能會(huì)提到ImageNet視覺識別比賽,稱為ILSVRC。
-
這個(gè)圖片分類比賽是訓(xùn)練一個(gè)模型,能夠?qū)⑤斎雸D片正確分
類到1000個(gè)類別中的某個(gè)類別。訓(xùn)練集120萬,驗(yàn)證集5萬,測試集10萬。 -
這1,000個(gè)圖片類別是我們在日常生活中遇到的,例如狗,貓,各種家居物品,車輛類型等等。
-
在圖像分類方面,ImageNet比賽準(zhǔn)確率已經(jīng)作為計(jì)算機(jī)視覺分類算法的基準(zhǔn)。自2012年以來,卷積神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí)技術(shù)主導(dǎo)了這一比賽的排行榜。
-
-
VGG16與VGG19
-
在2014年,VGG模型架構(gòu)由Simonyan和Zisserman提出,在“極深的大規(guī)模圖像識別卷積網(wǎng)絡(luò)”(Very Deep Convolutional Networks for Large Scale Image Recognition)這篇論文中有介紹
-
VGG模型結(jié)構(gòu)簡單有效,前幾層僅使用3×3卷積核來增加網(wǎng)絡(luò)深度,通過max pooling(最大池化)依次減少每層的神經(jīng)元數(shù)量,最后三層分別是2個(gè)有4096個(gè)神經(jīng)元的全連接層和一個(gè)輸出softmax層。
-
-
VGG有兩個(gè)很大的缺點(diǎn)
- 網(wǎng)絡(luò)架構(gòu)weight數(shù)量相當(dāng)大,很消耗磁盤空間。
- 訓(xùn)練非常慢
由于其全連接節(jié)點(diǎn)的數(shù)量較多,再加上網(wǎng)絡(luò)比較深,VGG16有533MB+,VGG19有574MB。這使得部署VGG比較耗時(shí)。
微調(diào)
-
所謂微調(diào):凍結(jié)模型庫的底部的卷積層,共同訓(xùn)練新添加的分類器層和頂部部分卷積層。這允許我們“微調(diào)”基礎(chǔ)模型中的高階特征表示,以使它們與特定任務(wù)更相關(guān)。。
-
只有分類器已經(jīng)訓(xùn)練好了,才能微調(diào)卷積基的頂部卷積層。如果有沒有這樣的話,剛開始的訓(xùn)練誤差很大,微調(diào)之前這些卷積層學(xué)到的表示會(huì)被破壞掉
微調(diào)步驟
- 一、在預(yù)訓(xùn)練卷積基上添加自定義層
- 二、凍結(jié)卷積基所有層
- 三、訓(xùn)練添加的分類層
- 四、解凍卷積基的一部分層
- 五、聯(lián)合訓(xùn)練解凍的卷積層和添加的自定義層
案例
import tensorflow as tf from tensorflow import keras import matplotlib.pyplot as plt %matplotlib inline import numpy as np import glob import os gpu_ok = tf.test.is_gpu_available() print("tf version:", tf.__version__) print("use GPU", gpu_ok) # 判斷是否使用gpu進(jìn)行訓(xùn)練 # 定義好keras,layers方便后面調(diào)用 keras = tf.keras layers = tf.keras.layers train_image_path = glob.glob("./dc/maogou/*.jpg") test_image_path = glob.glob("./dc/maogou_test/*.jpg") # 獲取圖片數(shù)據(jù)集 len(train_image_path),len(test_image_path) train_image_path[995:1005],test_image_path[593:600] # 定義目標(biāo)值 如果是貓 = 1 是狗 = 0 train_image_label = [int(p.split("\\")[1].split(".")[0]=="cat") for p in train_image_path] test_image_label = [int(p.split("\\")[1].split(".")[0]=="cat") for p in test_image_path] train_image_label[995:1005],test_image_label[593:600] # 圖片加載與預(yù)處理 def load_preprosess_image(path,lable):image = tf.io.read_file(path) # 讀取圖片路徑image = tf.image.decode_jpeg(image,channels=3) # 對圖片進(jìn)行解碼(jpeg格式圖片,channels=3 將讀入圖片統(tǒng)一為三通道)image = tf.image.resize(image,[256,256])# 對圖片進(jìn)行變形360*360像素(非裁剪)image = tf.cast(image,tf.float32) # 改變圖片格式image = image/255 # 對圖片進(jìn)行歸一化#lable = tf.reshape(lable,[1]) # 把目標(biāo)值轉(zhuǎn)換成2維形狀 如:[1,2,3] =>[[1],[2],[3]]return image,lable # 創(chuàng)建數(shù)據(jù)集 (包含了 路徑 以及目標(biāo)值) train_image_ds = tf.data.Dataset.from_tensor_slices((train_image_path,train_image_label)) test_image_ds = tf.data.Dataset.from_tensor_slices((test_image_path,test_image_label)) AUTOTUNE = tf.data.experimental.AUTOTUNE # AUTOTUNE 根據(jù)計(jì)算機(jī)cpu個(gè)數(shù)自動(dòng)進(jìn)行計(jì)算 train_image_ds = train_image_ds.map(load_preprosess_image,num_parallel_calls=AUTOTUNE) # 對所有圖片以及目標(biāo)值進(jìn)行計(jì)算 使用AUTOTUNE 根據(jù)計(jì)算機(jī)cpu個(gè)數(shù)自動(dòng)進(jìn)行計(jì)算 test_image_ds = test_image_ds.map(load_preprosess_image,num_parallel_calls=AUTOTUNE) train_image_ds ,test_image_ds# 查看處理后圖片的格式 for img,label in train_image_ds.take(2):plt.imshow(img) for img,label in test_image_ds.take(600):plt.imshow(img) BATCH_SIZE = 64 # 中文為批,一個(gè)batch由若干條數(shù)據(jù)構(gòu)成。batch是進(jìn)行網(wǎng)絡(luò)優(yōu)化的基本單位,網(wǎng)絡(luò)參數(shù)的每一輪優(yōu)化需要使用一個(gè)batch。 # batch中的樣本是被并行處理的。與單個(gè)樣本相比,一個(gè)batch的數(shù)據(jù)能更好的模擬數(shù)據(jù)集的分布, #batch越大則對輸入數(shù)據(jù)分布模擬的越好,反應(yīng)在網(wǎng)絡(luò)訓(xùn)練上,則體現(xiàn)為能讓網(wǎng)絡(luò)訓(xùn)練的方向“更加正確”。 #但另一方面,一個(gè)batch也只能讓網(wǎng)絡(luò)的參數(shù)更新一次,因此網(wǎng)絡(luò)參數(shù)的迭代會(huì)較慢。 #在測試網(wǎng)絡(luò)的時(shí)候,應(yīng)該在條件的允許的范圍內(nèi)盡量使用更大的batch,這樣計(jì)算效率會(huì)更高。 train_count = len(train_image_path) # 查看數(shù)據(jù)的個(gè)數(shù) test_count = len(test_image_path) train_count,test_count train_image_ds = train_image_ds.shuffle(train_count).repeat().batch(BATCH_SIZE) # 亂序 #train_image_ds = train_image_ds.prefetch(AUTOTUNE) # prefetch 該函數(shù)有一個(gè)后臺線程和一個(gè)內(nèi)部緩存區(qū),在數(shù)據(jù)被請求前, # 就從 dataset 中預(yù)加載一些數(shù)據(jù)(進(jìn)一步提高性能) prefetch(AUTOTUNE) 根據(jù)計(jì)算機(jī)性能自動(dòng)分配數(shù)據(jù)條數(shù)test_image_ds = test_image_ds.repeat().batch(BATCH_SIZE) #test_image_ds = test_image_ds.prefetch(AUTOTUNE)使用keras內(nèi)置經(jīng)典網(wǎng)絡(luò)實(shí)現(xiàn)
# weights="imagenet"使用預(yù)訓(xùn)練權(quán)重,include_top= False不包含全鏈接層 covn_base = keras.applications.VGG16(weights="imagenet",include_top= False) covn_base.summary() # 添加全連接層 model = keras.Sequential() # 建立一個(gè)順序模型 model.add(covn_base) # 添加vgg16卷積機(jī) model.add(layers.GlobalAveragePooling2D()) # 全局平均池化,深度神經(jīng)網(wǎng)絡(luò)中經(jīng)常使用的一個(gè)層,使用前后的 #尺寸分別為[B,H,W,C]->[B,C].特別要注意,這個(gè)層使用之后特征圖尺寸的維度變成了2維而非4維。 model.add(layers.Dense(512,activation="relu")) # 輸出512個(gè)單元 model.add(layers.Dense(1,activation="sigmoid")) # 輸出1個(gè)單元,sigmoid概率值 model.summary() # Trainable params: 14,977,857 covn_base.trainable = False # 因covn_base已經(jīng)訓(xùn)練好了所以我們設(shè)置false不可訓(xùn)練(凍結(jié)) model.summary() # 設(shè)置了covn_base.trainable = False后再次查看模型建構(gòu)Trainable params: 263,169 # 編譯模型 model.compile(optimizer=keras.optimizers.Adam(lr=0.001),loss="binary_crossentropy",metrics=["acc"]) # 訓(xùn)練模型 history = model.fit(train_image_ds,steps_per_epoch=train_count//BATCH_SIZE,epochs=12,validation_data=test_image_ds,validation_steps=test_count//BATCH_SIZE)
微調(diào)
常見預(yù)訓(xùn)練網(wǎng)絡(luò)
-
可用的模型
在 ImageNet 上預(yù)訓(xùn)練過的用于圖像分類的模型:
VGG16 VGG19 ResNet50
InceptionV3 InceptionResNetV2 Xception
MobileNet MobileNetV2
DenseNet NASNet -
模型概覽
-
Xception
在 ImageNet 上預(yù)訓(xùn)練的 Xception V1 模型,在 ImageNet 上,該模型取得了驗(yàn)證集 top1 0.790 和 top5 0.945 的準(zhǔn)確率。
注意該模型只支持 channels_last 的維度順序(高度、寬度、通道)。
模型默認(rèn)輸入尺寸是 299x299。
- Xception重要參數(shù)
pooling: 可選,
當(dāng) include_top 為 False 時(shí),該參數(shù)指定了特征提取時(shí)的池化方式。
None 代表不池化,直接輸出最后一層卷積層的輸出,該輸出是一個(gè) 4D 張量。
‘a(chǎn)vg’ 代表全局平均池化(GlobalAveragePooling2D),相當(dāng)于在最后一層卷積層后面再加一層全局平均池化層,輸出是一個(gè) 2D 張量。
‘max’ 代表全局最大池化。
其他訓(xùn)練網(wǎng)絡(luò)參數(shù)參數(shù)添加鏈接描述
案例
import tensorflow as tf from tensorflow import keras import matplotlib.pyplot as plt %matplotlib inline import numpy as np import glob import os os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true' gpu_ok = tf.test.is_gpu_available() print("tf version:", tf.__version__) print("use GPU", gpu_ok) # 判斷是否使用gpu進(jìn)行訓(xùn)練 keras = tf.keras layers = tf.keras.layers train_image_path = glob.glob("./dc/maogou/*.jpg") test_image_path = glob.glob("./dc/maogou_test/*.jpg") # 獲取圖片數(shù)據(jù)集 len(train_image_path),len(test_image_path) train_image_path[995:1005],test_image_path[593:600] # 定義目標(biāo)值 如果是貓 = 1 是狗 = 0 train_image_label = [int(p.split("\\")[1].split(".")[0]=="cat") for p in train_image_path] test_image_label = [int(p.split("\\")[1].split(".")[0]=="cat") for p in test_image_path] train_image_label[995:1005],test_image_label[593:600] # 圖片加載與預(yù)處理 def load_preprosess_image(path,lable):image = tf.io.read_file(path) # 讀取圖片路徑image = tf.image.decode_jpeg(image,channels=3) # 對圖片進(jìn)行解碼(jpeg格式圖片,channels=3 將讀入圖片統(tǒng)一為三通道)image = tf.image.resize(image,[256,256])# 對圖片進(jìn)行變形360*360像素(非裁剪)image = tf.cast(image,tf.float32) # 改變圖片格式image = image/255 # 對圖片進(jìn)行歸一化#lable = tf.reshape(lable,[1]) # 把目標(biāo)值轉(zhuǎn)換成2維形狀 如:[1,2,3] =>[[1],[2],[3]]return image,lable # 創(chuàng)建數(shù)據(jù)集 (包含了 路徑 以及目標(biāo)值) train_image_ds = tf.data.Dataset.from_tensor_slices((train_image_path,train_image_label)) test_image_ds = tf.data.Dataset.from_tensor_slices((test_image_path,test_image_label)) AUTOTUNE = tf.data.experimental.AUTOTUNE # AUTOTUNE 根據(jù)計(jì)算機(jī)cpu個(gè)數(shù)自動(dòng)進(jìn)行計(jì)算 train_image_ds = train_image_ds.map(load_preprosess_image,num_parallel_calls=AUTOTUNE) # 對所有圖片以及目標(biāo)值進(jìn)行計(jì)算 使用AUTOTUNE 根據(jù)計(jì)算機(jī)cpu個(gè)數(shù)自動(dòng)進(jìn)行計(jì)算 test_image_ds = test_image_ds.map(load_preprosess_image,num_parallel_calls=AUTOTUNE) train_image_ds ,test_image_ds# 查看處理后圖片的格式
微調(diào)
總結(jié)
以上是生活随笔為你收集整理的深度学习-Tensorflow2.2-预训练网络{7}-迁移学习基础针对小数据集-19的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度学习-Tensorflow2.2-T
- 下一篇: 深度学习-Tensorflow2.2-模