LeNet 是最先推進深度學習領域發展的卷積神經網絡之一。這項由 Yann LeCun 完成的開創性工做自 1988 年以來屢次成功迭代以後被命名爲 LeNet5。AlexNet 是 Alex Krizhevsky 等人在 2012 年發表的《ImageNet Classification with Deep Convolutional Neural Networks》論文中提出的,並奪得了 2012 年 ImageNet LSVRC 的冠軍,引發了很大的轟動。AlexNet 能夠說是具備歷史意義的一個網絡結構,在此以前,深度學習已經沉寂了很長時間,自 2012 年 AlexNet 誕生以後,後面的 ImageNet 冠軍都是用卷積神經網絡(CNN)來作的,而且層次愈來愈深,使得CNN成爲在圖像識別分類的核心算法模型,帶來了深度學習的大爆發。本文將詳細講解 AlexNet 模型及其使用 Keras 實現過程。開始以前,先介紹一下卷積神經網絡。
html
卷積是一種數學運算,它採用某種方式將一個函數「應用」到另外一個函數,結果能夠理解爲兩個函數的「混合體」。不過,這對檢測圖像中的目標有何幫助?事實證實,卷積很是擅長檢測圖像中的簡單結構,而後結合這些簡單特徵來構造更復雜的特徵。在卷積網絡中,會在一系列的層上發生此過程,每層對前一層的輸出執行一次卷積。卷積運算的目的是提取輸入的不一樣特徵,第一層卷積層可能只能提取一些低級的特徵如邊緣、線條和角等層級,更多層的網路能從低級特徵中迭代提取更復雜的特徵。
那麼,您會在計算機視覺中使用哪一種卷積呢?要理解這一點,首先了解圖像究竟是什麼。圖像是一種二階或三階字節數組,二階數組包含寬度和高度 2 個維度,三階數組有 3 個維度,包括寬度、高度和通道,因此灰階圖是二階的,而 RGB 圖是三階的(包含 3 個通道)。字節的值被簡單解釋爲整數值,描述了必須在相應像素上使用的特定通道數量。因此基本上講,在處理計算機視覺時,能夠將一個圖像想象爲一個 2D 數字數組(對於 RGB 或 RGBA 圖像,能夠將它們想象爲 3 個或 4 個 2D 數字數組的相互重疊)。
前端
激活層主要是激活函數的做用,那麼什麼是激活函數呢?在神經網絡中,當輸入激勵達到必定強度,神經元就會被激活,產生輸出信號。模擬這一細胞激活過程的函數,就叫激活函數。將神經元的輸出 f,做爲其輸入 x 的函數,對其建模的標準方法是用python
或者 sigmoid 函數 。就梯度降低的訓練時間而言,AlexNet 提出了比上面方式快 6 倍的 ReLu 函數 。ReLU 全稱爲修正線性單元(Rectified Linear Units)是一種針對元素的操做(應用於每一個像素),並將特徵映射中的全部負像素值替換爲零的非線性操做。其目的是在卷積神經網絡中引入非線性因素,由於在實際生活中咱們想要用神經網絡學習的數據大多數都是非線性的(卷積是一個線性運算 —— 按元素進行矩陣乘法和加法,因此咱們但願經過引入 ReLU 這樣的非線性函數來解決非線性問題)。您會在卷積網絡中看到的另外一種重要的層是池化層。池化層具備多種形式:最大值,平均值,求和等。但最經常使用的是最大池化,其中輸入矩陣被拆分爲相同大小的分段,使用每一個分段中的最大值來填充輸出矩陣的相應元素。池化層能夠被認爲是由間隔爲 s 個像素的池單元網格組成,每一個池彙總了以池單元的位置爲中心的大小爲 z×z 的鄰域。若是咱們設置 s = z(池化窗口大小與步長相同),咱們得到在 CNN 中經常使用的傳統的局部合併。 若是咱們設置 s<z(每次移動的步長小於池化的窗口長度),咱們就得到重疊池化。在 AlexNet 中首次使用重疊池化來避免過擬合。
git
全鏈接層是一個傳統的多層感知器,它在輸出層使用 softmax 激活函數(也可使用其餘分類器,好比 SVM)。「徹底鏈接」這個術語意味着前一層中的每一個神經元都鏈接到下一層的每一個神經元。 這是一種普通的卷積網絡層,其中前一層的全部輸出被鏈接到下一層上的全部節點。卷積層轉換爲全鏈接層時,總神經元個數不變。 github
在神經生物學有一個概念叫作「側抑制」(lateral inhibitio),指的是被激活的神經元抑制相鄰神經元。歸一化(normalization)的目的是「抑制」,局部歸一化就是借鑑了「側抑制」的思想來實現局部抑制,尤爲當使用 ReLU 時這種「側抑制」很管用,由於 ReLU 的響應結果是無界的(能夠很是大),因此須要歸一化。使用局部歸一化的方法有助於增長泛化能力。
算法
減小圖像數據過擬合最簡單最經常使用的方法,是使用標籤-保留轉換,人爲地擴大數據集。AlexNet 模型使用兩種不一樣的形式,這兩種形式都容許轉換圖像用不多的計算量從原始圖像中產生,因此轉換圖像不須要存儲在磁盤上。數據擴充的第一種形式由生成圖像轉化和水平反射組成。數據擴充的第二種形式包含改變訓練圖像中 RGB 通道的強度。
數組
對某一層神經元,Dropout 作的就是以 0.5 的機率將每一個隱層神經元的輸出設置爲零。以這種方式 「Dropped out」 的神經元既不用於前向傳播,也不參與反向傳播。因此每次提出一個輸入,該神經網絡就嘗試一個不一樣的結構,全部這些結構之間共享權重。由於神經元不能依賴於其餘特定神經元而存在,因此這種技術下降了神經元複雜的互適應關係。正因如此,要被迫學習更爲魯棒的特徵,這些特徵在結合其餘神經元的一些不一樣隨機子集時有用。若是沒有 Dropout,AlexNet 網絡會表現出大量的過擬合。
微信
# (1) Importing dependency
import keras
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
import numpy as np
np.random.seed(1000)
# (2) Get Data
import tflearn.datasets.oxflower17 as oxflower17
x, y = oxflower17.load_data(one_hot=True)
# (3) Create a sequential model
model = Sequential()
複製代碼
AlexNet 模型創建在千分類問題上,其算力對計算機要求很高。這裏咱們爲了簡單復現,使用了 TensorFlow 的數據集 oxflower17 ,此數據集對花朵進行17 分類,每一個分類有 80 張照片。Keras 包含許多經常使用神經網絡構建塊的實現,例如層、目標、激活函數、優化器和一系列工具,能夠更輕鬆地處理圖像和文本數據。在 Keras 中有兩類主要的模型:Sequential 順序模型和使用函數式 API 的 Model 類模型。這裏使用 Sequential 模型。 網絡
# 1st Convolutional Layer
model.add(Conv2D(filters=96, input_shape=(224,224,3), kernel_size=(11,11), strides=(4,4), padding='valid'))
model.add(Activation('relu'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation before passing it to the next layer
model.add(BatchNormalization())
複製代碼
這裏 W1=224,H1=224,D1=3,K=48,F=11,S=4,P=1.5。app
計算卷積層 2 有 W2=(224-11+3)/4+1=55,同理 H2=55,D2=K*2=96。
通過卷積運算後,輸出特徵圖像大小爲 55X55X96。
這裏使用了最大池化,步長爲 S=2,則 W=(55-3)/2+1=27。
再通過池化後,輸出特徵圖像大小爲 27X27X96。
# 2nd Convolutional Layer
model.add(Conv2D(filters=256, kernel_size=(11,11), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())
複製代碼
同理,能夠計算卷積後獲得特徵圖像大小爲 27X27X256。
通過池化,輸出特徵圖像大小爲 13X13X256。**
# 3rd Convolutional Layer
model.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Batch Normalisation
model.add(BatchNormalization())
複製代碼
# 4th Convolutional Layer
model.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Batch Normalisation
model.add(BatchNormalization())
複製代碼
# 5th Convolutional Layer
model.add(Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())
複製代碼
# Passing it to a dense layer
model.add(Flatten())
# 1st Dense Layer
model.add(Dense(4096, input_shape=(224*224*3,)))
model.add(Activation('relu'))
# Add Dropout to prevent overfitting
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())
複製代碼
# 2nd Dense Layer
model.add(Dense(4096))
model.add(Activation('relu'))
# Add Dropout
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())
複製代碼
# 3rd Dense Layer
model.add(Dense(1000))
model.add(Activation('relu'))
# Add Dropout
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())
複製代碼
# Output Layer
model.add(Dense(17))
model.add(Activation('softmax'))
model.summary()
# (4) Compile
model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=['accuracy'])
# (5) Train
model.fit(x, y, batch_size=64, epochs=1, verbose=1, validation_split=0.2, shuffle=True)
複製代碼
最後在全鏈接層通過softmax激活函數後獲得結果。
目前,您能夠在 Mo 平臺中找到基於 AlexNet 的項目 Flower,此項目對原文的千分類進行整合,最終作成花卉的17分類。您在學習的過程當中,遇到困難或者發現咱們的錯誤,能夠隨時聯繫咱們。
項目源碼地址:www.momodel.cn:8899/explore/5cf…
總結一下 AlexNet 的主要貢獻:
Mo(網址:momodel.cn)是一個支持 Python 的人工智能在線建模平臺,能幫助你快速開發、訓練並部署模型。
Mo 人工智能俱樂部 是由網站的研發與產品設計團隊發起、致力於下降人工智能開發與使用門檻的俱樂部。團隊具有大數據處理分析、可視化與數據建模經驗,已承擔多領域智能項目,具有從底層到前端的全線設計開發能力。主要研究方向爲大數據管理分析與人工智能技術,並以此來促進數據驅動的科學研究。
目前俱樂部每週六在杭州舉辦以機器學習爲主題的線下技術沙龍活動,不按期進行論文分享與學術交流。但願能匯聚來自各行各業對人工智能感興趣的朋友,不斷交流共同成長,推進人工智能民主化、應用普及化。