AlexNet模型思想詳解及核心代碼實現

2021-02-20 深度學習社區DLC
摘要

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

相關焦點

  • 【深度學習系列】用PaddlePaddle和Tensorflow實現經典CNN網絡AlexNet
    【深度學習系列】卷積神經網絡詳解(二)——自己手寫一個卷積神經網絡  【深度學習系列】用PaddlePaddle和Tensorflow進行圖像分類上周我們用PaddlePaddle和Tensorflow實現了圖像分類,分別用自己手寫的一個簡單的CNN網絡simple_cnn和LeNet-5的CNN網絡識別cifar-10數據集。
  • 基於模型的嵌入式C代碼的實現與驗證
    此外,手工編制的代碼良莠不齊,降低了軟體運行的可靠度,增加了代碼錯誤的可能性和系統出錯的風險。為了迎接這些挑戰,工程師必須找到以更快速有效開發軟體和硬體的方法。鑑於軟體工程化思想的引入和盛行,軟體業發展潮流逐漸趨於工程化、流水化。Matlab環境下集成的Sireulink/Stateflow模型設計和使用RTW生成目標代碼的軟體設計方案便是這一大背景的產物。
  • Stacking 模型融合詳解(附python代碼)
    Stacking 的基本思想  將個體學習器結合在一起的時候使用的方法叫做結合策略。對於分類問題,我們可以使用投票法來選擇輸出最多的類。對於回歸問題,我們可以將分類器輸出的結果求平均值。  但是這樣的實現是有很大的缺陷的。在原始數據集D上面訓練的模型,然後用這些模型再D上面再進行預測得到的次級訓練集肯定是非常好的。會出現過擬合的現象。Stacking是模型融合的一個重要的方法,幾乎每個數據科學競賽的前幾名都會使用,接下來我主要是介紹stacking的原理。相信大家看很多stacking的資料都會看到下面的這個圖:
  • 乾貨 TensorFlow之深入理解AlexNet
    相對於一般如線性模型使用正則的方法來防止模型過擬合,而在神經網絡中Dropout通過修改神經網絡本身結構來實現。對於某一層神經元,通過定義的概率來隨機刪除一些神經元,同時保持輸入層與輸出層神經元的個人不變,然後按照神經網絡的學習方法進行參數更新,下一次迭代中,重新隨機刪除一些神經元,直至訓練結束
  • AlexNet--CNN經典網絡模型詳解(pytorch實現)
    建議大家可以實踐下,代碼都很詳細,有不清楚的地方評論區見~二、AlexNet在imagenet上的圖像分類challenge上大神Alex提出的alexnet網絡結構模型贏得了2012屆的冠軍,振奮人心,利用CNN實現了圖片分類,別人用傳統的機器學習算法調參跳到半死也就那樣,Alex
  • 一行代碼即可調用18款主流模型!PyTorch Hub輕鬆解決論文可復現性
    ,加載ResNet、BERT、GPT、VGG、PGAN還是MobileNet等經典模型只需一行代碼。圖靈獎得主Yann LeCun發推表示,只需要一行代碼就可以調用所有倉庫裡的模型,通過一個pull請求來發布你自己的模型。同時,PyTorch Hub整合了Google Colab,併集成了論文代碼結合網站Papers With Code,可以直接找到論文的代碼。PyTorch Hub怎麼用?
  • 【NER】NLP-入門實體命名識別(NER)+Bilstm-CRF模型原理Pytorch代碼詳解——最全攻略
    希望能夠以這篇文章為載體,幫助其他跟我一樣的學習者梳理、串起NER的各個小知識點,最後上手NER的主流模型(Bilstm+CRF)(文中講的是pytorch,但是懂了pytorch去看keras十分容易相信我哈)全文結構:一、NER資料(主要介紹NER)二、主流模型Bilstm-CRF實現詳解(Pytorch篇)三、實現代碼的拓展(在第二點的基礎上進行拓展
  • NLP-入門實體命名識別(NER)+Bilstm-CRF模型原理Pytorch代碼詳解——最全攻略
    希望能夠以這篇文章為載體,幫助其他跟我一樣的學習者梳理、串起NER的各個小知識點,最後上手NER的主流模型(Bilstm+CRF)(文中講的是pytorch,但是懂了pytorch去看keras十分容易相信我哈)二、主流模型Bilstm-CRF實現詳解(Pytorch篇)一、NER資料參考:NLP之CRF應用篇(序列標註任務)(CRF++的詳細解析、Bi-LSTM+CRF
  • 深度學習筆記16:CNN經典論文研讀之AlexNet及其Tensorflow實現
    AlexNet 繼承了 LeCun 的 Le-Net5 思想,將卷積神經網絡的發展到很寬很深的網絡當中,相較於 Le-Net5 的六萬個參數,AlexNet 包含了 6 億三千萬條連接,6000 萬個參數和 65 萬個神經元,其網絡結構包括 5 層卷積,其中第一、第二和第五層卷積後面連接了最大池化層,然後是 3 個全連接層。
  • 小白學PyTorch | 5 torchvision預訓練模型與數據集全覽
    文章目錄:1 torchvision.datssets2 torchvision.models模型比較本文建議複製代碼去跑跑看,增加一下手感。公眾號回復【torchvision】獲取代碼和數據。構建模型可以通過下面的代碼:import torchvision.models as modelsresnet18
  • 【小白學PyTorch】5.torchvision預訓練模型與數據集全覽
    文章目錄:1 torchvision.datssets2 torchvision.models模型比較本文建議複製代碼去跑跑看,增加一下手感。如果有些數據需要科學上網,公眾號回復【torchvision】獲取代碼和數據。
  • AlexNet:深度學習時代的開始
    另一方面,ReLU激活函數在不同的參數初始化方法下使模型更容易訓練。這是由於當sigmoid激活函數輸出極接近0或1時,這些區域的梯度幾乎為0,從而造成反向傳播無法繼續更新部分模型參數;而ReLU激活函數在正區間的梯度恆為1。因此,若模型參數初始化不當,sigmoid函數可能在正區間得到幾乎為0的梯度,從而令模型無法得到有效訓練。
  • onnx實現對pytorch模型推理加速
    對於硬體供應商來說,也可以簡化神經網絡計算的複雜度,實現優化算法。Pytorch 模型轉onnx當提到保存和加載模型時,有三個核心功能需要熟悉:1.torch.save:將序列化的對象保存到disk。這個函數使用Python的pickle實用程序進行序列化。使用這個函數可以保存各種對象的模型、張量和字典。
  • 小白學PyTorch | 12 SENet詳解及PyTorch實現
    > 小白學PyTorch | 11 MobileNet詳解及
  • 【深度學習系列】用PaddlePaddle和Tensorflow實現經典CNN網絡GoogLeNet
    點擊上圖,立即開啟AI急速修煉作者:Charlotte    高級算法工程師 ,博客專家;擅長用通俗易懂的方式講解深度學習和機器學習算法,在實驗過程中發現,當我們嘗試增加網絡的層數,或者增加每一層網絡的神經元個數的時候,對準確率有一定的提升,簡單的說就是增加網絡的深度與寬度,但這樣做有兩個明顯的缺點:  解決以上兩個問題的基本方法是將全連接或卷積連接改為稀疏連接。
  • 機器學習之多元線性回歸模型梯度下降公式與代碼實現(篇二)
    上一篇我們介紹了線性回歸的概述和最小二乘的介紹,對簡單的一元線性方程模型手推了公式和python代碼的實現。機器學習之線性回歸模型詳細手推公式與代碼實現(篇一)今天這一篇來介紹多元線性回歸模型多元線性回歸模型介紹在回歸分析中,如果有兩個或兩個以上的自變量,就稱為多元回歸
  • 模型堆疊(Stacking)和模型融合的原理與實現以及一個庫heamy的介紹
    只要知道stack是用cv交叉驗證來得出元模型的特徵(一個基模型產出一個元特徵作為二級模型的輸入),而blend是用留出法,比如百分之80作訓練,另外百分之20的預測值作為元模型的標籤(而stack是用全部的訓練集預測來產出一個基模型對應的標籤,二級模型只用那百分之20的預測值,這樣可以把堆疊用的數據集和二級模型泛化用的數據集分開,而stacking就沒有分開,所以stakcing有數據洩露,存在過擬合的風險
  • 一文詳解 Word2vec 之 Skip-Gram 模型(訓練篇)
    如果你對模型的詞彙表感興趣,可以點擊:http://t.cn/RoVde3h你還可以直接瀏覽這個詞彙表:http://t.cn/RoVdsZr如果想了解這個模型如何進行文檔中的詞組抽取,可以看論文中「Learning Phrases」這一章,對應的代碼在 word2phrase.c ,相關連結如下。
  • 序列模型的實現細節
    前言序列模型組件如 RNN 和 Attention 在自然語言處理中有廣泛的應用。但由於序列長度不一且變化範圍較大,為保證效率和穩定性,有許多實現上的細節需要考慮。同樣的理論在不同實現下效果往往會有神秘的差異,甚至會出現不能收斂的情況。本文總結了一些用 Tensorflow 實現序列模型的一些做法,並分析了效率和精度上的權衡。
  • 從AlexNet到BERT:深度學習中那些最重要的idea回顧
    即使特定的網絡架構有些不同,但概念、方法和代碼都是相通的。本文將介紹來自不同領域的一些研究,但進入正題前,需要聲明一下:這篇文章不是為下面提到的研究提供深入詳解或代碼示例,因為長篇複雜的論文其實很難被總結成一個簡短的段落。相反,作者只會簡要概述這些技術和相關歷史背景,並提供其論文和實現連結。