ディープラーニングにおける関数型言語の美しさ–ClojureとHaskell

ディープラーニングは、人工ニューラルネットワークに基づいた機械学習メソッドのサブセットです。 これらは、脳などの生物学的システムにおける情報処理と分散通信ノードに触発されています。 深層学習では、各レベルは、入力データを少し抽象的で複合的な表現に変換することを学習します。 たとえば、顔認識システムでは、ピクセルはシステムの1つのレイヤーになり、エッジは別のレイヤーになり、目は別のレイヤーになり、顔は別のレイヤーにな 深い学習方法の複雑さは、プログラミングコミュニティで既存のパッケージを使用することを人気があります。 しかし、ディープラーニングシステムの生産において、パフォーマンスと安全性は、代わりにClojureやHaskellなどの関数型プログラミング言語を選択する企業を駆り立てる二つの問題である。

image

ディープラーニングの実装の難しさ

ディープラーニングシステムを生産に投入する際には、ニューラルネットワークには百万のパラメータが含まれている可能性があります。 データはすぐにこれらの変数を訓練するために爆発できます。 このようなデータの爆発には、安全な並行性と並列性を備えた効率的なプログラミング言語によってのみ達成できるパフォーマンスが必要です。 ニューラルネットワークの複雑さのために、データが層から層に渡されるため、プログラミング言語がこのデータを処理する方法の単純さと一貫性が重要 この場合の安全性とは、元のデータの状態を一貫した方法で保持できることを意味し、単純性とは、パフォーマンスを最大化しながらコードベースを簡単に読

なぜ関数型プログラミングがディープラーニングに適しているのか

ディープラーニングを実装するときに発生する可能性のある困難のいくつかを解決しようとすると、プログラマは関数型プログラミング言語が解決策を提供できることに気づいています。

計算機科学において、関数型プログラミングは、計算を数学関数の評価として扱い、状態の変化や可変データの変化を避けるプログラミングパラダイムである。 これは、数学的思考に近いプログラミングパターンです。

深層学習モデルは本質的に数学的モデルです。 例えば、人工ニューラルネットワークは、接続されたノードを含み、それぞれが簡単な数学的演算を実行する。 関数型プログラミング言語を使用することにより、プログラマはこれらの数学的演算を、演算自体に近い言語で記述することができます。 これらのプログラムが明示的に記述されているため、コードベースの読み取りと保守がはるかに簡単になります。

同時に、深層学習アルゴリズムの組成的性質は、神経作業の各層で、層または機能が連鎖してタスクを実行する傾向があることを意味します。 これは、関数型プログラミング言語の関数連鎖を使用して簡単に実装できます。

image

さらに、ディープラーニングでは、データに関数を適用してもデータは変化しません。 新しい値は、行の下に順番に出力されることがありますが、データ自体は一貫したままです。 関数型プログラミング言語の不変性機能により、プログラマは、元の不変データセットを変更することなく、新しい値が生成されるたびに新しいデータセットを作成することができます。 これにより、ニューラルネットワーク全体でデータの一貫性を維持することが容易になります。

最後に、深層学習の実装に関与する多数のパラメータとトレーニングデータは、並列性と並行性が実稼働レベルの深層学習システムを作成するための鍵であることを意味します。 並列処理とは、学習プロセスを高速化するために、異なるCpu上でスレッドを実行することを意味します。 同時実行とは、競合を回避するためにスレッドを管理する機能を意味します。 関数型プログラミングは、並行性と並列性を無償で可能にします。 これは、その性質上、純粋な関数がステートレスである関数型プログラミングは、特定の入力に対して常に同じ出力を生成し、任意の関数を分離し、いつでも実行できるようにすることを意味します。 これにより、並行性と並列性の管理がはるかに容易になります。 デッドロックや競合状態などの問題に対処する必要はありません。 異なるCpuにアクセスする異なるスレッドは、競合なしで独立して実行することができます。

Clojure

関数型プログラミングがディープラーニングで人気を集め、ディープラーニングに利用可能な堅牢なパッケージで、ClojureはWalmartやFacebookなどの企業に好まれています。 これは、LISPプログラミング言語に基づく高レベルで動的な関数型プログラミング言語であり、Javaと.NETランタイム環境の両方で実行できるようにするコ

Clojureの同時プログラミングの力

ClojureはJavaスレッドシステムを置き換えるのではなく、それを使って動作します。 コアデータ構造は不変であるため、スレッド間で容易に共有できます。 同時に、プログラムの状態の変更も可能ですが、Clojureは状態の一貫性を維持するためのメカニズムを提供します。 同じ参照を変更しようとしている2つのトランザクション間で競合が発生した場合、そのうちの1つは廃止されます。 明示的なロックは必要ありません。

(import '(java.util.concurrent Executors))(defn test-stm (let (fn (dotimes (dosync (doseq (alter r + 1 t)))))) (range nthreads))] (doseq (.get future)) (.shutdown pool) (map deref refs)))(test-stm 10 10 10000) -> (550000 550000 550000 550000 550000 550000 550000 550000 550000 550000)

ソース

Clojureの並列性は安い

ディープラーニングでは、モデルは大量のデータを訓練する必要があります。 並列処理は、異なるCpu上で複数のスレッドを実行することを意味します。 安価な並列処理は、パフォーマンスが大幅に向上することを意味します。 Partitionをmapと組み合わせて使用すると、コストのかからない並列処理を実現できます。

(defn calculate-pixels-2 (let (doall (map (fn (let (get-color (process-pixel (/ row (double *width*)) (/ col (double *height*)))))) x))) work)] (doall (apply concat result))))

ソース

Clojureのチェイン関数は明快さを意味します

Clojureには、非常に少数のデータ型に対する多くの関数があります。 また、関数を引数として他の関数に渡すこともできるため、深層学習での関数の連鎖が可能になります。 実装を実際の数学モデルに近づけることで、Clojureコードの読み取りと保守を簡単に行うことができます。

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

ソース

ClojureのIdと状態が安全性を提供

Clojureでは、各モデルのidには任意の時点で一つの状態があります。 その状態は決して変わらない真の価値です。 Idが変更されているように見える場合、これは別の状態に関連付けられているためです。 新しい値は古い値の関数です。 ニューラルネットワークの各層の内部では、元のデータの状態は常に保持されます。 関数の出力である新しい値を持つデータの各セットは、独立して動作できます。 これは、これらのデータセットに対して安全に、または競合に関係なくアクションを実行できることを意味します。 いつでもデータの元の状態を参照することができます。 したがって、一貫性は、この場合、安全性を意味します。

ライブラリと制限

歴史的に、cortex machine learningライブラリには、Clojureで機械学習アルゴリズムを実装するために必要なものがすべて含まれています。 最近、オープンソースのmxnet framework for deep learningの人気が高まっているため、mxnet-Clojure APIを使用して深層学習を実装する方が簡単です。

ClojureにはさまざまなApiや機械学習ライブラリが利用可能になりましたが、それに堪能になるための急な学習曲線はまだあります。 エラーメッセージは不可解である可能性があり、企業は機械学習システムをスケールアップするためにそれを使用するために先行投資する意思がある 生産対応システムの例がClojureで書かれるようになると、clojureの使用に伴うライブラリの数とサイズが一貫して成長する場合に限り、この言語は今後数年

Haskell

Haskellは、型推論と遅延評価で静的に型付けされた関数型言語です。 これはMirandaプログラミング言語の意味論に基づいており、機械学習を実装するために、より表現力豊かで、より速く、より安全であると考えられています。

Haskellの型安全性は、安全性と柔軟性を提供します

型安全性は、変数が保持できる値の型に対する制約を定義します。 これは、不正な操作を防止し、メモリの安全性を向上させ、論理エラーを少なくするのに役立ちます。 遅延評価とは、Haskellが式の値が必要になるまで式の評価を遅延させることを意味します。 それはまた実行時間を節約する繰り返された評価を避ける。 同時に、遅延評価により、無限のデータ構造を定義することができます。 これはプログラマに無限の数学的可能性を与えます。

Haskellの単純な明示的なコードは、明確な実装を提供します

Haskellの最大の利点の一つは、非常に明示的な数学的構造でアルゴリズムを記述できることです。 モデルを数行のコードで表すことができます。 数学の方程式を読むのと同じ方法でコードを読むこともできます。 これは、機械学習の深層学習アルゴリズムなどの複雑なアルゴリズムで非常に強力です。 たとえば、フィードフォワードニューラルネットワークの単層の以下の実装は、コードがどれだけ読みやすいかを示しています。

import Numeric.LinearAlgebra.Static.Backproplogistic :: Floating a => a -> alogistic x = 1 / (1 + exp (-x))feedForwardLog :: (KnownNat i, KnownNat o) => Model (L o i :& R o) (R i) (R o)feedForwardLog (w :&& b) x = logistic (w #> x + b)

Source

Haskellのマルチコア並列処理はパフォーマンスを提供

深層学習では、典型的なニューラルネットワークには、モデルを定義する百万のパラメータが含まれ また、これらのパラメータを学習するためには大量のデータが必要であり、計算上は非常に時間がかかります。 単一のマシンで、複数のコアを使用してメモリとプロセスを並行して共有することは、深層学習の実装に関しては非常に強力です。 しかし、Haskellでは、マルチコア並列処理の実装は簡単です。

ライブラリと制限

HaskellのHLearnライブラリには機械学習アルゴリズムの実装が含まれていますが、haskellのtensor-flow bindingは深層学習に使用できます。 一方、並列処理と並行処理には並列処理と並行処理が使用されます。

Haskellで開発された機械学習ライブラリがいくつかありますが、実稼働対応のHaskell実装のためには、まだ地上実装を行う必要があります。 特定の深層学習や機械学習タスクに利用できる公共ライブラリは限られていますが、HASKELLのAIでの使用も制限されます。 Aetion TechnologiesやCredit Suisse Global Modeling and Analytics Groupなどの企業は、実装でHaskellを使用しています—ここでは、Haskellを使用している組織の完全なリストです。

結論

ディープラーニングモデルは、関数の特定の階層化を必要とする複雑な数学モデルです。 ClojureやHaskellなどの関数型プログラミング言語は、モデルの数学に近いクリーンなコードで複雑さを表現することができます。 これにより、時間の節約、効率化、およびコードベースの管理が容易になります。 関数型プログラミングの特定の特性は、これらの言語の実装が他の言語の実装よりも安全であることを可能にする。 AI技術の開発が進むにつれて、AIにおける大規模なシステム開発プロジェクトのニーズに合わせてこれらの言語を評価することがより一般的に

この記事は、開発者によるコードの背後にある、開発者のためのメディアの一部です。 コードの背後に訪問して、より多くの記事やビデオを発見!

貢献したいですか? 公開されます!

お楽しみにTwitterで私たちに従ってください!

ヴィクトリアルーセル

コメントを残す

メールアドレスが公開されることはありません。