A. 人工神經網路概念梳理與實例演示
人工神經網路概念梳理與實例演示
神經網路是一種模仿生物神經元的機器學習模型,數據從輸入層進入並流經激活閾值的多個節點。
遞歸性神經網路一種能夠對之前輸入數據進行內部存儲記憶的神經網路,所以他們能夠學習到數據流中的時間依賴結構。
如今機器學習已經被應用到很多的產品中去了,例如,siri、Google Now等智能助手,推薦引擎——亞馬遜網站用於推薦商品的推薦引擎,Google和Facebook使用的廣告排名系統。最近,深度學習的一些進步將機器學習帶入公眾視野:AlphaGo 打敗圍棋大師李世石事件以及一些圖片識別和機器翻譯等新產品的出現。
在這部分中,我們將介紹一些強大並被普遍使用的機器學習技術。這當然包括一些深度學習以及一些滿足現代業務需求傳統方法。讀完這一系列的文章之後,你就掌握了必要的知識,便可以將具體的機器學習實驗應用到你所在的領域當中。
隨著深層神經網路的精度的提高,語音和圖像識別技術的應用吸引了大眾的注意力,關於AI和深度學習的研究也變得更加普遍了。但是怎麼能夠讓它進一步擴大影響力,更受歡迎仍然是一個問題。這篇文章的主要內容是:簡述前饋神經網路和遞歸神經網路、怎樣搭建一個遞歸神經網路對時間系列數據進行異常檢測。為了讓我們的討論更加具體化,我們將演示一下怎麼用Deeplearning4j搭建神經網路。
一、什麼是神經網路?
人工神經網路演算法的最初構思是模仿生物神經元。但是這個類比很不可靠。人工神經網路的每一個特徵都是對生物神經元的一種折射:每一個節點與激活閾值、觸發的連接。
連接人工神經元系統建立起來之後,我們就能夠對這些系統進行訓練,從而讓他們學習到數據中的一些模式,學到之後就能執行回歸、分類、聚類、預測等功能。
人工神經網路可以看作是計算節點的集合。數據通過這些節點進入神經網路的輸入層,再通過神經網路的隱藏層直到關於數據的一個結論或者結果出現,這個過程才會停止。神經網路產出的結果會跟預期的結果進行比較,神經網路得出的結果與正確結果的不同點會被用來更正神經網路節點的激活閾值。隨著這個過程的不斷重復,神經網路的輸出結果就會無限靠近預期結果。
二、訓練過程
在搭建一個神經網路系統之前,你必須先了解訓練的過程以及網路輸出結果是怎麼產生的。然而我們並不想過度深入的了解這些方程式,下面是一個簡短的介紹。
網路的輸入節點收到一個數值數組(或許是叫做張量多維度數組)就代表輸入數據。例如, 圖像中的每個像素可以表示為一個標量,然後將像素傳遞給一個節點。輸入數據將會與神經網路的參數相乘,這個輸入數據被擴大還是減小取決於它的重要性,換句話說,取決於這個像素就不會影響神經網路關於整個輸入數據的結論。
起初這些參數都是隨機的,也就是說神經網路在建立初期根本就不了解數據的結構。每個節點的激活函數決定了每個輸入節點的輸出結果。所以每個節點是否能夠被激活取決於它是否接受到足夠的刺激強度,即是否輸入數據和參數的結果超出了激活閾值的界限。
在所謂的密集或完全連接層中,每個節點的輸出值都會傳遞給後續層的節點,在通過所有隱藏層後最終到達輸出層,也就是產生輸入結果的地方。在輸出層, 神經網路得到的最終結論將會跟預期結論進行比較(例如,圖片中的這些像素代表一隻貓還是狗?)。神經網路猜測的結果與正確結果的計算誤差都會被納入到一個測試集中,神經網路又會利用這些計算誤差來不斷更新參數,以此來改變圖片中不同像素的重要程度。整個過程的目的就是降低輸出結果與預期結果的誤差,正確地標注出這個圖像到底是不是一條狗。
深度學習是一個復雜的過程,由於大量的矩陣系數需要被修改所以它就涉及到矩陣代數、衍生品、概率和密集的硬體使用問題,但是用戶不需要全部了解這些復雜性。
但是,你也應該知道一些基本參數,這將幫助你理解神經網路函數。這其中包括激活函數、優化演算法和目標函數(也稱為損失、成本或誤差函數)。
激活函數決定了信號是否以及在多大程度上應該被發送到連接節點。階梯函數是最常用的激活函數, 如果其輸入小於某個閾值就是0,如果其輸入大於閾值就是1。節點都會通過階梯激活函數向連接節點發送一個0或1。優化演算法決定了神經網路怎麼樣學習,以及測試完誤差後,權重怎麼樣被更准確地調整。最常見的優化演算法是隨機梯度下降法。最後, 成本函數常用來衡量誤差,通過對比一個給定訓練樣本中得出的結果與預期結果的不同來評定神經網路的執行效果。
Keras、Deeplearning4j 等開源框架讓創建神經網路變得簡單。創建神經網路結構時,需要考慮的是怎樣將你的數據類型匹配到一個已知的被解決的問題,並且根據你的實際需求來修改現有結構。
三、神經網路的類型以及應用
神經網路已經被了解和應用了數十年了,但是最近的一些技術趨勢才使得深度神經網路變得更加高效。
GPUs使得矩陣操作速度更快;分布式計算結構讓計算能力大大增強;多個超參數的組合也讓迭代的速度提升。所有這些都讓訓練的速度大大加快,迅速找到適合的結構。
隨著更大數據集的產生,類似於ImageNet 的大型高質量的標簽數據集應運而生。機器學習演算法訓練的數據越大,那麼它的准確性就會越高。
最後,隨著我們理解能力以及神經網路演算法的不斷提升,神經網路的准確性在語音識別、機器翻譯以及一些機器感知和面向目標的一些任務等方面不斷刷新記錄。
盡管神經網路架構非常的大,但是主要用到的神經網路種類也就是下面的幾種。
3.1前饋神經網路
前饋神經網路包括一個輸入層、一個輸出層以及一個或多個的隱藏層。前饋神經網路可以做出很好的通用逼近器,並且能夠被用來創建通用模型。
這種類型的神經網路可用於分類和回歸。例如,當使用前饋網路進行分類時,輸出層神經元的個數等於類的數量。從概念上講, 激活了的輸出神經元決定了神經網路所預測的類。更准確地說, 每個輸出神經元返回一個記錄與分類相匹配的概率數,其中概率最高的分類將被選為模型的輸出分類。
前饋神經網路的優勢是簡單易用,與其他類型的神經網路相比更簡單,並且有一大堆的應用實例。
3.2卷積神經網路
卷積神經網路和前饋神經網路是非常相似的,至少是數據的傳輸方式類似。他們結構大致上是模仿了視覺皮層。卷積神經網路通過許多的過濾器。這些過濾器主要集中在一個圖像子集、補丁、圖塊的特徵識別上。每一個過濾器都在尋找不同模式的視覺數據,例如,有的可能是找水平線,有的是找對角線,有的是找垂直的。這些線條都被看作是特徵,當過濾器經過圖像時,他們就會構造出特徵圖譜來定位各類線是出現在圖像的哪些地方。圖像中的不同物體,像貓、747s、榨汁機等都會有不同的圖像特徵,這些圖像特徵就能使圖像完成分類。卷積神經網路在圖像識別和語音識別方面是非常的有效的。
卷積神經網路與前饋神經網路在圖像識別方面的異同比較。雖然這兩種網路類型都能夠進行圖像識別,但是方式卻不同。卷積神經網路是通過識別圖像的重疊部分,然後學習識別不同部分的特徵進行訓練;然而,前饋神經網路是在整張圖片上進行訓練。前饋神經網路總是在圖片的某一特殊部分或者方向進行訓練,所以當圖片的特徵出現在其他地方時就不會被識別到,然而卷積神經網路卻能夠很好的避免這一點。
卷積神經網路主要是用於圖像、視頻、語音、聲音識別以及無人駕駛的任務。盡管這篇文章主要是討論遞歸神經網路的,但是卷積神經網路在圖像識別方面也是非常有效的,所以很有必要了解。
3.3遞歸神經網路
與前饋神經網路不同的是,遞歸神經網路的隱藏層的節點里有內部記憶存儲功能,隨著輸入數據的改變而內部記憶內容不斷被更新。遞歸神經網路的結論都是基於當前的輸入和之前存儲的數據而得出的。遞歸神經網路能夠充分利用這種內部記憶存儲狀態處理任意序列的數據,例如時間序列。
遞歸神經網路經常用於手寫識別、語音識別、日誌分析、欺詐檢測和網路安全。
遞歸神經網路是處理時間維度數據集的最好方法,它可以處理以下數據:網路日誌和伺服器活動、硬體或者是醫療設備的感測器數據、金融交易、電話記錄。想要追蹤數據在不同階段的依賴和關聯關系需要你了解當前和之前的一些數據狀態。盡管我們通過前饋神經網路也可以獲取事件,隨著時間的推移移動到另外一個事件,這將使我們限制在對事件的依賴中,所以這種方式很不靈活。
追蹤在時間維度上有長期依賴的數據的更好方法是用內存來儲存重要事件,以使近期事件能夠被理解和分類。遞歸神經網路最好的一點就是在它的隱藏層裡面有「內存」可以學習到時間依賴特徵的重要性。
接下來我們將討論遞歸神經網路在字元生成器和網路異常檢測中的應用。遞歸神經網路可以檢測出不同時間段的依賴特徵的能力使得它可以進行時間序列數據的異常檢測。
遞歸神經網路的應用
網路上有很多使用RNNs生成文本的例子,遞歸神經網路經過語料庫的訓練之後,只要輸入一個字元,就可以預測下一個字元。下面讓我們通過一些實用例子發現更多RNNs的特徵。
應用一、RNNs用於字元生成
遞歸神經網路經過訓練之後可以把英文字元當做成一系列的時間依賴事件。經過訓練後它會學習到一個字元經常跟著另外一個字元(「e」經常跟在「h」後面,像在「the、he、she」中)。由於它能預測下一個字元是什麼,所以它能有效地減少文本的輸入錯誤。
Java是個很有趣的例子,因為它的結構包括很多嵌套結構,有一個開的圓括弧必然後面就會有一個閉的,花括弧也是同理。他們之間的依賴關系並不會在位置上表現的很明顯,因為多個事件之間的關系不是靠所在位置的距離確定的。但是就算是不明確告訴遞歸神經網路Java中各個事件的依賴關系,它也能自己學習了解到。
在異常檢測當中,我們要求神經網路能夠檢測出數據中相似、隱藏的或許是並不明顯的模式。就像是一個字元生成器在充分地了解數據的結構後就會生成一個數據的擬像,遞歸神經網路的異常檢測就是在其充分了解數據結構後來判斷輸入的數據是不是正常。
字元生成的例子表明遞歸神經網路有在不同時間范圍內學習到時間依賴關系的能力,它的這種能力還可以用來檢測網路活動日誌的異常。
異常檢測能夠使文本中的語法錯誤浮出水面,這是因為我們所寫的東西是由語法結構所決定的。同理,網路行為也是有結構的,它也有一個能夠被學習的可預測模式。經過在正常網路活動中訓練的遞歸神經網路可以監測到入侵行為,因為這些入侵行為的出現就像是一個句子沒有標點符號一樣異常。
應用二、一個網路異常檢測項目的示例
假設我們想要了解的網路異常檢測就是能夠得到硬體故障、應用程序失敗、以及入侵的一些信息。
模型將會向我們展示什麼呢?
隨著大量的網路活動日誌被輸入到遞歸神經網路中去,神經網路就能學習到正常的網路活動應該是什麼樣子的。當這個被訓練的網路被輸入新的數據時,它就能偶判斷出哪些是正常的活動,哪些是被期待的,哪些是異常的。
訓練一個神經網路來識別預期行為是有好處的,因為異常數據不多,或者是不能夠准確的將異常行為進行分類。我們在正常的數據里進行訓練,它就能夠在未來的某個時間點提醒我們非正常活動的出現。
說句題外話,訓練的神經網路並不一定非得識別到特定事情發生的特定時間點(例如,它不知道那個特殊的日子就是周日),但是它一定會發現一些值得我們注意的一些更明顯的時間模式和一些可能並不明顯的事件之間的聯系。
我們將概述一下怎麼用 Deeplearning4j(一個在JVM上被廣泛應用的深度學習開源資料庫)來解決這個問題。Deeplearning4j在模型開發過程中提供了很多有用的工具:DataVec是一款為ETL(提取-轉化-載入)任務准備模型訓練數據的集成工具。正如Sqoop為Hadoop載入數據,DataVec將數據進行清洗、預處理、規范化與標准化之後將數據載入到神經網路。這跟Trifacta』s Wrangler也相似,只不過它更關注二進制數據。
開始階段
第一階段包括典型的大數據任務和ETL:我們需要收集、移動、儲存、准備、規范化、矢量話日誌。時間跨度的長短是必須被規定好的。數據的轉化需要花費一些功夫,這是由於JSON日誌、文本日誌、還有一些非連續標注模式都必須被識別並且轉化為數值數組。DataVec能夠幫助進行轉化和規范化數據。在開發機器學習訓練模型時,數據需要分為訓練集和測試集。
訓練神經網路
神經網路的初始訓練需要在訓練數據集中進行。
在第一次訓練的時候,你需要調整一些超參數以使模型能夠實現在數據中學習。這個過程需要控制在合理的時間內。關於超參數我們將在之後進行討論。在模型訓練的過程中,你應該以降低錯誤為目標。
但是這可能會出現神經網路模型過度擬合的風險。有過度擬合現象出現的模型往往會在訓練集中的很高的分數,但是在遇到新的數據時就會得出錯誤結論。用機器學習的語言來說就是它不夠通用化。Deeplearning4J提供正則化的工具和「過早停止」來避免訓練過程中的過度擬合。
神經網路的訓練是最花費時間和耗費硬體的一步。在GPUs上訓練能夠有效的減少訓練時間,尤其是做圖像識別的時候。但是額外的硬體設施就帶來多餘的花銷,所以你的深度學習的框架必須能夠有效的利用硬體設施。Azure和亞馬遜等雲服務提供了基於GPU的實例,神經網路還可以在異構集群上進行訓練。
創建模型
Deeplearning4J提供ModelSerializer來保存訓練模型。訓練模型可以被保存或者是在之後的訓練中被使用或更新。
在執行異常檢測的過程中,日誌文件的格式需要與訓練模型一致,基於神經網路的輸出結果,你將會得到是否當前的活動符合正常網路行為預期的結論。
代碼示例
遞歸神經網路的結構應該是這樣子的:
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder(
.seed(123)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).iterations(1)
.weightInit(WeightInit.XAVIER)
.updater(Updater.NESTEROVS).momentum(0.9)
.learningRate(0.005)
.gradientNormalization(GradientNormalization.ClipElementWiseAbsoluteValue)
.(0.5)
.list()
.layer(0, new GravesLSTM.Builder().activation("tanh").nIn(1).nOut(10).build())
.layer(1, new RnnOutputLayer.Builder(LossFunctions.LossFunction.MCXENT)
.activation("softmax").nIn(10).nOut(numLabelClasses).build())
.pretrain(false).backprop(true).build();
MultiLayerNetwork net = new MultiLayerNetwork(conf);
net.init();
下面解釋一下幾行重要的代碼:
.seed(123)
隨機設置一個種子值對神經網路的權值進行初始化,以此獲得一個有復驗性的結果。系數通常都是被隨機的初始化的,以使我們在調整其他超參數時仍獲得一致的結果。我們需要設定一個種子值,讓我們在調整和測試的時候能夠用這個隨機的權值。
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).iterations(1)
決定使用哪個最優演算法(在這個例子中是隨機梯度下降法)來調整權值以提高誤差分數。你可能不需要對這個進行修改。
.learningRate(0.005)
當我們使用隨機梯度下降法的時候,誤差梯度就被計算出來了。在我們試圖將誤差值減到最小的過程中,權值也隨之變化。SGD給我們一個讓誤差更小的方向,這個學習效率就決定了我們該在這個方向上邁多大的梯度。如果學習效率太高,你可能是超過了誤差最小值;如果太低,你的訓練可能將會永遠進行。這是一個你需要調整的超參數。
B. 【閱讀筆記】改進卷積神經網路的14個小技巧
原文: https://mp.weixin.qq.com/s/Lh_lJNvV9BGhc6no2ln-_g
原題目誤導性太大
1)架構要遵循應用
你也許會被 Google Brain 或者 DeepMind 這些奇特的實驗室所發明的那些耀眼的新模型所吸引,但是其中許多在你的用例或者業務環境中要麼是不可能實現,要麼是實現起來非常不現實。你應該使用對你的特定應用最有意義的模型,這種模型或許比較簡單,但是仍然很強大,例如 VGG。
2)網路路徑的激增
每年的 ImageNet Challenge 的冠軍都會使用比上一屆冠軍更加深層的網路。從 AlexNet 到 Inception,再到 ResNet,Smith 注意到了「網路中路徑數量倍增」的趨勢,並且「ResNet 可以是不同長度的網路的指數集合」。
3)爭取簡單
然而,更大的並不一定是更好的。在名為「Bigger is not necessarily better」的論文中,Springenberg 等人演示了如何用更少的單元實現最先進的結果。參考:https://arxiv.org/pdf/1412.6806.pdf
4)增加對稱性
無論是在建築上,還是在生物上,對稱性被認為是質量和工藝的標志。Smith 將 FractalNet 的優雅歸功於網路的對稱性。
5)金字塔式的形狀
你也許經常在表徵能力和減少冗餘或者無用信息之間權衡。卷積神經網路通常會降低激活函數的采樣,並會增加從輸入層到最終層之間的連接通道。
6)過度訓練
另一個權衡是訓練准確度和泛化能力。用類似 drop-out 或者 drop-path 的方法進行正則化可以提高泛化能力,這是神經網路的重要優勢。請在比你的實際用例更加苛刻的問題下訓練你的網路,以提高泛化性能。
7)全面覆蓋問題空間
為了擴展你的訓練數據和提升泛化能力,請使用雜訊和數據增強,例如隨機旋轉、裁剪和一些圖像操作。
8)遞增的特徵構造
隨著網路結構越來越成功,它們進一部簡化了每一層的「工作」。在非常深層的神經網路中,每一層僅僅會遞增的修改輸入。在 ResNets 中,每一層的輸出和它的輸入時很相似的,這意味著將兩層加起來就是遞增。實踐中,請在 ResNet 中使用較短的跳變長度。
9)標准化層的輸入
標准化是另一個可以使計算層的工作變得更加容易的方法,在實踐中被證明可以提升訓練和准確率。批量標准化(batch normalization)的發明者認為原因在於處理內部的協變數,但是 Smith 認為,「標准化把所有層的輸入樣本放在了一個平等的基礎上(類似於一種單位轉換),這允許反向傳播可以更有效地訓練」。
10)輸入變換
研究表明,在 Wide ResNets 中,性能會隨著連接通道的增加而增強,但是你需要權衡訓練代價與准確度。AlexNet、VGG、Inception 和 ResNets 都在第一層使用了輸入變換以讓輸入數據能夠以多種方式被檢查。
11)可用的資源決指引著層的寬度
然而,可供選擇的輸出數量並不是顯而易見的,這依賴於你的硬體能力以及期望的准確度。
12)Summation Joining
Summation 是一種常用的合並分支的方式。在 ResNets 中,使用總和作為連接的機制可以讓每一個分支都能計算殘差和整體近似。如果輸入跳躍連接一直存在,那麼 summation 會讓每一層學到正確地東西(例如與輸入的差別)。在任何分支都可以被丟棄的網路(例如 FractalNet)中,你應該使用這種方式類保持輸出的平滑。
13)下采樣變換
在池化的時候,利用級聯連接(concatenation joining)來增加輸出的數量。當使用大於 1 的步長時,這會同時處理連接並增加連接通道的數量。
14)用於競爭的 Maxout
Maxout 被用在你只需要選擇一個激活函數的局部競爭網路中。使用求和以及平均值會包含所有的激活函數,所以不同之處在於 maxout 只選擇一個「勝出者」。Maxout 的一個明顯的用例是每個分支具有不同大小的內核,而 Maxout 可以包含尺度不變性。
1)使用調優過的預訓練網路
「如果你的視覺數據和 ImageNet 相似,那麼使用預訓練網路會幫助你學習得更快」,機器學習公司 Diffbot 的 CEO Mike Tung 解釋說。低水平的卷積神經網路通常可以被重復使用,因為它們大多能夠檢測到像線條以及邊緣這些模式。將分類層用你自己的層替換,並且用你特定的數據去訓練最後的幾個層。
2)使用 freeze-drop-path
Drop-path 會在訓練的迭代過程中隨機地刪除一些分支。Smith 測試了一種相反的方法,它被稱為 freeze-path,就是一些路徑的權重是固定的、不可訓練的,而不是整體刪除。因為下一個分支比以前的分支包含更多的層,並且正確的內容更加容易近似得到,所以網路應該會得到更好的准確度。
3)使用循環的學習率
關於學習率的實驗會消耗大量的時間,並且會讓你遇到錯誤。自適應學習率在計算上可能是非常昂貴的,但是循環學習率不會這樣。使用循環學習率(CLR)時,你可以設置一組最大最小邊界,在邊界范圍內改變學習率。Smith 甚至還在論文《Cyclical Learning Rates for Training Neural Networks》中提供了計算學習率的最大值和最小值的方法。參考:https://arxiv.org/pdf/1506.01186.pdf
4)在有雜訊的標簽中使用 bootstrapping
在現實中,很多數據都是混亂的,標簽都是主觀性的或者是缺失的,而且預測的對象可能是訓練的時候未曾遇到過的。Reed 等人在文章《TRAINING DEEP NEURAL NETWORKS ON NOISY LABELS WITH BOOTSTRAPPING》中描述了一種給網路預測目標注入一致性的方法。直觀地講,這可以奏效,通過使網路利用對環境的已知表示(隱含在參數中)來過濾可能具有不一致的訓練標簽的輸入數據,並在訓練時清理該數據。參考:https://arxiv.org/pdf/1412.6596
5)採用有 Maxout 的 ELU,而不是 ReLU
ELU 是 ReLU 的一個相對平滑的版本,它能加速收斂並提高准確度。與 ReLU 不同,ELU 擁有負值,允許它們以更低的計算復雜度將平均單位激活推向更加接近 0 的值,就像批量標准化一樣參考論文《FAST AND ACCURATE DEEP NETWORK LEARNING BY EXPONENTIAL LINEAR UNITS (ELUS)》,https://arxiv.org/pdf/1511.07289.pdf。如果您使用具有全連接層的 Maxout,它們是特別有效的。
C. 神經網路,流形和拓撲
本文翻譯自colah的博客中的文章《Neural Networks, Manifolds, and Topology》
鏈接:http://colah.github.io/posts/2014-03-NN-Manifolds-Topology/
發布於2014年4月6日
關鍵詞:拓撲,神經網路,深度學習,流形假設(manifold hypothesis)
最近,深度神經網路給人們帶來很大的振奮,引起了極大的興趣,因為其在像計算機視覺等領域中取得的突破性成果。[1]
但是,人們對其仍存在一些擔憂。一個是要真正理解一個神經網路在做什麼是一件十分具有挑戰的事情。如果一個人將其訓練得很好,它可以取得高質量的結果,但是要理解其是如何做到這一點很難。如果網路出現故障,很難了解哪裡出現了問題。
雖然,總體上來說要理解深度神經網路的行為具有挑戰性,但事實證明,探索低維深度神經網路要容易得多,低維深度神經網路是指每層中只有少量神經元的網路。事實上,我們可以創建可視化來完全理解這種網路的行為和訓練過程。這種觀點將使我們能夠更深入地了解神經網路的行為,並觀察到神經網路和一個稱為拓撲的數學領域之間的聯系。
從中可以得到許多有趣的東西,包括能夠對某些特定數據集進行分類的神經網路復雜度的基本下界。
讓我們從一個非常簡單的數據集開始,在平面上有兩條曲線。網路將學習把點歸類為屬於一個或另一個。
對於這個問題,可視化神經網路行為的明顯方法 - 或者任何分類演算法 - 就是簡單地看一下它如何對每個可能的數據點進行分類。
我們將從最簡單的神經網路類別開始,只有一個輸入層和一個輸出層。這樣的網路只是試圖通過用直線劃分它們來分離這兩類數據。
那種網路不是很有趣。現代神經網路通常在其輸入和輸出之間具有多個層,稱為「隱藏」層。至少有一個。
和前面一樣,我們可以通過查看它對域中不同點的劃分來可視化該網路的行為。它使用比直線更復雜的曲線將數據分離。
對於每一層,網路都會轉換數據,創建一個新的表示。[2] 我們可以查看每個表示中的數據以及網路如何對它們進行分類。當我們到達最終表示時,網路將只繪制一條穿過數據的線(或者,在更高維度下,繪制一個超平面)。
在之前的可視化中,我們以「原始」表示形式查看了數據。當我們看輸入層時,你可以想到這一點。現在我們將在第一層轉換後查看它。你可以把它想像成我們在看隱藏層。
每個維度對應於層中神經元的發射。
在上一節中概述的方法中,我們通過查看與每個層對應的表示來學習理解網路。這給了我們一個離散的表示序列。
棘手的部分是理解我們如何從一個到另一個。值得慶幸的是,神經網路層具有很好的屬性,使這很容易實現。
在神經網路中使用各種不同類型的層。我們將討論tanh(雙曲正切)層作為一個具體示例。 tanh層 tanh(Wx + b) 包括:
1. 經過「權重」矩陣 W 的線性變換
2. 經過矢量 b 的平移
3. 點式地應用tanh。
我們可以將其視為一個連續的轉換,如下所示:
其他標准層的過程大致相同,包括仿射變換,然後逐點應用單調激活函數。
我們可以應用這種技術來理解更復雜的網路。例如,以下網路使用四個隱藏層對兩個略微糾纏的螺旋進行分類。隨著時間的推移,我們可以看到它從「原始」表示轉變為它為了對數據進行分類而學到的更高級別的表示。雖然螺旋最初是纏繞的,但最終它們是線性可分的。
另一方面,以下網路也使用多個層,無法對兩個更糾纏的螺旋進行分類。
值得明確指出的是,這些任務只是有些挑戰,因為我們使用的是低維神經網路。如果我們使用更廣泛的網路,所有這一切都會非常容易。
(Andrej Karpathy基於ConvnetJS做了一個很好的演示,它允許您通過這種對訓練的可視化來互動式地探索網路!)
每一層都伸展並占據空間,但它永遠不會削減,折斷或折疊它。直覺上,我們可以看到它保留了拓撲屬性。例如,如果一個集合之前是連通的那其之後也是連通的(反之亦然)。
像這樣不會影響拓撲的變換,稱為同胚。在形式上,它們是雙向連續函數的雙射。
定理 :如果權重矩陣W是非奇異的,則具有 N 個輸入和 N 個輸出的層是同胚。 (雖然需要注意域和范圍。)
證明 :讓我們一步一步考慮:
1. 假設W具有非零行列式。然後它是具有線性逆的雙射線性函數。線性函數是連續的。因此,乘以 W 是同胚。
2. 平移是同胚的。
3. tanh(和sigmoid和softplus但不是ReLU)是具有連續逆的連續函數。如果我們對我們考慮的域和范圍保持謹慎,它們就是雙射的。逐點應用它們是同胚。
因此,如果 W 具有非零行列式,則我們的層是同胚。 ∎
如果我們將這些層中任意多個組合在一起,這個結果就會繼續存在。
考慮一個二維數據集,有兩個類A和B⊂R2:
A={x|d(x,0)<1/3}
B={x|2/3<d(x,0)<1}
聲明 :如果沒有具有3個或更多隱藏單位的層,神經網路就無法對此數據集進行分類,無論深度如何。
如前所述,使用S形單元或softmax層進行分類等同於嘗試找到在最終表示中分離A和B的超平面(或在這種情況下為線)。由於只有兩個隱藏單元,網路在拓撲上無法以這種方式分離數據,並且註定要在此數據集上失敗。
在下面的可視化中,我們觀察到網路訓練時的隱藏表示以及分類線。正如我們所看到的那樣,它正在努力學習如何做到這一點。
最終,它會被拉入一個相當低效的局部最小值。 雖然,它實際上能夠達到~ 80% 的分類准確度。
這個例子只有一個隱藏層,但無論如何都會失敗。
證明 :每一層都是同胚,或者層的權重矩陣具有行列式0.如果它是一個同胚,A仍然被B包圍,並且一條線不能將它們分開。 但是假設它有一個行列式為0:那麼數據集會在某個軸上折疊。 由於我們處理與原始數據集同胚的某些東西,A被B包圍,並且在任何軸上折疊意味著我們將有一些A和B混合的點並且變得無法區分。∎
如果我們添加第三個隱藏單元,問題就變得微不足道了。 神經網路學習以下表示:
通過這種表示,我們可以使用超平面分離數據集。
為了更好地了解正在發生的事情,讓我們考慮一個更簡單的1維數據集:
A=[−1/3,1/3]
B=[−1,−2/3]∪[2/3,1]
如果不使用兩個或更多隱藏單元的層,我們就無法對此數據集進行分類。 但是如果我們使用有兩個單元的層,我們學會將數據表示為一條很好的曲線,允許我們用一條線來將不同的類分隔開來:
發生了什麼? 一個隱藏單元在x > -1/2時學會開火,一個在x > 1/2時學會開火。當第一個開火但第二個沒開火時,我們知道我們在A中。
這與現實世界的數據集,比如圖像數據有關嗎? 如果你真的認真對待流形假設,我認為值得考慮。
流形假設是自然數據在其嵌入空間中形成低維流形。 理論上[3]和實驗上[4]都有理由認為這是真的。 如果你相信這一點,那麼分類演算法的任務就是從根本上分離出一堆糾結的流形。
在前面的例子中,一個類完全包圍了另一個類。 然而,狗圖像流形似乎不太可能被貓圖像流形完全包圍。 但是,正如我們將在下一節中看到的那樣,還有其他更合理的拓撲情況可能仍然存在問題。
另一個值得考慮的有趣數據集是兩個鏈接的圓環, A 和 B .
與我們考慮的先前數據集非常相似,如果不使用n+1維,即第4維,則無法分離此數據集。
鏈接是在結理論中研究的,這是一個拓撲領域。 有時當我們看到一個鏈接時,它是否是一個非鏈接(一堆東西糾結在一起,但可以通過連續變形分開)並不是很明顯。
如果使用僅有3個單元的層的神經網路可以對其進行分類,那麼它就是非鏈接。 (問題:理論上,所有非鏈接是否都可以被只有3個單元的網路進行分類?)
從這個結的角度來看,我們對神經網路產生的連續可視化的表示不僅僅是一個很好的動畫,它還是一個解開鏈接的過程。在拓撲中,我們將其稱為原始鏈接和分離鏈接之間的環境同位素(ambient isotopy)。
形式上,流形A和B之間的環境同位素是連續函數F:[0,1]×X→Y,使得每個Ft是從X到其范圍的同胚,F0是恆等函數,F1將A映射到B。也就是說,Ft連續地從A向自身映射轉換到A向B映射。
定理 :在輸入和網路層表示之間存在環境同位素,如果:a) W 不是奇異的,b)我們願意置換隱藏層中的神經元,並且c)存在多於1個隱藏單元。
證明 :同樣,我們分別考慮網路的每個階段:
1. 最難的部分是線性變換。 為了使這成為可能,我們需要 W 有一個正的行列式。 我們的前提是它不是零,如果它是負的,我們可以通過切換兩個隱藏的神經元來翻轉符號,那麼我們可以保證行列式是正的。 正行列式矩陣的空間是路徑連通的,因此存在 p :[ 0,1 ] → GLn (R)5,使得 p(0) = Id 且 p(1) = W 。 我們可以用函數 x → p(t)x 連續地從恆等函數轉換到 W 變換,在每個時間點 t 將 x 乘以連續轉換矩陣 p(t) 。
2. 我們可以用函數 x → x + tb 不斷地從恆等函數轉換到b轉換。
3. 通過函數: x → (1- t)x +tσ(x) ,我們可以不斷地從恆等函數過渡到σ的逐點使用。∎
我想可能有興趣自動發現這種環境同位素並自動證明某些鏈接的等價性,或某些鏈接是可分離的。知道神經網路能否擊敗現有技術水平將會很有趣。
(顯然確定結是否平凡是NP問題。這對神經網路來說不是好兆頭。)
到目前為止我們談到的那種鏈接似乎不太可能出現在現實世界的數據中,但是有更高的維度的拓展。在現實世界的數據中可能存在這樣的事情似乎是合理的。
鏈接和結是一維流形,但我們需要4個維度才能解開所有這些。類似地,人們可能需要更高維度的空間以能夠解開n維流形。所有n維流形都可以在 2n + 2 維中解開。[6]
(我對結理論知之甚少,真的需要更多地了解有關維度和鏈接的知識。如果我們知道流形可以嵌入到n維空間中,而不是流形的維數,我們有什麼限制? )
一個神經網路要做的自然的事情,非常簡單的路線,是試圖將流形分開,並盡可能地拉伸纏繞的部分。 雖然這不會接近真正的解決方案,但它可以實現相對較高的分類准確度並且是誘人的局部最小值。
它會在它試圖拉伸的區域中表現為 非常高的衍生物 (very high derivatives)和近乎不連續性。我們知道這些事情會發生.[7] 在數據點處懲罰層的衍生物的收縮懲罰是對抗這種情況的自然方式.[8]
由於這些局部極小值從試圖解決拓撲問題的角度來看是絕對無用的,拓撲問題可能提供了探索解決這些問題的良好動機。
另一方面,如果我們只關心實現良好的分類結果,似乎我們可能不在乎。如果數據流形的一小部分被另一個流形鉤住,對我們來說這是一個問題嗎?盡管存在這個問題,似乎我們也應該能夠獲得主觀上來看不錯的分類結果。
(我的直覺是試圖欺騙這個問題是一個壞主意:很難想像它不會是一個死胡同。特別是在一個優化問題中,局部最小值是一個大問題,選擇一個架構,不能真正解決問題似乎是表現不佳的秘訣。)
我對標准神經網路層的思考越多 - 即是,通過仿射變換後跟一個逐點激活函數 - 我感覺更加失去理智。 很難想像這些對於操縱流形真的很有益。
或許有一種非常不同的層可以用來組成更傳統的層?
我自然想到的是學習一個矢量場,這個矢量場帶有我們想要改變流形的方向:
然後根據它來變形空間:
人們可以在固定點學習矢量場(只需從訓練集中取一些固定點作為錨點)並以某種方式進行插值。 上面的矢量場的形式如下:
其中v0和v1是向量,f0(x)和f1(x)是n維高斯。 這受到徑向基函數的啟發。
我也開始思考線性可分性對於神經網路的需求可能是巨大的,雖然可能是不合理的。在某些方面,感覺自然要做的就是使用k近鄰(k-NN)。然而,k-NN的成功在很大程度上取決於它對數據進行分類的表示,因此在k-NN能夠很好地工作之前需要一個好的表示。
作為第一個實驗,我訓練了一些MNIST網路(兩層卷積網,沒有丟失),達到了約1%的測試誤差。然後我丟棄了最終的softmax層並使用了k-NN演算法。我能夠始終如一地將測試誤差降低0.1-0.2%。
盡管如此,還是覺得哪裡有些問題。網路仍在嘗試進行線性分類,但由於我們在測試時使用k-NN,因此能夠從錯誤中恢復一點。
由於1/距離的加權,k-NN在它所作用的表示方面是可微的。因此,我們可以直接為k-NN分類訓練一個網路。這可以被認為是一種「最近鄰」層,可以作為softmax的替代品。
我們不希望為每個小批量提供整個訓練集,因為這在計算上非常昂貴。我認為一個很好的方法是根據小批量的其他元素的類別對小批量的每個元素進行分類,給每個元素一個權重1 /(與分類目標的距離)。[9]
遺憾的是,即使使用復雜的架構,使用k-NN也只會降低5-4%的測試錯誤 - 使用更簡單的架構會導致更糟糕的結果。但是,我花了很少的精力去調整超參數。
盡管如此,我在美學上仍然喜歡這種方法,因為看起來我們「要求」網路做的事情要合理得多。我們希望相同流形的點比其他點更接近,而流形可以通過超平面分離。這應該對應於擴張不同類別流形之間的空間並使各個流形收縮。感覺就像簡化。
數據的拓撲屬性(例如鏈接)可能使得無法使用低維網路線性分離類,無論深度如何。即使在技術上可行的情況下,例如螺旋,這樣做也是非常具有挑戰性的。
為了使用神經網路准確地對數據進行分類,有時需要寬層。此外,傳統的神經網路層似乎不能很好地表示對流形的重要操作;即使我們巧妙地手工設置權重,緊湊地表示我們想要的變換也是一項挑戰。新的層,特別是受機器學習的流形觀點驅動的,可能是有用的補充。
(這是一個正在開發的研究項目。它是作為公開進行研究的實驗而發布的。我很高興收到你對這些想法的反饋:你可以內聯或最後發表評論。對於拼寫錯誤,技術錯誤或你想要的澄清看到添加,我們鼓勵你在github上發出pull請求。)
感謝Yoshua Bengio, Michael Nielsen, Dario Amodei, Eliana Lorch, Jacob Steinhardt, and Tamsyn Waterhouse的評論和鼓勵。
1. This seems to have really kicked off with Krizhevsky et al. , (2012) , who put together a lot of different pieces to achieve outstanding results. Since then there』s been a lot of other exciting work. ↩
2. These representations, hopefully, make the data 「nicer」 for the network to classify. There has been a lot of work exploring representations recently. Perhaps the most fascinating has been in Natural Language Processing: the representations we learn of words, called word embeddings, have interesting properties. See Mikolov et al. (2013) , Turian et al. (2010) , and, Richard Socher』s work . To give you a quick flavor, there is a very nice visualization associated with the Turian paper. ↩
3. A lot of the natural transformations you might want to perform on an image, like translating or scaling an object in it, or changing the lighting, would form continuous curves in image space if you performed them continuously. ↩
4. Carlsson et al. found that local patches of images form a klein bottle. ↩
5. GLn(R)is the set of invertible n×n matrices on the reals, formally called the general linear group of degree n. ↩
6. This result is mentioned in Wikipedia』s subsection on Isotopy versions . ↩
7. See Szegedy et al. , where they are able to modify data samples and find slight modifications that cause some of the best image classification neural networks to misclasify the data. It』s quite troubling. ↩
8. Contractive penalties were introced in contractive autoencoders. See Rifai et al. (2011) . ↩
9. I used a slightly less elegant, but roughly equivalent algorithm because it was more practical to implement in Theano: feedforward two different batches at the same time, and classify them based on each other. ↩
D. 人工神經網路BP演算法源代碼與演示程序怎麼用
在matlab里建立一個.m的M文件,把代碼輸進去,保存,運行就可以了。
演示程序是在command 里打demo就可以了找到了 . 你郵箱多少,我只有簡單的BP神經網路程序。
E. 神經網路、流形和拓撲
譯者:樹石
最近,由於在諸如計算機視覺領域取得了突破性成果,深層神經網路引起了廣泛的關注和興趣。
然而,該領域仍然存在一些顧慮。比如, 要了解神經網路能夠做什麼相當具有挑戰性 。如果一個網路被訓練得很好,輸出高品質的結果,但了解它是如何做到的具有挑戰性。如果網路出現故障,也很難理解什麼地方出了錯。
雖然通常理解深層神經網路的行為比較困難, 探索低維度深層神經網路相對容易的多 ——在每一層只有幾個神經元的網路。事實上,我們可以通過創建可視化效果來理解網路的行為和對網路的培訓。這種方法將讓我們 獲取對神經網路行為的深層直覺,並觀察到神經網路和拓撲學之間的聯系 。
另外,還探討了一些有趣的事情,包括對某些數據集進行分類的神經網路的最低復雜性。
讓我們從一個非常簡單的數據集開始:在一個平面上的兩條曲線。該網路將學習如何將線上的點歸類為這一個還是另外一個。
將神經網路(或任何分類演算法)的行為可視化,顯而易見的方法是簡單地看它是如何對每一個可能的數據點進行分類。
我們將先從最簡單的神經網路開始,只有一個輸入層和一個輸出層的網路。這樣的網路只是試圖通過畫一條線將兩個類數據的分離。
諸如此類的網路不是很有趣。現代神經網路一般在輸入和輸出之間,具有稱為「隱藏」層的多個層次。至少包含一個隱藏層。
與以前一樣,我們可以通過查看它對其領域不同點進行的處理來觀察這個網路的行為。數據分割通過一條曲線來完成,而不是直線。
通過神經網路的每一層,數據被轉換,創建了一個新的 表示 (represention)。我們可以看一下在這些表示中的數據以及網路是如何劃分他們的。當我們到達最後一層的表示時,網路只需要繪制一條線(或者,在更高維度里繪制一個超平面)。
在前面的可視化中,我們看到其「原始」表示的數據,你可以將其視為輸入層。現在我們將看看經過第一層轉化後,你可以認為這是我們看到了隱藏層。
每個維度對應於該層中神經元的興奮。
在上一節中所概述的方法,我們知道通過查看每層的表示來了解網路。這給了我們一個離散的表示列表。
最棘手的部分是了解我們是如何從一個表示到另一個的。值得慶幸的是,神經網路層具有很好的性能,使這一點變得很容易。
神經網路由多種不同類型的層構成。我們將談論一個具體的例子:雙曲正切層(tanh)。一個雙曲正切層tanh(Wx+b)由以下組成:
我們可以觀察到這是一個連續變換,具體如下:
這個故事和其它標准層大體相同,由一個映射變換之後單調激活函數的逐點應用。
我們可以用這種技術來了解更復雜的網路。例如,下面的網路劃分兩個被略微纏結的螺旋,使用四個隱藏層。隨著時間的推移,我們可以看到它的「原始」表示轉移到更高層次為了對數據進行分類。而螺旋最初是糾結的,最終他們是線性可分的。
另一方面,以下的網路,也是使用多個層,分類兩個螺旋沒有成功,反而更加纏結。
這里值得明確指出,這些任務將變得有些困難,如果我們使用的是低維神經網路。如果我們使用更廣泛的網路,這一切都將是相當容易的。
( Andrei Karpathy有 很好的演示 基於ConvnetJS,讓您可以互動式地瀏覽網路,就像上面的這種可視化培訓! )
每一層都會拉伸和擠壓空間,但它永遠不會切割、斷裂和褶皺它。直觀地說,我們可以看到它保留了拓撲性質。例如,一組數據將在轉化後保持連接,如果它之前是連接的(反之亦然)。
這樣的轉換,不影響拓撲結構,被稱為同胚。在形式上,他們是連續函數的雙向映射。
定理 :具有N個輸入和N個輸出的層是同胚,如果權重矩陣W是非奇異的。(雖然需要小心它的值域和范圍。)
證明 :讓我們一步步考慮:
因此,如果W所有因子都是非零的,我們的層就是同胚的。∎
這一結果始終正確,如果我們將任意多個這些層組合在一起。
考慮包含兩個類的二維數據集
![][01]
[01]: http://latex.codecogs.com/svg.latex?,A,B subsetmathbb{R}^2
A = {x | d(x,0) < 1/3}
B = {x | 2/3 < d(x,0) < 1}
如前面提到的,用一個S形函數或SOFTMAX層分類相當於試圖找到一個超平面(或在這種情況下是一條線)在最終表示中分隔A與B。只有兩個隱藏層的網路對於分離這組數據在拓撲上是無能的,並註定要失敗。
在下面的可視化圖中,我們觀察到網路訓練隱藏的表示,通過試圖使用一條直線來分類。我們可以看到,它在努力學習某種方式來做到這一點是不斷掙扎而且困難重重。
最後,它被拉到一個相當低效的擬合。雖然它實際上能夠實現〜80%分類精度。
這個例子只有一個隱藏層,但無論如何它都會失敗。
證明 :要麼每層是一個同胚,要麼該層的權重矩陣具有0因子。如果該層是同胚的,A被B所環繞,一個直線不能將它們分開。但是,假設它具有一個0因子:那麼數據集將在某些軸上崩塌。因為我們正在處理的東西同胚於原始數據集,A被B所包圍,在任一軸崩塌於意味著我們將有一些A中的點和B中的點混合,從而無法完成A與B的區分。∎
如果我們增加第三個隱藏層,問題就變得微不足道。神經網路學習以下表示:
用這個表示,我們可以用一個超平面分開數據集。
為了更好的理解這是怎麼做到的,讓我們考慮一個更簡單的一維數據集:
![][02]
[02]: http://latex.codecogs.com/svg.latex?,A=[- frac{1}{3},,frac{1}{3}]
![][03]
[03]: http://latex.codecogs.com/svg.latex?,B=[-1,- frac{2}{3}]cup[frac{2}{3},1]
如果不使用兩個或多個隱藏單元層,我們不能將此數據集進行分類。但是,如果我們使用一個帶有兩層的網路,我們就學會將數據轉化成一個很好的曲線,讓我們能用一條線將數據分開:
發生了什麼?一個隱藏單元學習當x>-1/2時興奮,另一個單元學習當x>1/2時興奮。當第一個興奮,而不是第二個時,我們知道數據屬於A。
這個假說和現實世界的數據集相關嗎,比如圖像數據?如果你認真對待流形假說,我覺得他值得思考。
流形假說是指自然數據在它的嵌入空間構成了較低維度的數據流形。同時具有理論和實驗的理由相信這一假說是真的。如果你相信這一點,那麼分類演算法的任務是從根本上分離一堆糾結的流形。
在前面的例子中,一個類完全被另一個類包圍。然而,這似乎並不可能,比如狗的圖像流形完全被貓的圖像流形包圍。因為我們將在下一節中看到其他更合理的拓撲情況。
另一個有趣的數據集要考慮的是兩個鏈接的tori,A和B。
就像之前的數據集,這個數據不能被分離,如果不使用n+1維,即4個維度。
鏈接在結點理論(knot theory)中被討論,拓撲學的一個領域。有時,當我們看到一個鏈接,並不能一眼看出它是否真正相連(一堆被纏結在一起的事情,但可以通過連續變形分開)。
如果僅僅使用3個層次的神經網路就能夠對其進行分類,那麼它就是一個未鏈接(unlink)。(問:理論上是否能將所有未鏈接都通過只有3個層次的網路進行分類?)
從這個結的角度看,我們通過神經網路產生的連續可視化不僅僅是一個漂亮的動畫,它是解開鏈接的程序。在拓撲學中,我們把它稱為原始鏈接和分離環之間一個環境同痕(an ambient isotopy)。
形式上,流形A和B之間的一個環境同痕是一個連續函數F:[0,1]× X→Y,使得每個Ft是一個從X到它自己范圍的同胚,F0是一個標識函數,並F1是從A到B的一個映射。也就是,Ft是從A到自身的映射到從A到B的映射的連續轉換。
定理 :在輸入和網路層之間具有環境同痕,如果:
證明 :同樣,我們分別考慮網路的每個階段:
我想這也許是十分有趣的,通過程序自動發現這樣的環境同痕並自動證明某些鏈接的等價性,或者某些環節是可分離的。這將很有趣知道,如果神經網路是否可以各種情況。
(顯然,確定結點是否重要是一個NP,這不太適用於神經網路。)
我們已經談到的這類鏈接,到目前為止似乎不太可能是現實世界的數據,但他們是更高維的生成。這似乎是合理的。
鏈接和結點是1維流形,但我們需要4個維度才能夠解開他們。類似地,可能需要更高維度的空間,以便能夠解開n維流形。所有n維流形可在2n+2維度上解開。
(我對於結點理了解不多,確實需要更多地了解維度和鏈接。如果我們知道一個流形可以被嵌入到n維空間,而不是流形的維度,我們有什麼限制? )
很自然的想法,一個神經網路試圖直接將流形從糾結盡可能薄的部分拉出。雖然這不會在任何情況下都是一個好的解決方案,但是大多情況它可以實現較高的分類准確率,到達一個誘人的最低點(local miminum)。
它試圖拉伸具有高延展性的空間,並銳化靠近中斷處。我們知道這些事情發生。壓縮的處罰,在對數據點衍生層的處罰,都是很自然的做法。
由於這些局部最小點對於解決這種拓撲問題完全無用,拓撲問題值得很好的探索。
在另一方面,如果我們只關心取得了良好的分類結果,好像我們可能並不關心。如果很小的一個數據流形的點陷入另一個流形,會是一個問題嗎?看起來我們應該能夠得到很好的分類結果,盡管有這個問題。
(我的直覺是,像這樣欺騙自己是一個壞主意:這是很難想像它不會是死路一條。特別是,針對一個局部最小很重要的優化問題,選擇這種方式不能真正解決問題,這似乎是糟糕的表現。)
我越思考標準的神經網路層 - 即用映射變換後逐點激活功能 - 我就越不抱幻想。很難想像,他們能夠很好地操縱流形。
也許這可能是有意義的,我們採用一個非常不同的層,而不是傳統的神經網路層?
非常自然的感覺是,通過一個矢量場的學習,我們希望流形移動方向:
然後再對他變形空間:
人們可以學會在固定點的矢量場(只是需要從訓練集合選取一些固定點作為錨),並以某種方式介入。上面的矢量場的形式是:
![][04]
[04]: http://latex.codecogs.com/svg.latex?,F(x)= frac{v_0f_0(x)+v_1f_1(x)}{1+f_0(x)+f_1(x)}
其中,v0和v1是矢量,F0(X)和F1(X)是n維高斯函數。這一點來自於徑向基函數(radial basis functions)的靈感。
我也開始覺得線性可分可能是一個巨大的,也可能不合理的,神經網路的需求。在某些方面,非常自然的會想到使用K-近鄰(K-NN)。然而,K-NN的成功在很大程度上取決於它所分類的數據表示(represention),因此,人們在K-NN之前,需要一種良好的表示。
作為第一個實驗中,我訓練了一些MNIST網路(兩層卷積網,沒有下降現象)到達〜1%測試誤差。然後我放棄了最後的SOFTMAX層而使用K-NN演算法,我能夠始終如一地降低0.1-0.2%的測試誤差。
不過,這並不完全覺得是正確的事情。該網路還在試圖做線性分類,但由於我們使用K-NN測試,它能夠從它所犯的錯誤中恢復一些。
K-NN有區別於相對於它的網路層次,因為會用到(1 /距離值)加權。因此,我們可以直接訓練網路K-NN分類。這可以被認為是一種「k-NN」層替SOFTMAX。
我們不希望為每個小批量數據遍歷整個訓練集,因為這將非常消耗計算資源。我認為一個很好的辦法是根據小批次的其它元素對每個小批次的元素進行分類,賦予每一個元素(1 /從分類目標的距離)的權重。
可悲的是,即使有完善的體系結構,採用K-NN只下到5-4%檢測錯誤 - 使用簡單的架構會得到更壞的結果。不過,我已經很少把努力放在高維參數上了。
不過,我真的很喜歡這個方法,因為它好像就是我們「要求」網路運行的更加合理。我們希望在同一流形的點比其它的點更加接近,相對於由一個超平面被分離的其他流形。這相對需要拉伸不同類別流形之間的空間,同時收縮每一個流形。這感覺就像是在簡化問題。
具有拓撲性質的數據,例如鏈接,可能導致無法使用低維網路進行線性分類,無論深度有多大。即使在技術上是可能的情況下,例如螺旋,也是非常具有挑戰性的。
為了使神經網路准確的分類數據,多個層次有時是必要的 。此外,傳統的神經網路層似乎並不能很好的處理流形數據;即使我們巧妙的手工設置權重,想要緊湊的表達我們想要的轉換也是非常困難的。新建層次,特別使用流形相關的機器學習,可能是有用的補充。
(這是一個發展中的研究項目。相關研究信息會在網上公布。我會很高興聽聽您對這些想法的反饋:您可以發表評論。對於錯別字,技術錯誤,或任何澄清,我們鼓勵你發一個請求在GitHub上。)
致謝
謝謝Yoshua Bengio,邁克爾·尼爾森,達里奧 Amodei,埃利安娜洛奇,雅各布斯坦哈特和Tamsyn Waterhouse的意見和鼓勵。
F. 輕松體驗TensorFlow 第一個神經網路:基本分類(Part 1)
關於 Jupyter Notebook 的使用,可以參考如下鏈接,有詳細的步驟和截圖:
Jupyter Notebook神器-免費體驗來自微軟的Azure Notebook
基於Jupyter Notebook 快速體驗Python和plot()繪圖方法
基於Jupyter Notebook 快速體驗matplotlib.pyplot模塊中繪圖方法
TensorFlow 基本分類(basic classification)演示的完整代碼,可以訪問:
上述命令運行時間較長,請耐心等待。
pip list 命令用來查看當前環境下的Python 包,grep 命令用來查找和篩選。中間的豎線表示 pipe(管道),將pip list 命令的輸出作為 grep 命令的輸入。
pip 前面的感嘆號是cell 中運行 Linux 命令的方式,在命令行中運行則不需要加感嘆號。
上述命令的輸出,表示當前環境已經安裝好了 TensorFlow 包。如果沒有安裝,可以通過如下命令安裝:
安裝TensorFlow命令,說明如下:
本地安裝TensorFlow,截圖如下。
TensorFlow 安裝完成:
下面訓練了一個神經網路模型,來對服裝圖像進行分類,例如運動鞋和襯衫。需要使用tf.keras,這是一個用於在TensorFlow 中構建和訓練模型的高級API。
下面使用Fashion MNIST 數據集,其中包含了10個類別中共70,000張灰度圖像。圖像包含了低解析度(28 x 28像素)的單個服裝物品,圖片鏈接如下所示:
Fashion-MNIST是一個替代MNIST手寫數字集的圖像數據集。 它是由Zalando(一家德國的 時尚 科技 公司)旗下的研究部門提供。其涵蓋了來自10種類別的共7萬個不同商品的正面圖片。Fashion-MNIST的大小、格式和訓練集/測試集劃分與原始的MNIST完全一致。60000/10000的訓練測試數據劃分,28x28的灰度圖片。可以直接用它來測試你的機器學習和深度學習演算法性能,且不需要改動任何的代碼。
MNIST是 Mixed National Institute of Standards and Technology database 的簡寫。
下面使用60,000張圖像來訓練網路和10,000張圖像來評估網路模型學習圖像分類任務的准確程度。
可以直接從TensorFlow 使用Fashion MNIST,只需導入並載入數據。
載入數據集並返回四個NumPy數組:
圖像是28x28 NumPy數組,像素值介於0到255之間。labels是一個整數數組,數值介於0到9之間。
下面是圖像類別和標簽的對應關系:
每個圖像都映射到一個標簽。由於類別名稱不包含在數據集中,因此把他們存儲在這里以便在繪制圖像時使用:
以下顯示訓練集中有60,000個圖像,每個圖像表示為28 x 28像素:
訓練集中有 60000個標簽,並且每個標簽都是0-9 之間的整數。
測試集和訓練集類似,有10000個圖像和對應的10000個圖像標簽。
在訓練網路之前必須對數據進行預處理。 如果檢查訓練集中的第一個圖像,將看到像素值落在0到255的范圍內:
代碼說明:
plt.figure() 創建一個新的figure。
plt.colorbar() 方法用來顯示當前image 的顏色方案。
在發送到神經網路模型之前,我們將這些值縮放到0到1的范圍(歸一化處理)。為此,我們將像素值值除以255。重要的是,對訓練集和測試集要以相同的方式進行預處理:
顯示訓練集中的前25個圖像,並在每個圖像下方顯示類別名。驗證數據格式是否正確,我們是否已准備好構建和訓練網路。
代碼說明:
plt.xticks([])和plt.yticks([]) - 以空list 作為xticks() 方法的參數,查看數據集中圖像隱藏坐標軸。
plt.xlabel() 方法可以在 x 軸的下方顯示指定文本。
plt.subplot(5,5,1) 方法 - 表示5行5列共25個位置,最後一個參數1 表示Axes的位置,第一行的位置編號為:1-5,第二行的位置編號為:6-10,依此類推。
上述代碼遍歷了25 個位置(for i in range(25)),批量顯示多張圖。針對每一個位置,設置隱藏x和y軸,不顯示網關線(grid),在對應的位置顯示圖像以及類別(label)。
需要注意的地方:Axes 位置的起始值是1,不是常見的0。
對TensorFlow 深度學習有興趣的同學,可以訪問如下鏈接。
G. 初識卷積神經網路
按照上文中介紹的神經網路,如果處理一張圖片的話,參數有多大呢?假設圖像的大小為1200 * 1200,下一層的神經元個數為10^5,不難得出參數量為 1200 * 1200 * 10^5 = 1.44 * 10^12。可以看出一層的參數量就是很大了,如果再多加幾層,那參數量大的應該是超出了內存的承受范圍,這從研究和工程的角度都是不允許的。而且參數太多,很容易造成過擬合。
怎麼解決這個問題呢?經過研究,從稀疏連接、參數共享和平移不變性三個方面來進行改進。
可能有些人不懂這種稀疏連接是怎麼實現的?先來說說卷積操作,以一個二維矩陣為輸入(可以看作是一個單通道圖片的像素值),卷積產生的稀疏連接根本原因就是這塊的核函數,一般的核函數的大小遠小於輸入的大小。
以下圖例:卷積操作可以看做是一種滑窗法,首先,輸入維度是4×4,輸入中紅色部分,先和核函數中的元素對應相乘,就是輸出中左上角的元素值s1,即 s1 = a×k1+b×k2+e×k3+f×k4。
參數共享是指在一個模型的多個函數中使用相同的參數,它是卷積運算帶來的固有屬性。
在全連接中,計算每層的輸出時,權重矩陣中的元素只作用於某一個輸入元素一次;
而在卷積神經網路中,卷積核中的每一個元素將作用於每一個局部輸入的特定位置上。根據參數共享的思想,我們只需要學習一組參數集合,而不需要針對每一個位置的每一個參數來進行優化學習,從而大大降低了模型的存儲需求。
如果一個函數的輸入做了一些改變,那麼輸出也跟著做出同樣的改變,這就時平移不變性。
平移不變性是由參數共享的物理意義所得。在計算機視覺中,假如要識別一個圖片中是否有一隻貓,那麼無論這只貓在圖片的什麼位置,我們都應該識別出來,即就是神經網路的輸出對於平移不變性來說是等變的。
根據稀疏連接、參數共享和平移不變性三個思想,卷積核就應運而生了。看下圖,有個直觀的感受。
上圖就是在一個通道上做的卷積,但現實中,圖片一般是由3個通道構成(R\G\B),卷積核也由二維的平面生成了三維立體。具體的樣子如下圖:
如上圖所示,Filter W0 即為卷積核,其大小為(3 * 3 * 3),每個3*3的二維平面會和圖片的相應的通道進行卷積,3個通道的結果相加後加上統一的偏置b0,結果即為Output Volume 第一個通道的第一個位置的數。
從上圖還可以看出 Input Volume 四周加了0,這個0叫做padding,一般是為了卷積劃動的過程中包含原有的所有數;而多通道卷積核計算過程和卷積核計算過程,不太一樣的是多通道卷積核計算過程每次滑2下,這個滑動的距離叫做步長-stride。
所以通過輸入大小和卷積核大小,我們可以推斷出最終的結果的大小。比如上圖卷積核計算過程,輸入大小為5 * 5,卷積核為3 * 3,那麼卷積核在原圖上每次滑動一格,橫向滑3次,縱向也是3次,最終結果為 3 * 3。在多通道卷積核計算過程中,每次滑動為2格,橫向滑3次,縱向也是3次,最終結果也為 3*3。可以推斷出,最終大小的公式為:(輸入大小 - 卷積核大小)/ 滑動步長。
在卷積核計算過程,可以看出經過卷積後的大小變小了,那能不能經過卷積計算且大小不變呢?這里,引出了 padding 的另一個作用,保證輸入和輸出的大小一致。比方輸出的 5*5 加 padding,那麼四周就被0圍繞了,這時的輸入大小就變為7 * 7, 再經過 3 * 3的卷積後,按照上邊推斷出的公式,可以得出 最終的大小為 5 * 5,這時與輸入大小保持了一致。
池化層夾在連續的卷積層中間, 用於壓縮數據和參數的量,減小過擬合。
簡而言之,如果輸入是圖像的話,那麼池化層的最主要作用就是壓縮圖像。
池化層用的方法有Max pooling 和 average pooling,而實際用的較多的是Max pooling。下圖演示一下Max pooling。
對於每個2 * 2的窗口選出最大的數作為輸出矩陣的相應元素的值,比如輸入矩陣第一個2 * 2窗口中最大的數是1,那麼輸出矩陣的第一個元素就是1,如此類推。
全連接層的部分就是將之前的結果展平之後接到最基本的神經網路了。
根據上邊的介紹,可以得出,卷積核的通道數目和輸入的圖像的通道數目是保持一致的,而輸出的通道數目是和卷積核數目是一致的。這樣參數量可以得出,假設輸入的通道為5,卷積核大小為 3 * 3 ,輸出的通道數目為10,那麼參數量為:3 * 3 * 5 * 10,其中3 * 3 * 5是1個卷積核的參數個數,3 * 3 * 5 * 10 是 10個卷積核的參數個數,也就總共的參數個數。
在卷積中,滑動一次會經過多次的點乘,只經過一次的加法,所以加法的計算量可以忽略不計。其中,滑動一次會的點乘次數和卷積核的大小有關系,比方 3 * 3的卷積,則是經過了 3 * 3 = 9次點積。一共滑動多少次和輸出大小有關系,比方 輸出的結果也為 3 * 3,那麼就是滑動了9次。這樣就可以得出輸入和輸出單通道時計算量 3 * 3 * 3 * 3 = 81。那麼對於輸入多通道時,卷積核也需要增加相應的通道數目,此時應該在剛才的計算量上乘以通道的數目,得出輸入多通道的一個卷積核的計算量。這樣,對於輸出多通道,總的計算量則是乘以多個卷積核即可。
H. 神經網路從何而來
【嵌牛導讀】神經網路從何而來?這里說的『從何而來』,並不僅僅是從技術上去介紹一個方法的創造或發展,而更想探討方法背後所蘊含的思想基礎與演變之路。
【嵌牛鼻子】神經網路、深度學習
【嵌牛提問】神經網路的由來?
【嵌牛正文】深度學習與神經網路是近幾年來計算機與人工智慧領域最炙手可熱的話題了。為了蹭這波熱度,博主也打算分享一些自己的經驗與思考。第一篇文章想探討一個非常基礎的問題:神經網路從何而來?這里說的『從何而來』,並不僅僅是從技術上去介紹一個方法的創造或發展,而更想探討方法背後所蘊含的思想基礎與演變之路。
首先,需要為『神經網路』正一下名。在人工智慧領域,我們通常所說的神經網路(Neural Networks)全稱是人工神經網路(Artificial Neural Network),與之對應的是我們用肉長成的生物神經網路(Biology Neural Network)。眾所周知,人工神經網路受生物神經網路的啟發而產生,並在幾十年間不斷進步演化。可要論人類對人工智慧的探索歷史,卻遠遠長於這幾十年。為了深刻了解神經網路出現的背景,我們有必要從更早的歷史開始說起。
簡單說,人工智慧想做的事情就是去總結和提煉人類思考的過程,使之能夠機械化、可重復。從各種神話、傳說來看,我們的祖先在幾千年前就對這件事兒充滿了好奇與遐想。到兩千多年前,一大批偉大的哲學家在希臘、中國和印度相繼誕生,並將人類對這一問題的認識推向了新的高度。為避免本文成為枯燥的哲學史,這里不想舉太多的例子。偉大的希臘哲學家亞里士多德在他的《前分析篇》中提出了著名的三段論(sollygism),類似於:
所有希臘人是人
所有人終有一死
因此所有希臘人終有一死
雖然這是我們現在已經無比熟悉的推理模式,但是要在2000年前從無到有系統總結出一系列這樣的命題與推理模式,卻著實不易。有了『三段論』這種的武器,人們對問題的認識與決策就能從感性真正走向理性,做到可以重復。此外,我們熟悉的歐式幾何也是當時這種邏輯推理學派的代表。歐式幾何以一系列的公理為基礎,基於一套嚴密的邏輯推理體系,最終得到結論的證明,現在仍然是每個學生需要反復訓練的思維體操。
隨著時間的演進,認知哲學與邏輯學也在不斷的發展。在17世紀時,以笛卡爾、萊布尼茨為代表的哲學家進一步提出通過數學的方式對邏輯推演進行標准化,這也是對人腦推理與思考的再次抽象,為後續以後基於數字電路的人工智慧打下了基礎。之後,數理邏輯進一步發展,而到了20世紀中期,數理邏輯又一次取得了巨大的突破,哥德爾不完備理論、圖靈機模型等的相繼提出,科學家們既認識到了數理邏輯的局限性,也看到了將推理機械化的無限可能性,一種新的計算方式呼之欲出。
在圖靈機的思想指導下,第一台電子計算機很快被設計出來,為人工智慧的真正實現提供了物質上的基礎。其實回望人工智慧歷史上的歷次重大飛躍,硬體技術的發展無不扮演者重要的作用。很多看似有效的演算法都苦於沒有足夠強大的計算平台支持無疾而終,而計算能力的提升也可以促進科學家們們擺脫束縛,在演算法的研究道路上天馬行空。深度學習這些年的迅猛發展,很大程度就是得益於大規模集群和圖形處理器等技術的成熟,使得用復雜模型快速處理大規模數據成為可能。
1956年達特茅斯會議上,斯坦福大學科學家約翰·麥卡錫(John McCarthy)正式提出了『人工智慧』這一概念, 標志著一個學科的正式誕生,也標志著人工智慧的發展開始進入了快車道。如果說邏輯符號操作是對人類思維的本質的抽象,那麼利用電子計算機技術來模擬人類的符號推理計算也是一個自然而然的想法。在艾倫·紐威爾(Alan Newell)和赫伯特·西蒙(Herbert A.Simon)等大師的推動下,以邏輯推演為核心符號主義(symbolicism)流派很快占據了人工智慧領域的重要地位。符號主義在很多領域取得了成功,比如在80年代風靡一時的專家系統,通過知識庫和基於知識庫的推理系統模擬專家進行決策,得到了廣泛的應用。而本世紀初熱炒的語義網路以及當下最流行的知識圖譜,也可以看做這一流派的延續與發展。
符號主義最大的特點是知識的表示直觀,推理的過程清晰,但是也存在著許多局限性。除去在計算能力方面的困擾,一個很大的問題就在於雖然我們可以通過邏輯推理解決一些復雜的問題,但是對一些看似簡單的問題,比如人臉識別,卻無能為力。當看到一張人臉的照片,我們可以毫不費力的識別出這個人是誰,可這個過程並不需要做什麼復雜的推理,它在我們的大腦中瞬間完成,以至於我們對這個過程的細節卻一無所知。看起來想通過挖掘一系列嚴密的推理規則解決這類問題是相對困難的,這也促使很多人去探索與人腦工作更加貼合的解決方案。實際上在符號主義出現的同時,人工智慧的另一重要學派聯結主義(Connectionism)也開始蓬勃發展,本文的『主角』神經網路終於可以登場了。
在文章的一開始就提到,我們現在所說的人工神經網路是受生物神經網路啟發而設計出來的。在1890年,實驗心理學先驅William James在他的巨著《心理學原理》中第一次詳細論述人腦結構及功能。其中提到神經細胞受到刺激激活後可以把刺激傳播到另一個神經細胞,並且神經細胞激活是細胞所有輸入疊加的結果。這一後來得到驗證的假說也成為了人工神經網路設計的生物學基礎。基於這一假說,一系列模擬人腦神經計算的模型被相繼提出,具有代表性的有Hebbian Learning Rule, Oja's Rule和MCP Neural Model等,他們與現在通用的神經網路模型已經非常相似,例如在Hebbian Learning模型中,已經可以支持神經元之間權重的自動學習。而在1958年,Rosenblatt將這些模型付諸於實施,利用電子設備構建了真正意義上的第一個神經網路模型:感知機(Perceptron)。Rosenblatt現場演示了其學習識別簡單圖像的過程,在當時的社會引起了轟動,並帶來了神經網路的第一次大繁榮。此後的幾十年裡,神經網路又經歷了數次起起伏伏,既有春風得意一統天下的歲月,也有被打入冷宮無人問津的日子,當然,這些都是後話了。
本文更想討論這樣一個問題:神經網路產生的動機僅僅是對生物學中對神經機制的模仿嗎?在神經網路產生的背後,還蘊含著一代代科學家怎麼樣的思想與情懷呢?事實上,在神經網路為代表的一類方法在人工智慧中又被稱為聯結主義(Connectionism)。關於聯結主義的歷史,一般的文獻介紹按照慣例會追溯到希臘時期哲學家們對關聯性的定義與研究,例如我們的老朋友亞里士多德等等。然而當時哲學家研究的關聯其實並不特指神經元之間的這種關聯,比如前文提到的符號推理本身也是一種形式關聯,在希臘哲學中並沒有對這兩者進行專門的區分。所以硬要把這些說成是連接主義的思想起源略微有一些牽強。
前文提到,在數理邏輯發展過程中,17世紀的歐陸理性主義起到了重要的作用。以笛卡爾、萊布尼茨等為代表的哲學家,主張在理性中存在著天賦觀念,以此為原則並嚴格按照邏輯必然性進行推理就可以得到普遍必然的知識。與此同時,以洛克、休謨等哲學家為代表的英國經驗主義,則強調人類的知識來自於對感知和經驗歸納。這一定程度上是對絕對的真理的一種否定,人類的認識是存在主觀的,隨經驗而變化的部分的。如果在這個思想的指導下,我們與其去尋找一套普世且完備的推理系統,不如去構造一套雖不完美但能夠隨著經驗積累不斷完善的學習系統。而休謨甚至提出了放棄揭示自然界的因果聯系和必然規律,而是依據「習慣性聯想」去描繪一連串的感覺印象。這其實和神經網路設計的初衷是非常類似的:重視經驗的獲得與歸納(通過樣本進行學習),但對模型本身的嚴謹性與可解釋行則沒有那麼關注,正如有時候我們願意把神經網路模型看做是一個『黑箱』。
然而單單一個『黑箱』是不能成為經驗的學習與整理的系統的,我們還需要去尋找構建『黑箱』的一種方法論。現代哲學發展到20世紀初期時,在維特根斯坦和羅素等哲學家的倡導下,產生了邏輯經驗主義學派。依託當時邏輯學的迅猛發展,這一主義既強調經驗的作用,也重視通過嚴密的邏輯推理來得到結論,而非簡單的歸納。在數理邏輯領域頗有建樹的羅素有一位大名鼎鼎的學生諾伯特·維納,他創立的控制論與系統論、資訊理論一道,為信息科學的發展提供了堅實的理論基礎。而神經網路模型的創立也深受這『三論』的影響。前文提到MCP神經元模型的兩位創始人分別是羅素和維納的學生。作為一個系統,神經網路接受外部的輸入,得到輸出,並根據環境進行反饋,對系統進行更新,直到達到穩定狀態。這個過程,同樣也是神經網路對環境信息傳遞的接受和重新編碼的過程。如果如果把神經網路當做一個『黑盒』,那麼我們首先關心該是這個黑盒的輸入與輸出,以及如何根據環境給黑盒一個合理的反饋,使之能夠進行調整。而黑盒內部的結構,則更多的成為了形式的問題。我們借鑒生物神經網路構造這個黑盒,恰好是一個好的解決方案,但這未必是唯一的解決方案或者說與人類大腦的神經元結構存在必然的聯系。比如在統計學習領域中最著名的支持向量機(Support Vector Machines),最終是作為一種特殊的神經網路而提出的。可當其羽翼豐滿之後,則和神經網路逐漸脫離關系,開啟了機器學習的另一個門派。不同的模型形式之間可以互相轉化,但是重視經驗(樣本),強調反饋的思想卻一直保留下來。
前面說了這些,到底神經網路從何而來呢?總結下來就是三個方面吧:1.對理性邏輯的追求,對樣本實證的重視,為神經網路的誕生提供了思想的基礎。2.生物學與神經科學的發展為神經網路形式的出現提供了啟發。3.計算機硬體的發展與計算能力的提升使神經網路從理想變成了現實。而這三方面的發展也催生著神經網路的進一步發展與深度學習的成熟:更大規模的數據,更完善的優化演算法使網路能夠學習到更多更准確的信息;對人腦的認識的提升啟發設計出層次更深,結構更高效的網路結構;硬體存儲與計算能力提升使海量數據的高效訓練成為可能。而未來神經網路給我們帶來的更多驚喜,也很大可能源自於這三個方面,讓我們不妨多一些期待吧。
I. 一文讀懂神經網路
要說近幾年最引人注目的技術,無疑的,非人工智慧莫屬。無論你是否身處科技互聯網行業,隨處可見人工智慧的身影:從 AlphaGo 擊敗世界圍棋冠軍,到無人駕駛概念的興起,再到科技巨頭 All in AI,以及各大高校向社會輸送海量的人工智慧專業的畢業生。以至於人們開始萌生一個想法:新的革命就要來了,我們的世界將再次發生一次巨變;而後開始焦慮:我的工作是否會被機器取代?我該如何才能抓住這次革命?
人工智慧背後的核心技術是深度神經網路(Deep Neural Network),大概是一年前這個時候,我正在回老家的高鐵上學習 3Blue1Brown 的 Neural Network 系列視頻課程,短短 4 集 60 多分鍾的時間,就把神經網路從 High Level 到推導細節說得清清楚楚,當時的我除了獲得新知的興奮之外,還有一點新的認知,算是給頭腦中的革命性的技術潑了盆冷水:神經網路可以解決一些復雜的、以前很難通過寫程序來完成的任務——例如圖像、語音識別等,但它的實現機制告訴我,神經網路依然沒有達到生物級別的智能,短期內期待它來取代人也是不可能的。
一年後的今天,依然在這個春運的時間點,將我對神經網路的理解寫下來,算是對這部分知識的一個學習筆記,運氣好的話,還可以讓不了解神經網路的同學了解起來。
維基網路這樣解釋 神經網路 :
這個定義比較寬泛,你甚至還可以用它來定義其它的機器學習演算法,例如之前我們一起學習的邏輯回歸和 GBDT 決策樹。下面我們具體一點,下圖是一個邏輯回歸的示意圖:
其中 x1 和 x2 表示輸入,w1 和 w2 是模型的參數,z 是一個線性函數:
接著我們對 z 做一個 sigmod 變換(圖中藍色圓),得到輸出 y:
其實,上面的邏輯回歸就可以看成是一個只有 1 層 輸入層 , 1 層 輸出層 的神經網路,圖中容納數字的圈兒被稱作 神經元 ;其中,層與層之間的連接 w1、w2 以及 b,是這個 神經網路的參數 ,層之間如果每個神經元之間都保持著連接,這樣的層被稱為 全連接層 (Full Connection Layer),或 稠密層 (Dense Layer);此外,sigmoid 函數又被稱作 激活函數 (Activation Function),除了 sigmoid 外,常用的激活函數還有 ReLU、tanh 函數等,這些函數都起到將線性函數進行非線性變換的作用。我們還剩下一個重要的概念: 隱藏層 ,它需要把 2 個以上的邏輯回歸疊加起來加以說明:
如上圖所示,除輸入層和輸出層以外,其他的層都叫做 隱藏層 。如果我們多疊加幾層,這個神經網路又可以被稱作 深度神經網路 (Deep Neural Network),有同學可能會問多少層才算「深」呢?這個沒有絕對的定論,個人認為 3 層以上就算吧:)
以上,便是神經網路,以及神經網路中包含的概念,可見,神經網路並不特別,廣義上講,它就是
可見,神經網路和人腦神經也沒有任何關聯,如果我們說起它的另一個名字—— 多層感知機(Mutilayer Perceptron) ,就更不會覺得有多麼玄乎了,多層感知機創造於 80 年代,可為什麼直到 30 年後的今天才爆發呢?你想得沒錯,因為改了個名字……開個玩笑;實際上深度學習這項技術也經歷過很長一段時間的黑暗低谷期,直到人們開始利用 GPU 來極大的提升訓練模型的速度,以及幾個標志性的事件:如 AlphaGo戰勝李世石、Google 開源 TensorFlow 框架等等,感興趣的同學可以翻一下這里的歷史。
就拿上圖中的 3 個邏輯回歸組成的神經網路作為例子,它和普通的邏輯回歸比起來,有什麼優勢呢?我們先來看下單邏輯回歸有什麼劣勢,對於某些情況來說,邏輯回歸可能永遠無法使其分類,如下面數據:
這 4 個樣本畫在坐標系中如下圖所示
因為邏輯回歸的決策邊界(Decision Boundary)是一條直線,所以上圖中的兩個分類,無論你怎麼做,都無法找到一條直線將它們分開,但如果藉助神經網路,就可以做到這一點。
由 3 個邏輯回歸組成的網路(這里先忽略 bias)如下:
觀察整個網路的計算過程,在進入輸出層之前,該網路所做的計算實際上是:
即把輸入先做了一次線性變換(Linear Transformation),得到 [z1, z2] ,再把 [z1, z2] 做了一個非線性變換(sigmoid),得到 [x1', x2'] ,(線性變換的概念可以參考 這個視頻 )。從這里開始,後面的操作就和一個普通的邏輯回歸沒有任何差別了,所以它們的差異在於: 我們的數據在輸入到模型之前,先做了一層特徵變換處理(Feature Transformation,有時又叫做特徵抽取 Feature Extraction),使之前不可能被分類的數據變得可以分類了 。
我們繼續來看下特徵變換的效果,假設 為 ,帶入上述公式,算出 4 個樣本對應的 [x1', x2'] 如下:
再將變換後的 4 個點繪制在坐標系中:
顯然,在做了特徵變換之後,這兩個分類就可以很容易的被一條決策邊界分開了。
所以, 神經網路的優勢在於,它可以幫助我們自動的完成特徵變換或特徵提取 ,尤其對於聲音、圖像等復雜問題,因為在面對這些問題時,人們很難清晰明確的告訴你,哪些特徵是有用的。
在解決特徵變換的同時,神經網路也引入了新的問題,就是我們需要設計各式各樣的網路結構來針對性的應對不同的場景,例如使用卷積神經網路(CNN)來處理圖像、使用長短期記憶網路(LSTM)來處理序列問題、使用生成式對抗網路(GAN)來寫詩和作圖等,就連去年自然語言處理(NLP)中取得突破性進展的 Transformer/Bert 也是一種特定的網路結構。所以, 學好神經網路,對理解其他更高級的網路結構也是有幫助的 。
上面說了,神經網路可以看作一個非線性函數,該函數的參數是連接神經元的所有的 Weights 和 Biases,該函數可以簡寫為 f(W, B) ,以手寫數字識別的任務作為例子:識別 MNIST 數據集 中的數字,數據集(MNIST 數據集是深度學習中的 HelloWorld)包含上萬張不同的人寫的數字圖片,共有 0-9 十種數字,每張圖片為 28*28=784 個像素,我們設計一個這樣的網路來完成該任務:
把該網路函數所具備的屬性補齊:
接下來的問題是,這個函數是如何產生的?這個問題本質上問的是這些參數的值是怎麼確定的。
在機器學習中,有另一個函數 c 來衡量 f 的好壞,c 的參數是一堆數據集,你輸入給 c 一批 Weights 和 Biases,c 輸出 Bad 或 Good,當結果是 Bad 時,你需要繼續調整 f 的 Weights 和 Biases,再次輸入給 c,如此往復,直到 c 給出 Good 為止,這個 c 就是損失函數 Cost Function(或 Loss Function)。在手寫數字識別的列子中,c 可以描述如下:
可見,要完成手寫數字識別任務,只需要調整這 12730 個參數,讓損失函數輸出一個足夠小的值即可,推而廣之,絕大部分神經網路、機器學習的問題,都可以看成是定義損失函數、以及參數調優的問題。
在手寫識別任務中,我們既可以使用交叉熵(Cross Entropy)損失函數,也可以使用 MSE(Mean Squared Error)作為損失函數,接下來,就剩下如何調優參數了。
神經網路的參數調優也沒有使用特別的技術,依然是大家剛接觸機器學習,就學到的梯度下降演算法,梯度下降解決了上面迭代過程中的遺留問題——當損失函數給出 Bad 結果時,如何調整參數,能讓 Loss 減少得最快。
梯度可以理解為:
把 Loss 對應到 H,12730 個參數對應到 (x,y),則 Loss 對所有參數的梯度可以表示為下面向量,該向量的長度為 12730:
$$
abla L(w,b) = left[
frac{partial L}{partial w_1},
frac{partial L}{partial w_2},...,
frac{partial L}{partial b_{26}}
ight] ^ op
$$
所以,每次迭代過程可以概括為
用梯度來調整參數的式子如下(為了簡化,這里省略了 bias):
上式中, 是學習率,意為每次朝下降最快的方向前進一小步,避免優化過頭(Overshoot)。
由於神經網路參數繁多,所以需要更高效的計算梯度的演算法,於是,反向傳播演算法(Backpropagation)呼之欲出。
在學習反向傳播演算法之前,我們先復習一下微積分中的鏈式法則(Chain Rule):設 g = u(h) , h = f(x) 是兩個可導函數,x 的一個很小的變化 △x 會使 h 產生一個很小的變化 △h,從而 g 也產生一個較小的變化 △g,現要求 △g/△x,可以使用鏈式法則:
有了以上基礎,理解反向傳播演算法就簡單了。
假設我們的演示網路只有 2 層,輸入輸出都只有 2 個神經元,如下圖所示:
其中 是輸入, 是輸出, 是樣本的目標值,這里使用的損失函數 L 為 MSE;圖中的上標 (1) 或 (2) 分別表示參數屬於第 (1) 層或第 (2) 層,下標 1 或 2 分別表示該層的第 1 或 第 2 個神經元。
現在我們來計算 和 ,掌握了這 2 個參數的偏導數計算之後,整個梯度的計算就掌握了。
所謂反向傳播演算法,指的是從右向左來計算每個參數的偏導數,先計算 ,根據鏈式法則
對左邊項用鏈式法則展開
又 是輸出值, 可以直接通過 MSE 的導數算出:
而 ,則 就是 sigmoid 函數的導數在 處的值,即
於是 就算出來了:
再來看 這一項,因為
所以
注意:上面式子對於所有的 和 都成立,且結果非常直觀,即 對 的偏導為左邊的輸入 的大小;同時,這里還隱含著另一層意思:需要調整哪個 來影響 ,才能使 Loss 下降得最快,從該式子可以看出,當然是先調整較大的 值所對應的 ,效果才最顯著 。
於是,最後一層參數 的偏導數就算出來了
我們再來算上一層的 ,根據鏈式法則 :
繼續展開左邊這一項
你發現沒有,這幾乎和計算最後一層一摸一樣,但需要注意的是,這里的 對 Loss 造成的影響有多條路徑,於是對於只有 2 個輸出的本例來說:
上式中, 都已經在最後一層算出,下面我們來看下 ,因為
於是
同理
注意:這里也引申出梯度下降的調參直覺:即要使 Loss 下降得最快,優先調整 weight 值比較大的 weight。
至此, 也算出來了
觀察上式, 所謂每個參數的偏導數,通過反向傳播演算法,都可以轉換成線性加權(Weighted Sum)計算 ,歸納如下:
式子中 n 代表分類數,(l) 表示第 l 層,i 表示第 l 層的第 i 個神經元。 既然反向傳播就是一個線性加權,那整個神經網路就可以藉助於 GPU 的矩陣並行計算了 。
最後,當你明白了神經網路的原理,是不是越發的認為,它就是在做一堆的微積分運算,當然,作為能證明一個人是否學過微積分,神經網路還是值得學一下的。Just kidding ..
本文我們通過
這四點,全面的學習了神經網路這個知識點,希望本文能給你帶來幫助。
參考:
J. 神經網路淺談
人工智慧技術是當前炙手可熱的話題,而基於神經網路的深度學習技術更是熱點中的熱點。去年穀歌的Alpha Go 以4:1大比分的優勢戰勝韓國的李世石九段,展現了深度學習的強大威力,後續強化版的Alpha Master和無師自通的Alpha Zero更是在表現上完全碾壓前者。不論你怎麼看,以深度學習為代表的人工智慧技術正在塑造未來。
下圖為英偉達(NVIDIA)公司近年來的股價情況, 該公司的主要產品是「圖形處理器」(GPU),而GPU被證明能大大加快神經網路的訓練速度,是深度學習必不可少的計算組件。英偉達公司近年來股價的飛漲足以證明當前深度學習的井噴之勢。
好,話不多說,下面簡要介紹神經網路的基本原理、發展脈絡和優勢。
神經網路是一種人類由於受到生物神經細胞結構啟發而研究出的一種演算法體系,是機器學習演算法大類中的一種。首先讓我們來看人腦神經元細胞:
一個神經元通常具有多個樹突 ,主要用來接受傳入信息,而軸突只有一條,軸突尾端有許多軸突末梢,可以給其他多個神經元傳遞信息。軸突末梢跟其他神經元的樹突產生連接,從而傳遞信號。
下圖是一個經典的神經網路(Artificial Neural Network,ANN):
乍一看跟傳統互聯網的拓撲圖有點類似,這也是稱其為網路的原因,不同的是節點之間通過有向線段連接,並且節點被分成三層。我們稱圖中的圓圈為神經元,左邊三個神經元組成的一列為輸入層,中間神經元列為隱藏層,右邊神經元列為輸出層,神經元之間的箭頭為權重。
神經元是計算單元,相當於神經元細胞的細胞核,利用輸入的數據進行計算,然後輸出,一般由一個線性計算部分和一個非線性計算部分組成;輸入層和輸出層實現數據的輸入輸出,相當於細胞的樹突和軸突末梢;隱藏層指既不是輸入也不是輸出的神經元層,一個神經網路可以有很多個隱藏層。
神經網路的關鍵不是圓圈代表的神經元,而是每條連接線對應的權重。每條連接線對應一個權重,也就是一個參數。權重具體的值需要通過神經網路的訓練才能獲得。我們實際生活中的學習體現在大腦中就是一系列神經網路迴路的建立與強化,多次重復的學習能讓迴路變得更加粗壯,使得信號的傳遞速度加快,最後對外表現為「深刻」的記憶。人工神經網路的訓練也借鑒於此,如果某種映射關系出現很多次,那麼在訓練過程中就相應調高其權重。
1943年,心理學家McCulloch和數學家Pitts參考了生物神經元的結構,發表了抽象的神經元模型MP:
符號化後的模型如下:
Sum函數計算各權重與輸入乘積的線性組合,是神經元中的線性計算部分,而sgn是取符號函數,當輸入大於0時,輸出1,反之輸出0,是神經元中的非線性部分。向量化後的公式為z=sgn(w^T a)(w^T=(w_1,w_2,w_3),a=〖(a_1,a_2,a_3)〗^T)。
但是,MP模型中,權重的值都是預先設置的,因此不能學習。該模型雖然簡單,並且作用有限,但已經建立了神經網路大廈的地基
1958年,計算科學家Rosenblatt提出了由兩層神經元組成(一個輸入層,一個輸出層)的神經網路。他給它起了一個名字–「感知器」(Perceptron)
感知器是當時首個可以學習的人工神經網路。Rosenblatt現場演示了其學習識別簡單圖像的過程,在當時引起了轟動,掀起了第一波神經網路的研究熱潮。
但感知器只能做簡單的線性分類任務。1969年,人工智慧領域的巨擘Minsky指出這點,並同時指出感知器對XOR(異或,即兩個輸入相同時輸出0,不同時輸出1)這樣的簡單邏輯都無法解決。所以,明斯基認為神經網路是沒有價值的。
隨後,神經網路的研究進入低谷,又稱 AI Winter 。
Minsky說過單層神經網路無法解決異或問題,但是當增加一個計算層以後,兩層神經網路不僅可以解決異或問題,而且具有非常好的非線性分類效果。
下圖為兩層神經網路(輸入層一般不算在內):
上圖中,輸出層的輸入是上一層的輸出。
向量化後的公式為:
注意:
每個神經元節點默認都有偏置變數b,加上偏置變數後的計算公式為:
同時,兩層神經網路不再使用sgn函數作為激勵函數,而採用平滑的sigmoid函數:
σ(z)=1/(1+e^(-z) )
其圖像如下:
理論證明: 兩層及以上的神經網路可以無限逼近真實的對應函數,從而模擬數據之間的真實關系 ,這是神經網路強大預測能力的根本。但兩層神經網路的計算量太大,當時的計算機的計算能力完全跟不上,直到1986年,Rumelhar和Hinton等人提出了反向傳播(Backpropagation,BP)演算法,解決了兩層神經網路所需要的復雜計算量問題,帶動了業界使用兩層神經網路研究的熱潮。
但好景不長,演算法的改進僅使得神經網路風光了幾年,然而計算能力不夠,局部最優解,調參等一系列問題一直困擾研究人員。90年代中期,由Vapnik等人發明的SVM(Support Vector Machines,支持向量機)演算法誕生,很快就在若干個方面體現出了對比神經網路的優勢:無需調參;高效;全局最優解。
由於以上原因,SVM迅速打敗了神經網路演算法成為主流。神經網路的研究再一次進入低谷, AI Winter again 。
多層神經網路一般指兩層或兩層以上的神經網路(不包括輸入層),更多情況下指兩層以上的神經網路。
2006年,Hinton提出使用 預訓練 」(pre-training)和「微調」(fine-tuning)技術能優化神經網路訓練,大幅度減少訓練多層神經網路的時間
並且,他給多層神經網路相關的學習方法賦予了一個新名詞–「 深度學習 」,以此為起點,「深度學習」紀元開始了:)
「深度學習」一方面指神經網路的比較「深」,也就是層數較多;另一方面也可以指神經網路能學到很多深層次的東西。研究發現,在權重參數不變的情況下,增加神經網路的層數,能增強神經網路的表達能力。
但深度學習究竟有多強大呢?沒人知道。2012年,Hinton與他的學生在ImageNet競賽中,用多層的卷積神經網路成功地對包含一千類別的一百萬張圖片進行了訓練,取得了分類錯誤率15%的好成績,這個成績比第二名高了近11個百分點,充分證明了多層神經網路識別效果的優越性。
同時,科研人員發現GPU的大規模並行矩陣運算模式完美地契合神經網路訓練的需要,在同等情況下,GPU的速度要比CPU快50-200倍,這使得神經網路的訓練時間大大減少,最終再一次掀起了神經網路研究的熱潮,並且一直持續到現在。
2016年基於深度學習的Alpha Go在圍棋比賽中以4:1的大比分優勢戰勝了李世石,深度學習的威力再一次震驚了世界。
神經網路的發展歷史曲折盪漾,既有被捧上神壇的高潮,也有無人問津的低谷,中間經歷了數次大起大落,我們姑且稱之為「三起三落」吧,其背後則是演算法的改進和計算能力的持續發展。
下圖展示了神經網路自發明以來的發展情況及一些重大時間節點。
當然,對於神經網路我們也要保持清醒的頭腦。由上圖,每次神經網路研究的興盛期持續10年左右,從最近2012年算起,或許10年後的2022年,神經網路的發展將再次遇到瓶頸。
神經網路作為機器學習的一種,其模型訓練的目的,就是使得參數盡可能的與真實的模型逼近。理論證明,兩層及以上的神經網路可以無限逼近真實的映射函數。因此,給定足夠的訓練數據和訓練時間,總能通過神經網路找到無限逼近真實關系的模型。
具體做法:首先給所有權重參數賦上隨機值,然後使用這些隨機生成的參數值,來預測訓練數據中的樣本。假設樣本的預測目標為yp ,真實目標為y,定義值loss,計算公式如下:
loss = (yp -y) ^2
這個值稱之為 損失 (loss),我們的目標就是使對所有訓練數據的損失和盡可能的小,這就轉化為求loss函數極值的問題。
一個常用方法是高等數學中的求導,但由於參數不止一個,求導後計算導數等於0的運算量很大,所以常用梯度下降演算法來解決這樣的優化問題。梯度是一個向量,由函數的各自變數的偏導數組成。
比如對二元函數 f =(x,y),則梯度∇f=(∂f/∂x,∂f/∂y)。梯度的方向是函數值上升最快的方向。梯度下降演算法每次計算參數在當前的梯度,然後讓參數向著梯度的反方向前進一段距離,不斷重復,直到梯度接近零時截止。一般這個時候,所有的參數恰好達到使損失函數達到一個最低值的狀態。下圖為梯度下降的大致運行過程:
在神經網路模型中,由於結構復雜,每次計算梯度的代價很大。因此還需要使用 反向傳播 (Back Propagation)演算法。反向傳播演算法利用了神經網路的結構進行計算,不一次計算所有參數的梯度,而是從後往前。首先計算輸出層的梯度,然後是第二個參數矩陣的梯度,接著是中間層的梯度,再然後是第一個參數矩陣的梯度,最後是輸入層的梯度。計算結束以後,所要的兩個參數矩陣的梯度就都有了。當然,梯度下降只是其中一個優化演算法,其他的還有牛頓法、RMSprop等。
確定loss函數的最小值後,我們就確定了整個神經網路的權重,完成神經網路的訓練。
在神經網路中一樣的參數數量,可以用更深的層次去表達。
由上圖,不算上偏置參數的話,共有三層神經元,33個權重參數。
由下圖,保持權重參數不變,但增加了兩層神經元。
在多層神經網路中,每一層的輸入是前一層的輸出,相當於在前一層的基礎上學習,更深層次的神經網路意味著更深入的表示特徵,以及更強的函數模擬能力。更深入的表示特徵可以這樣理解,隨著網路的層數增加,每一層對於前一層次的抽象表示更深入。
如上圖,第一個隱藏層學習到「邊緣」的特徵,第二個隱藏層學習到「邊緣」組成的「形狀」的特徵,第三個隱藏層學習到由「形狀」組成的「圖案」的特徵,最後的隱藏層學習到由「圖案」組成的「目標」的特徵。通過抽取更抽象的特徵來對事物進行區分,從而獲得更好的區分與分類能力。
前面提到, 明斯基認為Rosenblatt提出的感知器模型不能處理最簡單的「異或」(XOR)非線性問題,所以神經網路的研究沒有前途,但當增加一層神經元後,異或問題得到了很好地解決,原因何在?原來從輸入層到隱藏層,數據發生了空間變換,坐標系發生了改變,因為矩陣運算本質上就是一種空間變換。
如下圖,紅色和藍色的分界線是最終的分類結果,可以看到,該分界線是一條非常平滑的曲線。
但是,改變坐標系後,分界線卻表現為直線,如下圖:
同時,非線性激勵函數的引入使得神經網路對非線性問題的表達能力大大加強。
對於傳統的樸素貝葉斯、決策樹、支持向量機SVM等分類器,提取特徵是一個非常重要的前置工作。在正式訓練之前,需要花費大量的時間在數據的清洗上,這樣分類器才能清楚地知道數據的維度,要不然基於概率和空間距離的線性分類器是沒辦法進行工作的。然而在神經網路中,由於巨量的線性分類器的堆疊(並行和串列)以及卷積神經網路的使用,它對雜訊的忍耐能力、對多通道數據上投射出來的不同特徵偏向的敏感程度會自動重視或忽略,這樣我們在處理的時候,就不需要使用太多的技巧用於數據的清洗了。有趣的是,業內大佬常感嘆,「你可能知道SVM等機器學習的所有細節,但是效果並不好,而神經網路更像是一個黑盒,很難知道它究竟在做什麼,但工作效果卻很好」。
人類對機器學習的環節干預越少,就意味著距離人工智慧的方向越近。神經網路的這個特性非常有吸引力。
1) 谷歌的TensorFlow開發了一個非常有意思的神經網路 入門教程 ,用戶可以非常方便地在網頁上更改神經網路的參數,並且能看到實時的學習效率和結果,非常適合初學者掌握神經網路的基本概念及神經網路的原理。網頁截圖如下:
2) 深度學習領域大佬吳恩達不久前發布的《 神經網路和深度學習 》MOOC,現在可以在網易雲課堂上免費觀看了,並且還有中文字幕。
3) 《神經網路於深度學習》(Michael Nielsen著)、《白話深度學習與TensorFlow》也是不錯的入門書籍。