- 原文地址:Implementation of Convolutional Neural Network using Python and Keras
- 原文做者:rubikscode
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:JohnJiangLA
- 校對者:Gladysgong Starrier
你有沒有想過?Snapchat 是如何檢測人臉的?自動駕駛汽車是怎麼知道路在哪裏?你猜的沒錯,他們是使用了卷積神經網絡這種專門用於處理計算機視覺的神經網絡。在前一篇文章中,咱們研究了它們是怎麼工做的。咱們討論了這些神經網絡的層及其功能。基本上,卷積神經網絡的附加層會將圖像處理成神經網絡可以支持的標準格式。這樣作的第一步是檢測某些特徵或屬性,這些工做是由卷積層完成的。前端
這一層使用過濾器來檢測低層次的特徵(好比邊緣和曲線)以及更高層次的特徵(好比臉和手)。而後卷積神經網絡使用附加層消除圖像中的線性干擾,這些干擾會致使過度擬合。當線性干擾移除後,附加層會將圖像下采樣並將數據進行降維。最後,這些信息會被傳遞到一個神經網絡中,在卷積神經網絡中它叫全鏈接層。一樣,本文的目標是如何實現這些層,所以關於這些附加層的更多細節以及如何工做和具體用途均可以在前一篇文章中找到。python
在咱們開始解決問題和開始碼代碼以前,請正確配置好你的環境。與本系列以前的全部文章同樣,我會使用 Python 3.6。另外,我使用的是 Anaconda 和 Spyder,可是你也可使用其餘的 IDE。而後,最重要的是安裝 Tensorflow 和 Keras。安裝和使用 Tensorflow 的說明請查看此處,而安裝和使用 Keras 的說明請查看此處。android
所以,在本文中,咱們將訓練咱們的網絡來識別圖像中的數字。爲此,咱們將使用另外一個著名的數據集 —— MNIST 數據集。在前身 NIST 的基礎上,這個數據集由一個包含 60,000 個樣本的訓練集和一個包含 10,000 個手寫數字圖像的測試集組成。全部數字都已大小歸一化並居中了。圖像的大小也是固定的,所以預處理圖像數據已被最簡化了。這也是這個數據集爲什麼如此流行的緣由。它被認爲是卷積神經網絡世界中的 「Hello World」 樣例。ios
此外,使用卷積神經網絡,咱們能夠獲得與人類判斷相差無幾的結果。目前,這一紀錄由 Parallel Computing Center(赫梅爾尼茨基,烏克蘭)保持。他們只使用了由 5 個卷積神經網絡組成的集合,並將錯誤率控制在 0.21%。很酷吧?git
與本系列前面的文章同樣,咱們首先導入全部必要的庫。其中一些是咱們熟悉的,可是其中一些須要進一步講解。github
正如你所見,咱們將使用 numpy,這是咱們在前面的示例中用於操做多維數組和矩陣的庫。另外,也能夠看到,咱們會使用一些本系列以前 Keras 庫中用過的特性,也會使用一些新特性。好比建立模型和標準層(好比全鏈接層)會使用到 Sequential 和 Dense。算法
此外,咱們還會使用一些 Keras 中的新類。Conv2D 是用於建立卷積層的類。MaxPooling2D 則是用於建立池化層的類,而 Flatten 是用於降維的類。咱們也使用 Keras util 中的 to_categorical。該類用於將向量(整形量)轉化爲二值類別矩陣,即它用於 one-hot 編碼。最後,注意咱們將使用 matplotlib 來顯示結果。後端
導入必要的庫和類以後,咱們須要處理數據。幸運的是,Keras 提供了 MNIST 數據集, 因此咱們不須要下載它。如前所述,全部這些圖像都已經進行了部分預處理。這意味着他們有相同的大小和數字位於合適的位置。所以,讓咱們導入這個數據集併爲咱們的模型準備數據:數組
如你所見,咱們從 Keras 數據集中導入了 MNIST 數據集。而後,咱們將數據加載到訓練和測試矩陣中。在此基礎上,利用形狀屬性獲得圖像的維數,並對輸入數據進行重構,從而獲得輸入圖像的一個通道。基本上,咱們只使用這個圖像的一個通道,而不是常規的三個通道(RGB)。這樣作是爲了簡化實現的難度。而後對輸入矩陣中的數據進行歸一化處理。最後,咱們使用 to_categorical 對輸出矩陣進行編碼。網絡
如今,數據已經準備好了,咱們能夠開始最有趣的環節了 —— 建立模型:
理所固然的,咱們爲此須要使用 Sequential,並首先使用 Conv2D 類添加捲積層。正如你所見的,這個類使用的參數不多,因此讓咱們一塊兒來研究下。第一個參數是定要使用的過濾器個數,即要檢測的特徵個數。一般來講咱們從 32 開始隨後逐步增大這個數字。這正是咱們在作的,在第一個卷積層中咱們檢測 32 個特徵,第二層中 64 個,最後的第三層中 128 個。使用的過濾器大小則由下一個參數 —— kernel_size 來定義,咱們已經選擇了 3*3 的過濾器。
在激活函數中,咱們使用整流器函數。這樣,在每一個卷積層中非線性程度都會天然增長。實現這一點的另外一種方法是使用 keras.layers.advanced_activations 中的 LeakyReLU。它不像標準的整理器函數,不是將全部低於某一固定值的值壓縮爲零,而是有一個輕微的負斜率。若是你決定使用它,請注意必須使用 Conv2D 中的線性激活。下面就是這種方式的樣例:
咱們有點跑題了。講回到 Conv2D 及其參數。另外一個很是重要的參數是 input_shape。使用這個參數,定義輸入圖像的維數。如前所述,咱們只使用一個通道,這是爲何咱們的 input_shape 最終維度是 1。這是咱們從輸入圖像中提取的維度。
此外,咱們還在模型中添加了其它層。Dropout 層能幫助咱們防止過度擬合,此後,咱們使用 MasPooling2D 類添加池化層。顯然,這一層使用的是 max-pool 算法,池化過濾器的大小則是 2*2。池化層以後是降維層,最後是全鏈接層。對於最後的全鏈接層,咱們添加了兩層的神經網絡,對於這兩層,咱們使用了 Dense 類。最後,咱們編譯模型,並使用了 Adam 優化器。
若是你不明白其中的一些概念,你能夠查看以前的文章,其中解釋了卷積層的原理機制。另外,若是你對於一些 Keras 的內容有疑惑,那麼這篇文章會幫助到你。
很好,咱們的數據預處理了,咱們的模型也建好了。下面咱們將他們合併到一塊兒,並訓練咱們的模型。爲了使咱們正在使用的可以運轉正常。咱們傳入輸入矩陣並定義 batch_size 和 epoch 數。咱們要作的另一件事是定義 validation_split。這個參數用於定義將測試數據的哪一個部分用做驗證數據。
基本上,該模型將保留部分訓練數據,但它使用這部分數據在每一個循環結束時計算損失和其餘模型矩陣。這與測試數據不一樣,由於咱們在每一個循環結束後都會使用它。
在咱們的模型已經訓練完成並準備好以後,咱們使用 evaluate 方法並將測試集傳入。這裏咱們可以得出這個卷積神經網絡的準確率。
咱們能夠作的另外一件事是在測試數據集中收集對對神經網絡的預測。這樣,咱們就能夠將預測結果和實際結果進行比較。爲此,咱們將使用 predict 方法。使用這個方法咱們還能夠對單個輸入進行預測。
讓咱們使用這些咱們剛剛收集到的預測來完成咱們實現的最後一步。咱們將顯示預測的數字與實際的數字。咱們還會顯示咱們預測的圖像。基本上,咱們將爲咱們的實現作很好的可視化展現。畢竟,咱們在處理圖像。
在這裏,咱們使用了 pyplot 來顯示十幅圖像,並給出了實際結果和咱們的預測。當咱們運行咱們的實現時,以下圖所示:
咱們運行了 20 輪並獲得了 99.39% 的準確率。並不差,固然這還有提高空間。
卷積神經網絡是計算機視覺領域中一個很是有趣的分支,也是最有影響力的創新之一。本文中咱們實現了這些神經網絡中的一個簡易版本並用它來檢測 MNIST 數據集上的數字。
感謝閱讀!
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。