吊炸天的CNNs,這是我見過最詳盡的圖解!(上)

原文鏈接:吊炸天的CNNs,這是我見過最詳盡的圖解!(上) - AI 傳送門

導讀:卷積神經網路(CNNs)在「自動駕駛」、「人臉識別」、「醫療影像診斷」等領域,都發揮著巨大的作用。這一無比強大的演算法,喚起了很多人的好奇心。當阿爾法狗戰勝了李世石和柯傑後,人們都在談論「它」。

但是,

「它」是誰?

「它」是怎樣做到的?

已經成為每一個初入人工智慧——特別是圖像識別領域的朋友,都渴望探究的秘密。

本文通過「演算法可視化」的方法,將卷積神經網路的原理,呈獻給大家。教程分為上、下兩個部分,通篇長度不超過7000字沒有複雜的數學公式,希望你讀得暢快。

下面,我們就開始吧!


先提一個小問題:

「你是通過什麼了解這個世界的?」

當一輛汽車從你身邊疾馳而過,你是通過哪些信息知道那是一輛汽車?

「它的材質,速度,發動機的聲響,還是什麼?」

你可能說不清所以然,但是當你看到下圖時,你會第一時間反應出來,「噢,車! 」

為什麼你能猜對它?

「輪廓」!

——對,我給你看了它的輪廓。

再給你一些七七八八、大小不一的圖片,你總能猜對一些。

你是怎樣做到的?

很簡單

你讀了一張圖片 → 找到了圖片的特徵 → 進而對圖片做出了分類

其實,CNNs的工作原理也是這樣。

先不考慮那些複雜的專有名詞:什麼卷積(convolution)、池化(pooling)、過濾器(filter) 等等…… 統統拋到一邊。

CNNs做的就是下面3件事:

1. 讀取圖片; 2. 提取特徵; 3. 圖片分類。

下面,我們逐一來看各步驟的細節。

如果是一張黑白圖片,我們看到的,是這個樣子的:

而在計算機的眼裡,它看到的,是這個樣子的:

好沒有情趣……

這些數字是哪裡來的?

因為圖片是由一個又一個的像素點構成。(當你將圖片無限放大,你能看到那些像素點)

而每一個像素點,都是由一個0~255的數字組成。

所以,在計算機「看」來,一張圖片,就是一個又一個的數字。

所以,我們第一步的工作,是將左上圖的那隻小狗,轉換成右上圖的那一行行數字。

幸運的是,目前在python中,很多第三方庫,諸如PIL/Matplotlib等,都可以實現這種轉換,我們需要了解的是,後面的所有運算過程,都是基於右上圖來完成的,至於具體的轉換過程,不需要我們費心來做。

在文章開篇的例子中,我們知道,在識別一輛汽車的時候,可以將它的輪廓提取出來,從而判斷出那是一輛車。

同樣的,CNNs在識別圖片時,也需要提取圖像的特徵。

在CNNs中,完成這一工作的小伙叫「卷積」。(希望你不要糾結這個極具個性的名字,懂得它的原理就OK)

「卷積」在每次工作時,手裡都會握著幾把「過濾器」。

過濾器的作用是:尋找圖片的特徵

仍以小狗為例,過濾器會在圖片上從頭到尾「滑過」一遍

每滑到一個地方,就將該地方的圖像特徵提取出來。

那它是怎樣提取的呢?

別忘了,在計算機的眼裡,世界是這個樣子的:

(為了簡化問題,這裡將像素值僅用0和1表示)

假設過濾器是這個樣子的:

當橘色的過濾器在綠色矩形框中,緩慢滑過時,

我們用橘色過濾器中的每一個值,與綠色矩形框中的對應值相乘、再相加

有點兒拗口,直接看圖:

結果「4」,就是我們從第一個橘色方框中,提取出的特徵。

如果我們每次將橘色過濾器,向右、向下移動1格,則提取出的特徵為:

你可能會問:

我知道綠色矩陣代表一張圖片,是計算機「眼中」圖片的樣子。

但是, 經過橘色過濾器提取特徵後,得到的粉色矩陣,那是什麼?

我們從人類的視角,再重新審視一遍。

這次,我們回到之前的例子中。

仍以這張萌狗為例,它經過「過濾器」提取特徵後,得到的是一張……哦,好吧……看起來有點兒模糊的圖。

雖然圖片模糊了,但是圖片中的主要特徵,已經被過濾器全部提取出來,單憑這麼一張模糊的圖,作為人類的我們,足以對它做出判斷了。(誰敢說它是一隻貓?!)

下面,我們再換幾個過濾器試試。

這些就是經過過濾器提取後,得到的不同「特徵圖片」。

你也可以自己動手試試~~

卷積小遊戲:體驗玩中學的快感!

遊戲過後,記得要回來呦~~

由此我們可以看出,採用不同的「過濾器」,能夠提取出不同的圖片特徵。

你可能又會問:

那過濾器里的數值,該如何確定呢?

這就涉及到CNNs要做的工作了。每一個過濾器中的數值,都是演算法自己學習來的,不需要我們費心去設置。

需要我們做的有:

設置過濾器的大小(用字母「F」表示)

上例中,我們的過濾器大小是3×3,即F=3。

當然,你還可以設置成5×5,都是可以的。

只不過,需要注意的是:過濾器的尺寸越大,得到的圖像細節就越少,最終得到的特徵圖的尺寸也更小。

設置過濾器滑動的步幅數(用字母「S」表示)

上例中,過濾器滑動的步幅是1,即每次過濾器向右或向下滑動1個像素單位。

當然,你也可以將步幅設置為2或更多,但是通常情況下,我們會使用S=1或S=2。

設置過濾器的個數(用字母「K」表示)

上例中,我們分別給大家展示了4種過濾器。所以你可以理解為K=4,如下圖:

當然,你可以設置任意個數。

再次強調:不要在意過濾器裡面的數值,那是演算法自己學習來的,不需要我們操心,我們只要把過濾器的個數設置好,就可以了。

所以,一張圖片,在經過4種過濾器的提取後,會得到4種不同的特徵圖片:

實際上,這就是「卷積」小伙兒所做的工作。

從上面的例子我們能夠看到,「卷積」輸出的結果,是包含「寬、高、深」3個維度的:

實際上,在CNNs中,所有圖片都是包含有「寬、高、深」。

像輸入的圖片——萌狗,它也是包含3個維度,只不過,它的深度是1,所以在我們的圖片中沒有明顯地體現出來:

所以,我們要記住,經過「卷積」層的處理後,圖片含有深度,這個「深度」,等於過濾器的個數

例如,上面我們採用了4種過濾器,那麼,輸出的結果,深度就為4。

設置是否補零(用字母「P」表示)

何為「補零」?

上面的例子中,我們採用了3×3大小的過濾器,直接在原始圖片滑過。

從結果中可以看到,最終得到的「特徵圖片」比「原始圖片」小了一圈:

為什麼會出現這種情況?

原因很簡單:過濾器將原始圖片中,每3*3=9個像素點,提取為1個像素點

所以,當過濾器遍歷整個圖片後,得到的特徵圖片會比原始圖片更小。

當然,你也可以得到一個和原始圖片大小一樣的特徵圖,這就需要採用「在原始圖片外圍補零」的方法:

下面,我們來看看「補零」後的效果:

從圖中可以看到,當我們在原始圖片外圍補上1圈零後,得到的特徵圖大小和原始圖一樣,都是5*5。

你可能會問:

如何確定「補零」的圈數,才能保證圖片大小一致?

假設你的過濾器大小為F,滑動步幅S=1,想要實現這一目標,補零的個數應為:

舉個例子:

在上圖中,因為我們使用的是3*3大小的過濾器,而且每次滑動時,都是向右或向下移動1格。

所以,為了使特徵圖片與原始圖片保持一致,需要補零P=(3-1)/2=1,即在原始圖片外圍,補1圈零。

如果你使用的過濾器大小為5*5,那麼補零P=(5-1)/2=2,即在原始圖片外圍,補2圈零。

當然,是否需要「補零」,由你自己來決定,「補零」並不是硬性規定。

溫馨提示:

假設原始圖片的大小為W,當我們設置了

過濾器的大小(F)、滑動的步幅數(S)、以及補零的圈數(P)

實際上,得到的特徵圖片大小為:

所以,當我們設置這些超參數時,需要遵循一個原則,即「上面公式得到的結果,必須為一個整數」:

恭喜你!

看到這裡,CNNs中最難的部分我們已經學習完了。

下一期,我們會繼續了解 「非線性計算」 和 「池化」 。

但它們都很簡單,深呼吸,我們下期見……

※ 本文首發於微信公眾號:AI傳送門,歡迎關注。

更多機器學習的相關資料,可參考 機器學習資料匯總


推薦閱讀:

TAG:圖像識別 | 機器學習 | 卷積神經網路CNN |