Pytorch CIFAR-10分類(VGGNet16)

VGGNet

在這裏插入圖片描述

在這裏插入圖片描述

VGG-16 一些性質:

VGG 是一個很經典的卷積神經網絡結構,是由 AlexNet 改進的,相比於 AlexNet,主要的改變有兩個地方:

使用 3 x 3 卷積核代替 AlexNet 中的大卷積核

使用 2 x 2 池化核代替 AlexNet 的 3 x 3 池化核

VGGNet 有很多類型,論文中提出了 4 種不同層次的網絡結構(從 11 層到 19 層)

VGG 有很多優點,最本質的特點就是用小的卷積核(3x3)代替大的卷積核,2個 3x3 卷積堆疊等於1個 5x5 卷積,3 個 3x3 堆疊等於1個 7x7 卷積,感受野大小不變。

可以想象一下,在步長 s 爲 1,填充 padding 爲 0 時,2 個 3x3 卷積後的圖像 size 爲 (((N-3)/1+1)-3)/1+1 = ((N-3+1)-3+1) = N-4 = (N-5)/1+1。且做卷積後,得到的特徵,都是從原圖像上相同的像素點提取的(原圖像每 5x5 的空域像素點對應一個新的特徵),因此感受野大小不變。故 2 個 3x3 的卷積核與 5x5 的卷積核等價。

關於LeNet和VGG的一些總結

1). 網絡結構

LeNet和VGG這些傳統的卷積神經網絡的結構一般都是卷積層+全連接層,而卷積層則一般包括卷積(nn.conv2d)、激活(nn.ReLU(True))和池化(一般爲最大池化nn.MaxPool2d(ksize,stride)),在卷積之後也可以加入批歸一化(nn.BatchNorm2d(out_channel))。全連接一般有兩-三層,第一層的輸入爲卷積層最終的輸出,大小爲卷積層最終輸出的數據拉伸爲一維向量的大小。

2). 代碼結構

代碼結構基本相同,基本分爲以下幾部分:

導入各種包

定義超參數

下載數據集

定義網絡模型

定義損失函數和優化方式

訓練模型
    1). 初始化loss和accuracy
    2). 前向傳播
    3). 反向傳播
    4). 測試模型
    5). 打印每個epoch的loss和acc
    
保存模型

不同的地方就是網絡模型的定義部分,以及定義損失函數和優化方式的定義也有可能不同。對於不同的網絡,其結構必然不同,需要重新定義,但其實也是大同小異。

3). 遇到的問題和解決

從LeNet到VGG,一直以來進入了一個誤區,一直以爲數據圖像的大小要匹配/適應網絡的輸入大小。在LeNet中,網絡輸入大小爲32x32,而MNIST數據集中的圖像大小爲28x28,當時認爲要使兩者的大小匹配,將padding設置爲2即解決了這個問題。然而,當用VGG訓練CIFAR10數據集時,網絡輸入大小爲224x224,而數據大小是32x32,這兩者該怎麼匹配呢?試過將32用padding的方法填充到224x224,但是運行之後顯示內存不足(笑哭.jpg)。也百度到將數據圖像resize成224x224。這個問題一直困擾了好久,看着代碼裏沒有改動數據尺寸和網絡的尺寸,不知道是怎麼解決的這個匹配/適應的問題。最後一步步調試才發現在第一個全連接處報錯,全連接的輸入尺寸和設定的尺寸不一致,再回過頭去一步步推數據的尺寸變化,發現原來的VGG網絡輸入是224x224的,由於卷積層不改變圖像的大小,只有池化層才使圖像大小縮小一半,所以經過5層卷積池化之後,圖像大小縮小爲原來的1/32。卷積層的最終輸出是7x7x512=25088,所以全連接層的輸入設爲25088。當輸入圖像大小爲32x32時,經過5層卷積之後,圖像大小縮小爲1x1x512,全連接的輸入大小就變爲了512,所以不匹配的地方在這裏,而不是網絡的輸入處。所以輸入的訓練圖像的大小不必要與網絡原始的輸入大小一致,只需要計算經過卷積池化後最終的輸出(也即全連接層的輸入),然後改以下全連接的輸入即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章