2014-09-29 53 views
12

神經網絡實際上只是很多參數的巨大作用,所以你可能會認爲,這將是美好的函數式語言來寫這樣的功能,但在某些NN庫對其他語言工作過,我有一些疑問如何在這個範例中有效地實施它們。如何在Haskell中高效實現通用神經網絡?

繞過信息:如果你使每個神經元或層的相關性的圖表,你會得到這樣的事情

enter image description here

其中X是輸入,並˚F是輸出。雖然它在圖中看起來非常直截了當,但如果您真的將網絡視爲一項功能,那麼f必須將輸入(加上權重參數的子集)傳遞到g1g2,它們中的每一個都具有將這些傳遞給h1,h2h3誰最終將結果發送到上面的圖層。考慮到一組輸入加上一組權重可能是一千或更多的變量,這看起來效率很低。在其他語言中,您不必這樣做,因爲每個神經元都可以保留它的參數,並且輸入可以直接傳遞到輸入層。

國:如果你看一下圖表,既G1G2要單獨調用H2,但由於H2具有產生兩個相同的值,它不有意義的計算兩次輸出。既然你沒有國家或副作用這成爲棘手的,如果你有一個非常龐大的網絡,然後甚至一些並行計算這會浪費大量的時間。

最後,當我說網絡是通用,我的意思是它可以有任意形狀,只要它的結構不包含循環。大多數庫我看到使用的層的疊層,所以你只需要限定層的數量和神經元的每一層中的號碼,但它的形狀是直線圖;這是對簡單的應用程序,但真的很難核心員工需要網絡具有更復雜的架構

標識像如何攻克這些問題,因爲我想實現一個庫,用於自己的需要一些建議。

注:

我不是完全陌生的語言。我用函子和單子相當數量的(主要是在我的基礎上haskells API C#FP庫),但我以前從未使用過Haskell中的實際應用。

更新

State單子看起來非常有前途!

+2

你有沒有研究HNN包裝是如何做到的? – 2014-09-29 03:35:27

+0

我會研究它。我知道他們使用hmatrices,並不渴望這種通用的東西,但也許他們也面臨這些問題。 – 2014-09-29 03:41:43

+0

如果它像函數調用圖一樣工作,我的第一個直覺就是可以通過使用nexus類型的結構來提高效率,如本文所示http://www.cs.ox.ac.uk/ralf.hinze/出版物/ HW03.pdf。不幸的是,我不太清楚這個問題能夠給出答案。 「Hylomorphism」也可能是一個關鍵詞。編輯:其實,現在我想到了,你可能需要比技術通常提供的更多的結構信息。 – 2014-09-29 03:41:51

回答

1

我的意思是,因爲Haskell有相互遞歸可能寫在一個大的相互遞歸的WHERE子句的條件,您已經構造圖是最簡單的方法:

run_graph x = run_f g1 g2 where 
    g1 = run_g1 h1 h2 
    g2 = run_g2 h2 h3 
    h1 = run_h1 x 
    h2 = run_h2 x 
    h3 = run_h3 x 

通過給予這些數字更豐富類型比例如Double,您可以構建一種與圖形對應的抽象數據結構,然後您可以使用反向傳播。

您可能不必擔心過早優化用於評估的圖形:Haskell會自動緩存功能在其輸入上的答案;這是可能的,因爲在Haskell函數中不應該有副作用。當您的run_*函數創建數據結構中的抽象節點時,eval_g1 h2 h3最終將使用來自eval_h2 x的緩存值,該值將跳轉回h2。如果這太枯燥乏味,那麼在您必須明確開始指定圖層並在圖的圖層中傳播Data.Array.Unboxed之前,您可能仍然可以切換到攜帶IntMap狀態的節點的寬度優先步行。