AlexNet是2012年ImageNet競賽冠軍獲得者Hinton和他的學生Alex Krizhevsky設計的。也是在那年之後,更多更深的神經網絡被提出,網絡開始往深水區涉入,比如優秀的vgg,GoogLeNet等。AlexNet是在LeNet的基礎上加深了網絡的結構,學習更豐富更高維的圖像特徵。本文將詳細概述AlexNet的特點及核心思想,最後給出相關的代碼實現。
AlexNet模型的核心思想問題LeNet是卷積神經網絡的祖師爺LeCun在1998年提出,用於解決手寫數字識別的視覺任務。自那時起,CNN的最基本的架構就定下來了:卷積層、池化層、全連接層。如今各大深度學習框架中所使用的LeNet都是簡化改進過的LeNet-5(-5表示具有5個層),和原始的LeNet有些許不同,比如把激活函數改為了現在很常用的ReLu。
LeNet-5模型的套路可以總結為:conv1->pool->conv2->pool2再接全連接層,永恆不變的愛是:卷積層後緊接池化層的模式(卷積必池化)。其經典的模型結構如圖所示:
那麼就存在一個問題,如何讓網絡變的更深,且提取的特徵豐富呢?
解決方案1.錢;2.技術,Hinton的學生Alex做的了,小小年紀承受了比思聰都要早的考驗(錢和技術給了他巨大的人生考驗)。2012年Alex提出的Alexnet網絡模型結構引爆了神經網絡的應用熱潮,並贏得了2012屆圖像識別大賽的冠軍,使得CNN成為在圖像分類上的核心算法模型。該模型相比於LeNet模型,Alex將錢花到了極致,多GPU並行訓練深度Alexnet將深度學習模型得出預測結果的時間提高到人們可以接受的時間範圍之內。因此Alexnet模型的特點如下:
更深的網絡結構
打破卷積必池化的思維定式,使用層疊的卷積層,即卷積層+卷積層+池化層來提取圖像的特徵
多GPU訓練
使用Dropout、Data Augmentation抑制過擬合
使用Relu替換之前的sigmoid的作為激活函數
引入LRN
模型結構:
網絡特點我們知道神經網絡需要使用激活函數,一般激活函數具有兩個作用。其一、無論卷積還是全連接層,實質上都是線性運算,通過加入非線性的激活函數可以增強網絡的非線性映射能力,相當於kernel method。其二、神經網絡一般通過BP算法優化,激活函數可以加快網絡收斂速度。傳統神經網絡激活函數通常為反正切或是sigmoid,AlexNet使用RELU作為激活函數,相比於反正切,該方法訓練速度大約有6倍提升。RELU激活函數簡單到難以置信。
雖然後來的很多網絡都不屑於使用LRN,甚至直接說LRN對於網絡沒有任何提升,但是思路真的很新奇呀。
LRN加在RELU的激活後面,能夠增加網絡的泛化能力,並在ILSVRC-2012上降低1%的錯誤率。傳說思路來源於神經元的側向抑制機制,不同的神經元都在做特徵提取這件事,能否讓他們相互競爭呢?
也算是創新點之一吧,畢竟此前的文章的池化沒有重疊的,不過後續的其他文章也鮮有重疊。重疊池化的意思是,池化步伐小於kernel size,這樣池化後的feature map的感受野其實是有部分重疊的。
文章使用Random Crop、flip從而上千倍的擴充訓練樣本的數量,也使得隨機裁剪成為通用方法。具體做法就是首先將圖片resize到256*256大小,然後從中隨機crop出224*224大小的patch訓練,測試時就從四個角及中心crop,然後水平翻轉圖像形成10個測試圖片,然後對於這10個結果取一下平均值就好啦。另一種增強為轉換RGB通道的強度,在之後的模型中很少用到,對於該模型,大約降低了1%錯誤率。
DropOut通過訓練時隨機使得一部分結點失效,不貢獻連接權重而減少過擬合風險。同時強迫這些神經元去學習互補的一些特徵。
AlexNet模型的代碼實現實現環境:python3.6.5、tensorflow 1.1.8、keras 2.2.0等。
核心代碼本文將給出keras神經網絡編程框架實現的一個簡單Alexnet模型。(相比論文原始模型,這是一個非常小的網絡,只有5個卷積層並且池化層大小不同。)
#alexnetmodel3 = Sequential()model3.add(Conv2D(input_shape=(n,n,3),filters=96,kernel_size=(11,11),strides=(4,4),padding="valid", activation="relu"))model3.add(MaxPooling2D(pool_size=(3,3),strides=(2,2)))model3.add(Conv2D(256, kernel_size=(5,5), padding="same",strides=(1,1), activation="relu"))model3.add(MaxPooling2D(pool_size=(3,3),strides=(2,2)))model3.add(Conv2D(384, kernel_size=(3,3), padding="same", strides=(1,1), activation="relu"))model3.add(Conv2D(384, kernel_size=(3,3), padding="same", strides=(1,1), activation="relu"))model3.add(Conv2D(256, kernel_size=(3,3), padding="same", strides=(1,1), activation="relu"))model3.add(MaxPooling2D(pool_size=(3,3),strides=(2,2)))model3.add(Flatten())model3.add(Dense(4096,activation="relu"))model3.add(Dense(4096,activation="relu"))model3.add(Dense(units=len(classes), activation="softmax"))model3.summary()plot_model(model3, show_shapes=True, to_file='ALEX_NET.png')模型參數:
Layer (type) Output Shape Param # =================================================================conv2d_42 (Conv2D) (None, 30, 30, 96) 34944 _________________________________________________________________max_pooling2d_15 (MaxPooling (None, 14, 14, 96) 0 _________________________________________________________________conv2d_43 (Conv2D) (None, 14, 14, 256) 614656 _________________________________________________________________max_pooling2d_16 (MaxPooling (None, 6, 6, 256) 0 _________________________________________________________________conv2d_44 (Conv2D) (None, 6, 6, 384) 885120 _________________________________________________________________conv2d_45 (Conv2D) (None, 6, 6, 384) 1327488 _________________________________________________________________conv2d_46 (Conv2D) (None, 6, 6, 256) 884992 _________________________________________________________________max_pooling2d_17 (MaxPooling (None, 2, 2, 256) 0 _________________________________________________________________flatten_3 (Flatten) (None, 1024) 0 _________________________________________________________________dense_8 (Dense) (None, 4096) 4198400 _________________________________________________________________dense_9 (Dense) (None, 4096) 16781312 _________________________________________________________________dense_10 (Dense) (None, 8) 32776 =================================================================Total params: 24,759,688Trainable params: 24,759,688Non-trainable params: 0_________________________________________________________________模型結構:
總結對於沒有GPU的我們普通人,其越深的Alexnet模型結構,其訓練速度越慢,且準確率並不是太高。如果模型過分的深的化,例如VGG模型(基於ALexnet加深了網絡深度,證明了更深的網絡,能更好的提取特徵),則會出現梯度消失等問題。那麼如何解決該問題呢,例如使用BatchNorm,將激活函數換為ReLu,使用Xaiver初始化等。以及最後的殘差神經網絡模型。
參考文獻1.Krizhevsky A, Sutskever I, Hinton G E. ImageNet classification with deep convolutional neural networks[C]// International Conference on Neural Information Processing Systems. Curran Associates Inc. 2012:1097-1105.
2. https://haosen.blog.csdn.net/article/details/111396283
3.https://haosen.blog.csdn.net/article/details/110726937
4. https://haosen.blog.csdn.net/article/details/105822437
5. Tm P , Pranathi A , Saiashritha K , et al. Tomato Leaf Disease Detection Using Convolutional Neural Networks[C]// 2018 Eleventh International Conference on Contemporary Computing (IC3). IEEE Computer Society, 2018