深度学习之迁移学习实现神奇宝贝识别
經過之前深度學習的實踐,無論是自己搭建的CNN網絡也好,還是通過遷移學習調用官方的網絡模型也好,都有其優點以及不足。本次實驗通過對各種常用的CNN網絡模型進行調用,了解一下它們的特點,對比一下在對于同一數據集進行分類時的準確率。
本次所調用的CNN模型有:VGG16 VGG19 ResNet Densenet模型
1.導入庫
import tensorflow as tf import numpy as np import matplotlib.pyplot as plt import os,PIL,pathlib from tensorflow import keras from tensorflow.keras import layers,models,Sequential,Input2.加載數據
操作與之前的相似,將數據按照8:2的比例劃分為訓練集和測試集
data_dir = "E:/tmp/.keras/datasets/Pokemon_photos" data_dir = pathlib.Path(data_dir)img_count = len(list(data_dir.glob('*/*.png')))#總共219張照片 # print(img_count)height = 224 width = 224 epochs = 20 batch_size = 8 train_data_gen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255,rotation_range=45,shear_range=0.2,zoom_range=0.2,validation_split=0.2,horizontal_flip=True ) train_ds = train_data_gen.flow_from_directory(directory=data_dir,target_size=(height,width),batch_size=batch_size,shuffle=True,class_mode='categorical',subset='training' ) test_ds = train_data_gen.flow_from_directory(directory=data_dir,target_size=(height,width),batch_size=batch_size,shuffle=True,class_mode='categorical',subset='validation' )3.自己搭建CNN網絡
三層卷積池化層+Flatten+三層全連接層
#CNN model = tf.keras.Sequential([tf.keras.layers.Conv2D(16,3,padding="same",activation="relu",input_shape=(height,width,3)),tf.keras.layers.MaxPooling2D(),tf.keras.layers.Conv2D(32,3,padding="same",activation="relu"),tf.keras.layers.MaxPooling2D(),tf.keras.layers.Conv2D(64,3,padding="same",activation="relu"),tf.keras.layers.AveragePooling2D(),tf.keras.layers.Flatten(),tf.keras.layers.Dense(1024,activation="relu"),tf.keras.layers.Dense(512,activation="relu"),tf.keras.layers.Dense(10,activation="softmax") ])
最終的模型準確率在80%左右,通過實驗結果可以發現,增加epochs的個數,最終的模型準確率并沒有得到提高,而是在震蕩,而模型準確率最高的時候在epochs為20的時候。
4.官方模型
VGG16模型
VGG16和VGG19是VGG系列模型中最經典的兩個模型,后者具有更深的層次。VGG系列的模型有以下特點:
①小卷積核:相比AlexNet,將卷積核全部替換為3x3,極少用了1x1。而3x3是最小的能夠捕獲像素八鄰域信息的尺寸。
②小池化層:相比AlexNet,3x3的池化核全部換為2x2的池化核。
③層數更深:VGG16為例,3 → 64 → 126 → 256 → 512,卷積核專注于擴大通道數,3個通道的特征經過經過卷積層的提取擴散到了512個通道。
④層數更深:VGG16為例,3 → 64 → 126 → 256 → 512 ,卷積核專注于擴大通道數,3個通道的特征經過經過卷積層的提取擴散到了512個通道。
⑤全連接轉1 × 1卷積:測試階段可以接收任意寬或高為的輸入。
這是相比于VGG模型之前的模型所做出的改變,那么為何要做這樣的改變呢?
3x3卷積核
兩個3x3的堆疊卷基層的有限感受野是5x5;三個3x3的堆疊卷基層的感受野是7x7,故可以通過小尺寸卷積層的堆疊替代大尺寸卷積層,并且感受野大小不變。多個小卷積可以提取出更大更深的卷積特征,并且減少模型參數數量。
2x2池化核
AlexNet的最大池化核為 3 × 3,步幅為2。VGGNet最大池化核為 2 × 2,步幅為2 22。小池化核帶來的是更細節的信息捕獲。
1x1卷積核
測試階段可以接收任意寬或高為的輸入,消除輸入的限制。
調用官方VGG16模型,其中常用的幾個參數解釋如下:
VGG模型中包含的所有參數,在別的官方模型中,參數與之類似。 tf.keras.applications.vgg16.VGG16(include_top=True, weights='imagenet', input_tensor=None,input_shape=None, pooling=None, classes=1000,classifier_activation='softmax' )include_top:是否包括網絡頂部的 3 個全連接層。 weights:默認不加載權重文件,"imagenet"加載官方權重文件,或者輸入自己的權重文件路徑。 classes:分類圖像的類別數。 conv_base = tf.keras.applications.VGG16(weights = 'imagenet',include_top = False) conv_base.trainable =False#不可訓練 #模型搭建 model = tf.keras.Sequential() model.add(conv_base) model.add(tf.keras.layers.GlobalAveragePooling2D()) model.add(tf.keras.layers.Dense(1024,activation='relu')) model.add(tf.keras.layers.Dense(10,activation='softmax'))優化器的配置與前幾篇博客的設置相同,在此不再贅述。
相比較自己搭建的CNN網絡,VGG16模型準確率沒有那么頻繁的振動,最終模型準確率在80%。不過這是epochs=20的條件下,在epochs同樣的條件下,訓練效果應該更好。
調用官方VGG19模型
conv_base = tf.keras.applications.VGG19(weights = 'imagenet',include_top = False) conv_base.trainable =False#不可訓練 #模型搭建 model = tf.keras.Sequential() model.add(conv_base) model.add(tf.keras.layers.GlobalAveragePooling2D()) model.add(tf.keras.layers.Dense(1024,activation='relu')) model.add(tf.keras.layers.Dense(10,activation='softmax'))
相比較起VGG16模型,VGG19模型充分體現了加深網絡深度對于模型準確率的好處。模型準確率在80%以上,最高達到了90%。
當把epochs設置為40時,結果如下所示:
準確率最高為94.87%,效果不錯。
ResNet50模型
在深層網絡能夠收斂的前提下,隨著網絡深度的增加,正確率開始飽和甚至下降,稱之為網絡的退化(degradation)問題。在一定程度上,加深網絡模型可以增加模型的準確率,但是網絡深度過深,準確率就會下降,這些退化并不是過擬合造成的。在極端條件下,如果增加的所有層都是前一層的直接復制(即 y=x),這種情況下深層網絡的訓練誤差應該和淺層網絡相等。因此,網絡退化的根本原因還是優化問題。 為了解決優化的難題,提出了殘差網絡。殘差網絡可以理解為在前向網絡中增加了一些快捷連接(shortcut connections)。這些連接會跳過某些層,將原始數據直接傳到之后的層。新增的快捷連接不會增加模型的參數和復雜度。整個模型還是可以使用端到端的方法來訓練(比如SGD),在實現上并不難。
conv_base = tf.keras.applications.ResNet50(weights = 'imagenet',include_top = False) conv_base.trainable =False #模型搭建 model = tf.keras.Sequential() model.add(conv_base) model.add(tf.keras.layers.GlobalAveragePooling2D()) model.add(tf.keras.layers.Dense(1024,activation='relu')) model.add(tf.keras.layers.Dense(10,activation='softmax'))
這結果就很迷,訓練集的準確率已經高達100%,但是測試集的準確率幾乎為0。應該不是網絡本身的問題,有些參數的設置博主并不是很理解,希望路過的大佬可以指點一二。在之前的一篇博客鳥類識別中,這樣的情況也出現了,當時以為是過擬合,但現在看來并不是過擬合。
Densenet模型
這個模型是最近幾年提出的網絡模型,平常用的并不多,但是它的優點突出。
1、減輕了vanishing-gradient(梯度消失)
2、加強了feature的傳遞。
3、更有效地利用了feature。
4、一定程度上較少了參數數量。
Densenet模型在保證網絡中層與層之間最大程度的信息傳輸的前提下,直接將所有層連接起來!在傳統的卷積神經網絡中,如果你有L層,那么就會有L個連接,但是在DenseNet中,會有L(L+1)/2個連接。簡單講,就是每一層的輸入來自前面所有層的輸出。如下圖所示:
該網絡在訓練集的準確率上已經達到了98%,但是在測試集的準確率在70%-80%之間,并沒有VGG模型的準確率高。
總結:
本文只是對同一數據集利用不同的網絡模型進行準確率的比較,并沒有說某一網絡模型一定好。任何一種網絡模型都有其突出的優點以及各自的不足。在對于神奇寶貝的識別中,VGG19網絡的準確率是最高的,并且沒有出現振動或者過擬合的現象。
總結
以上是生活随笔為你收集整理的深度学习之迁移学习实现神奇宝贝识别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python---win32gui、wi
- 下一篇: windows ie浏览器如何清除浏览器