日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

函数求值需要运行所有线程_精读《深度学习 - 函数式之美》

發布時間:2023/12/10 pytorch 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 函数求值需要运行所有线程_精读《深度学习 - 函数式之美》 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 引言

函數式語言在深度學習領域應用很廣泛,因為函數式與深度學習模型的契合度很高,The Beauty of Functional Languages in Deep Learning?—?Clojure and Haskell 就很好的詮釋了這個道理。

通過這篇文章可以加深我們對深度學習與函數式編程的理解。

2 概述與精讀

深度學習是機器學習中基于人工神經網絡模型的一個分支,通過模擬多層神經元的自編碼神經網絡,將特征逐步抽象化,這需要多維度、大數據量的輸入。TensorFlow 和 PyTorch 是比較著名的 Python 深度學習框架,同樣 Keras 在 R 語言中也很著名。然而在生產環境中,基于 性能和安全性 的考慮,一般會使用函數式語言 Clojure 或 Haskell。

在生產環境中,可能要并發出里幾百萬個參數,因此面臨的挑戰是:如何高效、安全的執行這些運算。

所以為什么函數式編程語言可以勝任深度學習的計算要求呢? 深度學習的計算模型本質上是數學模型,而數學模型本質上和函數式編程思路是一致的:數據不可變且函數間可以任意組合。這意味著使用函數式編程語言可以更好的表達深度學習的計算過程,因此更容易理解與維護,同時函數式語言內置的 Immutable 數據結構也保障了并發的安全性。

另外函數式語言的函數之間都是相互隔離的,即便在多線程環境下也不會發生競爭和死鎖的情況,函數式編程語言會自動處理這些情況。

比如說 Clojure,它甚至可在兩個同時修改同一引用的程序并發運行時,自動重試其中之一,而不需要手動加鎖:

(import ‘(java.util.concurrent Executors)) (defn test-stm [nitems nthreads niters](let [refs (map ref (repeat nitems 0))pool (Executors/newFixedThreadPool nthreads)tasks (map (fn [t](fn [](dotimes [n niters](dosync(doseq [r refs](alter r + 1 t))))))(range nthreads))](doseq [future (.invokeAll pool tasks)](.get future))(.shutdown pool)(map deref refs))) (test-stm 10 10 10000) -> (550000 550000 550000 550000 550000 550000 550000 550000 550000 550000)

上面的代碼創建了引用(refs),同時創建了多個線程自增這個引用對象,按理說每個線程都修改這個引用會導致競爭狀態出現,但從結果來看是正常的,說明 Clojure 引擎在執行時會自動解決這個問題。實際上當兩個線程出現競爭而失敗時,Clojure 會自動重試其中之一。

原文介紹

Clojure 的另一個優勢是并行效率高:

(defn calculate-pixels-2 [](let [n (* *width* *height*)work (partition (/ n 16) (range 0 n))result (pmap (fn [x](doall (map(fn [p](let [row (rem p *width*) col (int (/ p *height*))](get-color (process-pixel (/ row (double *width*)) (/ col (double *height*))))))x)))work)](doall (apply concat result))))

使用 partition 結合 pmap 可以使并發效率達到最大化,也就是 CPU 幾乎都消耗在實際計算上,而不是并行的任務管理與上下文切換。Clojure 憑借 partition 對計算進行分區,采取分而治之并對分區計算結果進行合并的思路優化了并發性能。

原文介紹

Clojure 另一個特性是函數鏈式調用:

;; pipe arg to function (-> "x" f1) ; "x1";; pipe. function chaining (-> "x" f1 f2) ; "x12"

其中 (-> "x" f1 f2) 等價于 f2(f1("x")),這種描述不僅更簡潔清晰,也更接近于實際數學模型。

原文介紹

最后,Clojure 還具備計算安全性,計算過程不會修改已有的數據,因此在神經網絡的任何一層的原始值都會保留,每層計算都可以獨立運行且函數永遠冪等。

Haskell 也有獨特的優勢,它具有類型推斷、惰性求值等特性,被認為更適合用于機器學習。

類型推斷即 Haskell 類型都是靜態的,如果試圖賦予錯誤的類型會報錯。

Haskell 的另一個優勢是可以非常清晰的描述數學模型。

想想一般數學模型是怎么描述函數的:

fn =>f1 = 1f2 = 9f3 = 16n > 2, fn = 3fn-3 + 2fn-2 + fn-1

一般語言用 if-else 描述等價關系,但 Haskell 可以幾乎原汁原味的還原函數定義過程:

solve :: Int -> Interger solve 1 = 1 solve 2 = 9 solve 3 = 16 solve n = 3 * solve (n - 3) + 2 * solve (n - 2) + solve (n - 1)

這使得閱讀 Haskell 代碼和閱讀數學公式一樣輕松。

原文

Haskell 另一個優勢是惰性求值,即計算會在真正用到時才進行,而不會在計算前提前消費掉,比如:

let x = [1..] let y = [2,4 ..] head (tail tail( (zip x y)))

可以看到,x 與 y 分別是 1,2,3,4,5,6... 與 2,4,6,8... 的無限數組,而 zip 函數將其整合為一個新數組 (1,2),(2,4),(3,6),(4,8)... 這也是無限數組,如果將 zip 函數執行完那么程序就會永遠執行下去。但 Haskell 卻不會陷入死循環,而是直接輸出第一位數字 1。這就是惰性計算的特性,無論數組有多長,只有真正用到某項時才對其進行計算,所以哪怕初始數據量或計算量很大,實際消耗的運算資源只取決于這次計算實際用到的部分。

由于深度學習數據量巨大,惰性求值可以忽略海量數據輸入,大大提升計算性能。

3 總結

本文介紹了為什么深度學習更適合使用函數式語言,以及介紹了 Clojure 與 Haskell 語言的共性:安全性、高性能,以及各自獨有的特性,證明了為何這兩種語言更適合用在深度學習中。

在前端領域說到函數式或函數之美,大部分時候想到的是 Class Component 與 Function Component 的關系,這個理解是較為片面的。通過本文我們可以了解到,函數式的思想與數學表達式思想如出一轍,以寫數學公式的思維方式寫代碼,就是一種較好的函數式編程思路。

函數式應該只有表達式,沒有語句,這是因為函數式是為了處理運算而誕生的,因此很適合用在深度學習領域。

討論地址是:精讀《深度學習 - 函數式之美》 · Issue #212 · dt-fe/weekly

如果你想參與討論,請 點擊這里,每周都有新的主題,周末或周一發布。前端精讀 - 幫你篩選靠譜的內容。

關注 前端精讀微信公眾號

版權聲明:自由轉載-非商用-非衍生-保持署名(創意共享 3.0 許可證)

總結

以上是生活随笔為你收集整理的函数求值需要运行所有线程_精读《深度学习 - 函数式之美》的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。