用Keras實現一個標準的CNN!

本文主要介紹了機器學習概念,討論了典型卷積神經網絡中的主要部分,如卷積層、合併層和完全連接層。

用Keras實現一個標準的CNN!

介紹

卷積神經網絡(CNN)是一組深層網絡,它可以利用數據(如圖像)的空間結構來了解數據,從而使算法可以輸出一些有用的信息。考慮一個問題,如何確定某個圖像中是否有人?例如,如果給CNN一個人的圖像,這個深度神經網絡首先需要學習一些局部特徵(例如眼睛、鼻子、嘴巴等)。這些局部特徵就是在卷積層中習得的。

然後,CNN將查看給定圖像中存在的局部特徵,然後生成特定的激活模式(或激活矢量),該激活模式將完全的表示這些局部特徵映射的存在。這些激活模式由CNN中完全連接的層產生。例如,如果圖像為非人物,則激活模式將與針對人物圖像的激活模式不同。

CNN在模塊化層面

現在介紹CNN中的子模塊。一個典型的CNN有三種不同的部分。它們是卷積層、合併層和完全連接層。下文將重點介紹合併層的概念。

首先我們討論卷積層在深度上起到的作用。卷積層由許多內核組成,存在於卷積層中的這些內核(有時稱為卷積濾波器)學習圖像中存在的局部特徵。卷積層學習的這種局部特徵稱為特徵映射。然後將這些特徵在圖像上進行卷積。這種卷積操作將產生一個矩陣(有時稱為激活圖)。如果在卷積濾波器中表示的特徵出現在輸入的該位置處,則激活映射在給定位置處產生高值。

合併層使這些特徵通過CNN平移而不會改變(例如,無論人的眼睛是在[x = 10,y = 10]還是[x = 12,y = 11]位置,合併層輸出都相同)。聚合幾個這樣的層,會使我們具有更高的平移不變性。

最後是完全連接層。完全連接層負責根據激活的特徵圖集和圖像中的位置生成不同的激活圖案,並激活特徵圖。這就是CNN在視覺上的樣子。

用Keras實現一個標準的CNN!

在瞭解CNN的整體結構的基礎上,讓我們繼續理解構成CNN的每個子組件。

卷積層

卷積運算具體做些什麼? 如果該位置存在卷積特徵,則卷積運算為給定位置輸出高值,否則輸出低值。更具體地說,在卷積核的給定位置,我們取每個核心單元值和與核心單元重疊的對應圖像像素值的元素相乘,然後取它們的和。精確值的確定根據以下公式(m - 核寬和高,h - 卷積輸出,x - 輸入,w - 卷積核)。

用Keras實現一個標準的CNN!

圖像上的卷積過程,如下圖所示:

用Keras實現一個標準的CNN!

僅僅知道卷積運算的作用還不夠,我們還需要了解卷積輸出代表什麼。設想卷積輸出中的值的顏色(0 - 黑色,100 - 白色)。如果你將這幅圖可視化像,它將代表一個在眼睛所在位置發光的二元圖像。

用Keras實現一個標準的CNN!

卷積運算也可以被認為是對給定圖像進行某種變換。該變換可能導致各種效果(例如,提取邊緣,模糊等)。

合併層

現在讓我們來了解合併層的功能。合併(或有時稱為二次採樣)層使得CNN在卷積輸出方面具有平移不變性。實踐中使用兩種不同的池化機制(最大池化和平均池化)。 我們將max-pooling稱為pooling,因為max-pooling與平均池化相比被廣泛使用。更準確地說,在給定位置的合併操作輸出落入內核的輸入的最大值。 在數學上,

用Keras實現一個標準的CNN!

讓我們通過在前面看到的卷積輸出上應用合併層操作來理解其的工作原理。

用Keras實現一個標準的CNN!

如您所見,我們使用同一圖像的兩個變體。一個原始圖像和另一個圖像在x軸上稍微平移。 但是,合併操作會使兩個圖像輸出完全相同的特徵圖(黑色 - 0,白色 - 100)。 所以我們說合並操作使得CNN翻譯不變量的知識成為可能。需要注意的一點是,我們每次移動的像素不是1個像素,而是2個像素。這就是所謂的跨越式合併,這意味著我們正在以2的步幅進行合併。

完全連接層

完全連接層將結合由不同卷積核所學習的特徵,以便網絡可以建立關於整體圖像的全局表示。 我們可以理解完全連接層,如下所示。

用Keras實現一個標準的CNN!

完全連接層中的神經元將根據輸入中是否存在由卷積特徵表示的各種實體而被激活。當完全連接的神經元為此被激活時,它會根據輸入圖像中存在的特徵產生不同的激活模式。這為圖像中存在的輸出層提供了一種緊湊的表示形式,即輸出層可以輕鬆用於正確分類圖像。

一起編織它們

現在我們所要做的就是將所有這些組合起來,形成一個從原始圖像到決策的模型。總而言之,卷積層將學習數據中的各種局部特徵,那麼合併層將使得CNN對於這些特徵的平移不變。最後,我們有完全連接層,說:"我們發現了兩隻眼睛、一隻鼻子和一隻嘴巴,所以這一定是一個人,並激活正確的輸出。

添加越來越多的層有什麼作用?

增加更多的層顯然可以提高深度神經網絡的性能。事實上,深度學習中最引人注目的突破性研究大多與解決如何添加更多層同時不影響模型的訓練的問題有關。因為模型越深入,訓練越困難。

但擁有更多的層可以幫助CNN以分層方式學習功能。例如,第一層學習圖像中的各種邊緣方向,第二層學習基本形狀(圓形、三角形等),第三層學習更高級的形狀(例如,眼睛的形狀、鼻子的形狀)等等上。與使用單層學習的CNN相比,這將會有更好的性能。

訓練CNN(又名反向傳播)

現在需要記住的一點是,當你實現CNN時,這些卷積特徵(眼睛、鼻子、嘴巴)不會自己出現。CNN的目標是學習給定數據的這些特徵。為此,我們定義一個成本函數,獎勵正確識別的數據並懲罰錯誤分類的數據。示例成本函數是均方根誤差或二元交叉熵損失。

在定義了損失之後,我們可以優化特徵的權重(即特徵的每個單元格值),以反映引導CNN正確識別某個人的有用特徵。更具體地說,我們通過在每個參數的梯度相對於損失顯示的相反方向上邁出一小步來優化每個卷積核和完全連接的神經元。但是,要實現CNN,您需要知道如何實現梯度傳播的確切細節。這是因為,大多數深度學習庫(例如TensorFlow、PyTorch)會在您自定義正向計算時在內部實施這些差異化操作。

用Keras實現和運行CNN

這裡我們將簡要討論如何實現CNN。僅僅瞭解基礎知識還不夠,我們也應該瞭解如何使用像Keras這樣的標準深度學習庫來實現模型。

首先我們定義我們想要使用的Keras API。 我們將使用順序API。

用Keras實現一個標準的CNN!

然後我們定義一個卷積層,如下所示:

用Keras實現一個標準的CNN!

在這裡,32是該層中的內核數量,(3,3)是卷積層的內核大小(高度和寬度)。我們使用非線性激活Relu和[圖像高度、圖像寬度、顏色通道]的輸入形狀[28,28,1]。 請注意,輸入形狀應該是前一層產生的輸出的形狀 因此,對於第一個卷積層,我們有實際的數據輸入。 對於層的其餘部分,它將是前一層產生的輸出。接下來我們討論如何實現最大池化:

用Keras實現一個標準的CNN!

這裡我們不提供任何參數,因為我們將使用Keras中提供的默認值。如果你沒有指定參數,Keras將使用(2,2)的內核大小和(2,2)的步幅。接下來我們定義完全連接層。但在此之前,我們需要將輸出平坦化,因為完全連接層要處理1D數據:

用Keras實現一個標準的CNN!

在這裡我們定義了兩個完全連接或密集的層。 第一個完全連接的層有256個神經元,並使用Relu激活。 最後,我們定義一個具有10個輸出節點並具有softmax激活的密集層。 這充當輸出層,它將激活具有相同對象的圖像的特定神經元。 最後我們編譯我們的模型,

用Keras實現一個標準的CNN!

在這裡,我們說使用 Adam optimiser(訓練模型),使用交叉熵損失並用模型的準確性來評估模型。最後我們可以使用數據來訓練和測試我們的模型。我們將使用MNIST數據集,使用在練習中定義的maybe_download和read_mnist函數下載並讀入內存。MNIST數據集包含手寫數字(0-9)的圖像,目標是通過分配圖像表示的數字來正確分類圖像。

接下來我們通過調用以下函數來訓練我們的模型:

用Keras實現一個標準的CNN!

我們可以用一些測試數據來測試我們的模型,如下所示:

用Keras實現一個標準的CNN!

我們將在幾個不同的時期運行它,這將幫助您提高您的模型性能。

結論

我們首先站在有利位置討論了在CNN內部發生的事情。然後我們討論了典型CNN中的主要部分,如卷積層、合併層和完全連接層。之後我們更詳細地介紹了每個部分。接下來,我們非常簡短地討論瞭如何在CNN中訓練。最後我們討論了我們可以用Keras實現一個標準的CNN:一個高級的TensorFlow庫。


分享到:


相關文章: