(cs231n與5月dl班課程筆記)
1 前言
2012年我在北京組織過8期machine learning讀書會,那時“機器學習”非常火,很多人都對其抱有巨大的熱情。當我2013年再次來到北京時,有一個詞似乎比“機器學習”更火,那就是“深度學習”。
本博客內寫過一些機器學習相關的文章,但上一篇技術文章“LDA主題模型”還是寫於2014年11月份,畢竟自2015年開始創業做在線教育后,太多的雜事、瑣碎事,讓我一直想再寫點技術性文章但每每恨時間抽不開。然由於公司在不斷開機器學習、深度學習等相關的在線課程,耳濡目染中,總會順帶着學習學習。
我雖不參與講任何課程(我所在公司“七月在線”的所有在線課程都是由目前講師團隊的17位講師講),但依然可以用最最小白的方式 把一些初看復雜的東西抽絲剝繭的通俗寫出來。這算重寫技術博客的價值所在。
在dl中,有一個很重要的概念,就是卷積神經網絡CNN,基本是入門dl必須搞懂的東西。本文基本根據斯坦福的機器學習公開課、cs231n、與七月在線寒老師講的5月dl班第4次課CNN與常用框架視頻所寫,是一篇課程筆記。
一開始本文只是想重點講下CNN中的卷積操作具體是怎么計算怎么操作的,但后面不斷補充,包括增加不少自己的理解,故寫成了關於卷積神經網絡的通俗導論性的文章。有何問題,歡迎不吝指正。
2 人工神經網絡
2.1 神經元
神經網絡由大量的神經元相互連接而成。每個神經元接受線性組合的輸入后,最開始只是簡單的線性加權,后來給每個神經元加上了非線性的激活函數,從而進行非線性變換后輸出。每兩個神經元之間的連接代表加權值,稱之為權重(weight)。不同的權重和激活函數,則會導致神經網絡不同的輸出。
舉個手寫識別的例子,給定一個未知數字,讓神經網絡識別是什么數字。此時的神經網絡的輸入由一組被輸入圖像的像素所激活的輸入神經元所定義。在通過非線性激活函數進行非線性變換后,神經元被激活然后被傳遞到其他神經元。重復這一過程,直到最后一個輸出神經元被激活。從而識別當前數字是什么字。
神經網絡的每個神經元如下
基本wx + b的形式,其中
、
表示輸入向量
、
為權重,幾個輸入則意味着有幾個權重,即每個輸入都被賦予一個權重
- b為偏置bias
- g(z) 為激活函數
- a 為輸出
如果只是上面這樣一說,估計以前沒接觸過的十有八九又必定迷糊了。事實上,上述簡單模型可以追溯到20世紀50/60年代的感知器,可以把感知器理解為一個根據不同因素、以及各個因素的重要性程度而做決策的模型。
舉個例子,這周末北京有一草莓音樂節,那去不去呢?決定你是否去有二個因素,這二個因素可以對應二個輸入,分別用x1、x2表示。此外,這二個因素對做決策的影響程度不一樣,各自的影響程度用權重w1、w2表示。一般來說,音樂節的演唱嘉賓會非常影響你去不去,唱得好的前提下 即便沒人陪同都可忍受,但如果唱得不好還不如你上台唱呢。所以,我們可以如下表示:
:是否有喜歡的演唱嘉賓。
= 1 你喜歡這些嘉賓,
= 0 你不喜歡這些嘉賓。嘉賓因素的權重
= 7
:是否有人陪你同去。
= 1 有人陪你同去,
= 0 沒人陪你同去。是否有人陪同的權重
= 3。




2.2 激活函數
常用的非線性激活函數有sigmoid、tanh、relu等等,前兩者sigmoid/tanh比較常見於全鏈接層,后者relu常見於卷積層。這里先簡要介紹下最基礎的sigmoid函數(btw,在本博客中SVM那篇文章開頭有提過)。
sigmoid的函數表達式如下
其中z是一個線性組合,比如z可以等於:b + *
+
*
。通過代入很大的正數或很小的負數到g(z)函數中可知,其結果趨近於0或1。
因此,sigmoid函數g(z)的圖形表示如下( 橫軸表示定義域z,縱軸表示值域g(z) ):
也就是說,sigmoid函數的功能是相當於把一個實數壓縮至0到1之間。當z是非常大的正數時,g(z)會趨近於1,而z是非常大的負數時,則g(z)會趨近於0。
壓縮至0到1有何用處呢?用處是這樣一來便可以把激活函數看作一種“分類的概率”,比如激活函數的輸出為0.9的話便可以解釋為90%的概率為正樣本。
舉個例子,如下圖(圖引自Stanford機器學習公開課)
z = b + *
+
*
,其中b為偏置項 假定取-30,
、
都取為20
- 如果
= 0
= 0,則z = -30,g(z) = 1/( 1 + e^-z )趨近於0。此外,從上圖sigmoid函數的圖形上也可以看出,當z=-30的時候,g(z)的值趨近於0
- 如果
= 0
= 1,或
=1
= 0,則z = b +
*
+
*
= -30 + 20 = -10,同樣,g(z)的值趨近於0
- 如果
= 1
= 1,則z = b +
*
+
*
= -30 + 20*1 + 20*1 = 10,此時,g(z)趨近於1。
換言之,只有和
都取1的時候,g(z)→1,判定為正樣本;
或
取0的時候,g(z)→0,判定為負樣本,如此達到分類的目的。
2.3 神經網絡
將下圖的這種單個神經元
組織在一起,便形成了神經網絡。下圖便是一個三層神經網絡結構
上圖中最左邊的原始輸入信息稱之為輸入層,最右邊的神經元稱之為輸出層(上圖中輸出層只有一個神經元),中間的叫隱藏層。
啥叫輸入層、輸出層、隱藏層呢?
- 輸入層(Input layer),眾多神經元(Neuron)接受大量非線形輸入訊息。輸入的訊息稱為輸入向量。
- 輸出層(Output layer),訊息在神經元鏈接中傳輸、分析、權衡,形成輸出結果。輸出的訊息稱為輸出向量。
- 隱藏層(Hidden layer),簡稱“隱層”,是輸入層和輸出層之間眾多神經元和鏈接組成的各個層面。如果有多個隱藏層,則意味着多個激活函數。
同時,每一層都可能由單個或多個神經元組成,每一層的輸出將會作為下一層的輸入數據。比如下圖中間隱藏層來說,隱藏層的3個神經元a1、a2、a3皆各自接受來自多個不同權重的輸入(因為有x1、x2、x3這三個輸入,所以a1 a2 a3都會接受x1 x2 x3各自分別賦予的權重,即幾個輸入則幾個權重),接着,a1、a2、a3又在自身各自不同權重的影響下 成為的輸出層的輸入,最終由輸出層輸出最終結果。
上圖(圖引自Stanford機器學習公開課)中
表示第j層第i個單元的激活函數
/神經元
表示從第j層映射到第j+1層的控制函數的權重矩陣
此外,輸入層和隱藏層都存在一個偏置(bias unit),所以上圖中也增加了偏置項:x0、a0。針對上圖,有如下公式
此外,上文中講的都是一層隱藏層,但實際中也有多層隱藏層的,即輸入層和輸出層中間夾着數層隱藏層,層和層之間是全連接的結構,同一層的神經元之間沒有連接。
3 卷積神經網絡之層級結構
cs231n課程里給出了卷積神經網絡各個層級結構,如下圖
上圖中CNN要做的事情是:給定一張圖片,是車還是馬未知,是什么車也未知,現在需要模型判斷這張圖片里具體是一個什么東西,總之輸出一個結果:如果是車 那是什么車
所以
- 最左邊是數據輸入層,對數據做一些處理,比如去均值(把輸入數據各個維度都中心化為0,避免數據過多偏差,影響訓練效果)、歸一化(把所有的數據都歸一到同樣的范圍)、PCA/白化等等。CNN只對訓練集做“去均值”這一步。
中間是
- CONV:卷積計算層,線性乘積 求和。
- RELU:激勵層,上文2.2節中有提到:ReLU是激活函數的一種。
- POOL:池化層,簡言之,即取區域平均或最大。
最右邊是
- FC:全連接層
4 CNN之卷積計算層
4.1 什么是卷積

對應位置上是數字先相乘后相加
=
![]()
4.2 圖像上的卷積
如下圖所示
4.3 GIF動態卷積圖
a. 深度depth:神經元個數,決定輸出的depth厚度。同時代表濾波器個數。
b. 步長stride:決定滑動多少步可以到邊緣。
- 兩個神經元,即depth=2,意味着有兩個濾波器。
- 數據窗口每次移動兩個步長取3*3的局部數據,即stride=2。
- zero-padding=1。
- 左邊是輸入(7*7*3中,7*7代表圖像的像素/長寬,3代表R、G、B 三個顏色通道)
- 中間部分是兩個不同的濾波器Filter w0、Filter w1
- 最右邊則是兩個不同的輸出
隨着左邊數據窗口的平移滑動,濾波器Filter w0 / Filter w1對不同的局部數據進行卷積計算。
值得一提的是:
- 左邊數據在變化,每次濾波器都是針對某一局部的數據窗口進行卷積,這就是所謂的CNN中的局部感知機制。
- 打個比方,濾波器就像一雙眼睛,人類視角有限,一眼望去,只能看到這世界的局部。如果一眼就看到全世界,你會累死,而且一下子接受全世界所有信息,你大腦接收不過來。當然,即便是看局部,針對局部里的信息人類雙眼也是有偏重、偏好的。比如看美女,對臉、胸、腿是重點關注,所以這3個輸入的權重相對較大。
- 與此同時,數據窗口滑動,導致輸入在變化,但中間濾波器Filter w0的權重(即每個神經元連接數據窗口的權重)是固定不變的,這個權重不變即所謂的CNN中的參數(權重)共享機制。
- 再打個比方,某人環游全世界,所看到的信息在變,但采集信息的雙眼不變。btw,不同人的雙眼 看同一個局部信息 所感受到的不同,即一千個讀者有一千個哈姆雷特,所以不同的濾波器 就像不同的雙眼,不同的人有着不同的反饋結果。
我第一次看到上面這個動態圖的時候,只覺得很炫,另外就是據說計算過程是“相乘后相加”,但到底具體是個怎么相乘后相加的計算過程 則無法一眼看出,網上也沒有一目了然的計算過程。本文來細究下。
首先,我們來分解下上述動圖,如下圖
接着,我們細究下上圖的具體計算過程。即上圖中的輸出結果1具體是怎么計算得到的呢?其實,類似wx + b,w對應濾波器Filter w0,x對應不同的數據窗口,b對應Bias b0,相當於濾波器Filter w0與一個個數據窗口相乘再求和后,最后加上Bias b0得到輸出結果1,如下過程所示:
![]()
![]()
1* 0 + 1*0 + -1*0
+
-1*0 + 0*0 + 1*1
+
-1*0 + -1*0 + 0*1
+
-1*0 + 0*0 + -1*0
+
0*0 + 0*1 + -1*1
+
1*0 + -1*0 + 0*2
+
0*0 + 1*0 + 0*0
+
1*0 + 0*2 + 1*0
+
0*0 + -1*0 + 1*0
+
![]()
1
=
1
然后濾波器Filter w0固定不變,數據窗口向右移動2步,繼續做內積計算,得到0的輸出結果
最后,換做另外一個不同的濾波器Filter w1、不同的偏置Bias b1,再跟圖中最左邊的數據窗口做卷積,可得到另外一個不同的輸出。
5 CNN之激勵層與池化層
5.1 ReLU激勵層
2.2節介紹了激活函數sigmoid,但實際梯度下降中,sigmoid容易飽和、造成終止梯度傳遞,且沒有0中心化。咋辦呢,可以嘗試另外一個激活函數:ReLU,其圖形表示如下
ReLU的優點是收斂快,求梯度簡單。
5.2 池化pool層
前頭說了,池化,簡言之,即取區域平均或最大,如下圖所示(圖引自cs231n)
上圖所展示的是取區域最大,即上圖左邊部分中 左上角2x2的矩陣中6最大,右上角2x2的矩陣中8最大,左下角2x2的矩陣中3最大,右下角2x2的矩陣中4最大,所以得到上圖右邊部分的結果:6 8 3 4。很簡單不是?
6 后記
本文基本上邊看5月dl班寒講的CNN視頻邊做筆記,之前斷斷續續看過不少CNN相關的資料(包括cs231n),但看過視頻之后,才系統了解CNN到底是個什么東西,作為聽眾 寒講的真心贊、清晰。然后在寫CNN相關的東西時,發現一些前置知識(比如神經元、多層神經網絡等也需要介紹下),包括CNN的其它層次機構(比如激勵層),所以本文本只想簡要介紹下卷積操作的,但考慮到知識之間的前后關聯,所以越寫越長,便成本文了。
此外,在寫作本文的過程中,請教了我們講師團隊里的寒、馮兩位,感謝他兩。同時,感謝愛可可老師的微博轉發,感謝七月在線所有同事。
以下是修改日志:
- 2016年7月5日,修正了一些筆誤、錯誤,以讓全文更通俗、更精准。有任何問題或槽點,歡迎隨時指出。
- 2016年7月7日,第二輪修改完畢。且根據cs231n的卷積動圖依次截取了18張圖,然后用制圖工具制作了一gif 動態卷積圖,放在文中4.3節。
- 2016年7月16日,完成第三輪修改。本輪修改主要體現在sigmoid函數的說明上,通過舉例和統一相關符號讓其含義更一目了然、更清晰。
- 2016年8月15日,完成第四輪修改,增補相關細節。比如補充4.3節GIF動態卷積圖中輸入部分的解釋,即7*7*3的含義(其中7*7代表圖像的像素/長寬,3代表R、G、B 三個顏色通道)。不斷更易懂。
- 2016年8月22日,完成第五輪修改。本輪修改主要加強濾波器的解釋,及引入CNN中濾波器的通俗比喻。
7 參考文獻及推薦閱讀
- 人工神經網絡wikipedia
- 斯坦福機器學習公開課
- http://neuralnetworksanddeeplearning.com/
- 雨石 卷積神經網絡:http://blog.csdn.net/stdcoutzyx/article/details/41596663
- cs231n 神經網絡結構與神經元激勵函數:http://cs231n.github.io/neural-networks-1/,中譯版
- cs231n 卷積神經網絡:http://cs231n.github.io/convolutional-networks/
- 七月在線寒老師講的5月dl班第4次課CNN與常用框架視頻,已經剪切部分放在七月在線官網:julyedu.com
- 七月在線5月深度學習班第5課CNN訓練注意事項部分視頻:https://www.julyedu.com/video/play/42/207
- 七月在線5月深度學習班:https://www.julyedu.com/course/getDetail/37
- 七月在線5月深度學習班課程筆記——No.4《CNN與常用框架》:http://blog.csdn.net/joycewyj/article/details/51792477
- 七月在線6月數據數據挖掘班第7課視頻:數據分類與排序
- 手把手入門神經網絡系列(1)_從初等數學的角度初探神經網絡:http://blog.csdn.net/han_xiaoyang/article/details/50100367
- 深度學習與計算機視覺系列(6)_神經網絡結構與神經元激勵函數:http://blog.csdn.net/han_xiaoyang/article/details/50447834
- 深度學習與計算機視覺系列(10)_細說卷積神經網絡:http://blog.csdn.net/han_xiaoyang/article/details/50542880
- zxy 圖像卷積與濾波的一些知識點:http://blog.csdn.net/zouxy09/article/details/49080029
- zxy 深度學習CNN筆記:http://blog.csdn.net/zouxy09/article/details/8781543/
- http://www.wildml.com/2015/11/understanding-convolutional-neural-networks-for-nlp/,中譯版
- 《神經網絡與深度學習》中文講義:http://vdisk.weibo.com/s/A_pmE4iIPs9D
- ReLU與sigmoid/tanh的區別:https://www.zhihu.com/question/29021768
- CNN、RNN、DNN內部網絡結構區別:https://www.zhihu.com/question/34681168
- 理解卷積:https://www.zhihu.com/question/22298352
- 神經網絡與深度學習簡史:1 感知機和BP算法、4 深度學習的偉大復興
- 在線制作gif 動圖:http://www.tuyitu.com/photoshop/gif.htm
- 支持向量機通俗導論(理解SVM的三層境界)