1. 程式人生 > >深度學習基礎--不同網路種類--可微分程式設計;Differentiable Programming

深度學習基礎--不同網路種類--可微分程式設計;Differentiable Programming

可微分程式設計;Differentiable Programming

  lecun說"深度學習已死,可微分程式設計萬歲!",即深度學習這個詞已死,該有新的名詞可微分程式設計來替代它了。   深度學習的本質是可微分程式設計,那麼,就把神經網路當函式用吧!   一個程式本身當成一個神經網路,然後自己調節引數。實現真正的可微分程式設計需要的就是自動化調參,於是乎,貝葉斯方法開始大量用於深度學習。

傳統程式設計方法與可微分程式設計(Differentiable Programming)

  1)傳統的程式設計方法:程式設計師人工寫出每一行程式碼,機器按照給定的程式碼執行程式,根據輸入資料X得到運算結果Y。   2)Differentiable Programming:讓程式自己寫程式。程式設計師不寫程式碼,或者僅寫出少量high-level的程式碼,但是提供大量輸入資料X與對應運算結果Y的例子。神經網路根據提供的資料集,自動學出從輸入資料X到最終運算結果Y的對映(既整個程式);或者結合程式設計師提供的high-level的程式碼,用神經網路作為中間函式,補全得到整個程式。

更具體地解釋可微分程式設計

  最近,有一些研究者轉向了“不整齊”的神經網路。這些神經網路並沒有分出明顯的層次,反而是,神經節點之間可以跨層次連線,不同的神經網路之間也可以相互連線,它們之間的連線也可以是各種函式。Hinton的Capsule網路,也類似於這個思想。還有一個課題叫AutoML,研究如何自動生成神經網路的結構。但是不論網路結構怎麼改變,有效的訓練方法還是那幾種,例如BP演算法和遺傳演算法。   其中最常用的BP演算法,就是以求“微分”為基礎的。只要一個函式可以求微分,那就可以用BP演算法去訓練(訓練能否成功是另一回事)。

  LeCun的原文中提到,現在越來越多的人用“過程式”的方法定義神經網路,就像是定義以往的程式一樣。這句話的意思是,人們開始“設計”神經網路的結構,就像是我們以往的程式設計一樣。舉個例子,以往我們程式設計,要對一串數字進行排序,我們一般會寫一個sort函式,然後我們就可以多次呼叫這個sort函式。神經網路也是一樣,比方說我們有個神經網路,它可以對一串數字進行排序,那麼我們也可以多次呼叫它(題外話:在Neural Turing Machines這篇論文中,就訓練了可以對數字進行排序的神經網路)。這樣的神經網路,就像是我們傳統程式設計概念中的函式一樣,可以被重複呼叫。唯一的不同點是,以往的程式是固定的;而神經網路是動態的,是可以被訓練的。

  例如capsule,以前CNN每個節點的權值是標量,Hinton改為用向量,將來不排除可以用張量。但本質上的架構,其實確實是可微分程式設計。Lecun要提出改名也無可厚非,畢竟這是對DeepLearning續命的好方法啊,可惜一波不明就裡的媒體直接拿來做標題榜。

可能產生的影響

  可以看出來,其實任何神經網路都可以像搭積木一樣拼出來,這個積木只需要一個條件,就是可以微分,這種可微分是做BP的必要條件, 而且可微分有一個很好的特點,就是鏈式法則,這樣決定了所有的微分可以組合起來。除了這個之外,和普通程式設計沒有什麼區別。我想這就是可微分程式設計的來歷。   想一想,這對以後的程式設計有什麼影響,以後寫神經網路。直接提供給你幾個可以微分的模組(就像Drag and Drop UI 裡面的這種模組), 你簡單的組合起來, 加上loss function, 就可以形成你的神經網路了。   我覺得有點像Keras現在做的,但是現在Keras只提供了有限的Cell。以後的模組應該只要滿足模組可微分就可以了,這個比現在的Keras Cell 要多的多得多。

  1)簡單的神經網路:一層加一層,每一層有N個節點,forward過程做加權,backward過程,因為每個節點都是可以微分的,做反向傳播(BP)。   2)CNN,每一層改為一個3維或者4維的層級,每一塊掃描,每一塊可微分。forward加權,因為每個節點可微分,做BP。   3)RNN,每個層可以向自己做微分。   4)GAN,兩個網路,每層都可以微分,特殊的loss函式。

  演算法越來越向全自動的方向發展,例如自適應的batch、自適應梯度…