Siri から Google 翻訳まで、ディープ ニューラル ネットワークは自然言語の機械理解において大きな進歩をもたらしました。これらのモデルのほとんどは、言語を単語や文字の単調なシーケンスとして捉え、そのシーケンスを処理するためにリカレント ニューラル ネットワーク (RNN) と呼ばれるモデルを使用します。しかし、多くの言語学者は、言語はツリー構造を持つ単語の階層として理解するのが最も適切であると信じており、再帰ニューラルネットワークと呼ばれるディープラーニングモデルはこの構造を考慮に入れており、この分野では多くの研究が行われてきました。これらのモデルは実装が非常に難しく非効率的ですが、新しいディープラーニング フレームワークである PyTorch を使用すると、これらのモデルやその他の複雑な自然言語処理モデルがはるかに簡単になります。 再帰型ニューラル ネットワークは PyTorch の柔軟性を示す良い例ですが、PyTorch は他の幅広いディープラーニング フレームワークもサポートしています。特に、コンピューター ビジョンの計算を強力にサポートします。 PyTorch は、Facebook AI Research と他のいくつかの研究室の開発者の成果です。このフレームワークは、Torch7 の効率的で柔軟な GPU アクセラレーション バックエンド ライブラリと直感的な Python フロントエンドを組み合わせたものです。迅速なプロトタイピング、読みやすいコード、幅広いディープラーニング モデルのサポートが特徴です。 SPINNを起動する リンク先の記事では、リカレント トラッカーと TreeLSTM ノードを備えたリカレント ニューラル ネットワーク (SPINN とも呼ばれる) の PyTorch 実装について詳しく説明しています。SPINN は、多くの一般的なフレームワークを使用して構築するのが難しい自然言語処理用のディープラーニング モデルの例です。ここでのモデル実装ではバッチ処理を使用しているため、GPU アクセラレーションを活用でき、バッチ処理を使用しないバージョンよりも大幅に高速に実行できます。 SPINN は Stack-augmented Parser-Interpreter Neural Network の略で、スタンフォード大学の SNLI データセットを使用して自然言語推論タスクを解決する方法として 2016 年に Bowman らによって導入されました。 タスクは、文のペアを 3 つのカテゴリに分類することです。文 1 が未表示の画像の正確なキャプションであると仮定すると、文 2 は (a) 間違いなく (b) おそらく、(c) 絶対に正確なキャプションではありませんか? (クラスはそれぞれ、含意、中立、矛盾と呼ばれます)。たとえば、ある文が「2 匹の犬が野原を走っている」であるとすると、含意によりこの文のペアは「屋外の動物」になり、中立性によりこの文のペアは「子犬が何匹か走って棒を捕まえようとしている」になり、矛盾によりこの文のペアは「ペットがソファーに座っている」になる可能性があります。 特に、SPINN を研究する最初の目標は、文間の関係を決定する前に、各文を固定長のベクトル表現にエンコードすることです (ソフト フォーカス方式で各文の各部分を互いに比較する注意モデルなど、他の方法もあります)。 データセットは、構文解析ツリー法を使用して機械的に生成されます。構文解析ツリーは、各文の単語を独立した意味を持つ句と節にグループ化し、各句は 2 つの単語またはサブフレーズで構成されます。多くの言語学者は、人間は上記のツリーのように階層的に単語の意味を組み合わせることで言語を理解していると信じており、同じようにニューラル ネットワークを構築してみる価値はあります。次の例はデータセットからの文であり、その解析ツリーはネストされた括弧で表されます。
この文をエンコードする 1 つの方法は、構文解析ツリーを持つニューラル ネットワークを使用してニューラル ネットワーク レイヤー Reduce を構築することです。このレイヤー Reduce は、単語のペア (GloVe などの単語埋め込みによって表される) やフレーズを組み合わせて、このレイヤー (関数) を再帰的に適用し、最後の Reduce の結果を文のエンコードとして使用します。
しかし、ネットワークをもっと人間らしく動作させ、左から右に読み、文章の文脈を保ちながら、構文解析木を使ってフレーズを組み立てたい場合はどうでしょうか。あるいは、ネットワークが独自の構文解析木を構築し、見た単語に基づいて文章を読むようにトレーニングしたい場合はどうでしょうか。同じ構文解析木が少し違った形でどのように見えるかを以下に示します。
あるいは、3 番目の方法で表現すると次のようになります。
私がやったことは、開き括弧を削除し、「shift」を「S」でマークし、閉じ括弧を「reduce」の「R」に置き換えただけです。しかし、今では、スタックとスタックのようなバッファを操作するための一連の命令として情報を左から右に読み取ることができ、上記の再帰的な方法とまったく同じ結果を得ることができます。
また、文のコンテキストを保持して、Reduce レイヤーを文の後半に適用するときに、システムがすでに読み取った文の部分に関する情報を考慮に入れるようにしたいと考えています。そこで、2 つの引数を持つ Reduce 関数を、左節、右節、現在の節のコンテキスト状態を入力値とする 3 つの引数を持つ関数に置き換えます。この状態は、ニューラル ネットワークの 2 番目の層、リカレント トラッカーと呼ばれるユニットによって作成されます。トラッカーは、現在の文のコンテキスト状態、バッファ内の先頭エントリ b、およびスタック内の最初の 2 つのエントリ s1\s2 に基づいて、スタック操作の各ステップ (つまり、各単語または閉じ括弧の読み取り) の後に新しい状態を生成します。
これらのことを実行するには、お気に入りのプログラミング言語でコードを記述することが容易に想像できます。処理する文ごとに、バッファから次の単語をロードし、トラッカーを実行し、単語をスタックにプッシュするか、Reduce 関数を実行するかをチェックし、その操作を実行し、文全体が処理されるまでこれを繰り返します。このプロセスを単一の文に適用すると、2 つのトレーニング可能なレイヤーをスタッキング操作で何度も適用して、大規模で複雑なディープ ニューラル ネットワークが構築されます。しかし、TensorFlow や Theano などの従来のディープラーニング フレームワークに精通している場合は、このような動的なプロセスを実装するのが難しいことをご存知でしょう。少し時間を取って、PyTorch が他と異なる理由を確認し、検討してみる価値があります。 図1: 関数のグラフ表現 ディープ ニューラル ネットワークは、本質的には多数のパラメータを持つ複雑な関数です。ディープラーニングの目的は、損失関数 (損失) によって測定された偏微分 (勾配) を計算することで、これらのパラメータを最適化することです。関数が計算グラフ構造 (図 1) として表現されている場合、グラフを逆方向に走査することで、冗長な作業なしでこれらの勾配を計算できます。現代のディープラーニング フレームワークはすべてこのバックプロパゲーションの概念に基づいているため、すべてのフレームワークには計算グラフを表す方法が必要です。 TensorFlow、Theano、Keras、Torch7 の nngraph ライブラリなど、多くの一般的なフレームワークでは、計算グラフは事前に構築された静的オブジェクトです。グラフは数式のようなコードを使用して定義されますが、その変数は実際にはまだ値を保持していないプレースホルダーです。図のプレースホルダー変数は関数にコンパイルされ、トレーニング セットのバッチで繰り返し実行して出力と勾配値を生成できます。 この静的計算グラフ方式は、固定構造を持つ畳み込みニューラル ネットワークに適しています。しかし、他の多くのアプリケーションでは、ニューラル ネットワークのグラフ構造をデータに応じて変化させることが有用です。自然言語処理では、研究者は多くの場合、各タイムステップで入力された単語によってリカレントニューラルネットワークを展開(決定)する必要があります。上記の SPINN モデルのスタック操作は、特定の文の計算グラフ構造を定義するために、制御フロー (for ステートメントや if ステートメントなど) に大きく依存しています。より複雑なケースでは、モデル自体のサブネットワークの出力に応じて構造が変化するモデルを構築する必要があるかもしれません。 これらのアイデアの一部 (すべてではない) は静的グラフ システムに無理やり組み込むことができますが、ほとんどの場合、透明性が低下し、コードの難読化が進むという代償を伴います。フレームワークは、ループや条件文などのプログラミング プリミティブを表す特別なノードを計算グラフに追加する必要があり、ユーザーはプログラミング コード言語の for ステートメントや if ステートメントだけでなく、これらのノードを学習して使用する必要があります。これは、プログラマーが使用する制御フロー ステートメントは 1 回だけ実行され、プログラマーはグラフを構築するときに単一の計算パスをハード コードする必要があるためです。 たとえば、単語埋め込み(初期状態 h0 から開始)を介して再帰型ニューラル ネットワーク ユニット (rnn_unit) を実行するには、TensorFlow の特別な制御フロー ノード tf.while_loop が必要です。コード実行時の単なるプレースホルダーであるため、実行時に単語の長さを取得するには追加の特別なノードが必要です。
動的計算グラフに基づくアプローチは、これまでのアプローチとは根本的に異なり、ハーバード大学の Kayak、自動微分化ライブラリ (autograd)、研究中心のフレームワーク Chainer や DyNet など、数十年にわたる学術研究の歴史があります。このようなフレームワーク (define-by-run とも呼ばれます) では、計算グラフは実行時に構築および再構築され、同じコードを使用してフォワード パスの計算を実行すると同時に、バックプロパゲーションに必要なデータ構造も構築されます。このアプローチでは、制御フローを標準の for および if ステートメントを使用して記述できるため、より簡単なコードが生成されます。また、実行時のブレークポイントやスタック トレースが実行エンジン内のコンパイルされた関数ではなく、実際に記述されたコードにトレースされるため、デバッグも容易になります。同じ可変長の再帰型ニューラル ネットワークは、単純な Python for ループを使用して動的フレームワークに実装できます。
PyTorch は、TensorFlow などの静的グラフ フレームワークのパワーとパフォーマンスに匹敵する、実行時に定義する初のディープラーニング フレームワークであり、標準的な畳み込みネットワークから最もワイルドな強化学習まで、さまざまなアイデアに適しています。それでは、SPINN の実装を見てみましょう。 コード ネットワークの構築を始める前に、データ ローダーを設定する必要があります。ディープラーニングを使用すると、モデルはデータサンプルのバッチで動作し、並列処理によってトレーニングを高速化し、各ステップでよりスムーズな勾配変化を実現できます。ここでこれができると思います(上記のスタック操作処理をバッチ処理する方法については後ほど説明します)。次の Python コードは、PyTorch のテキスト ライブラリに組み込まれた、同様の長さのデータ サンプルを連結してバッチを自動的に生成するシステムを使用してデータをロードします。このコードを実行すると、train_iter、dev_iter、test_iter には、SNLI のバッチのトレーニング、検証、テストの各チャンクを反復処理するループが含まれます。
トレーニング ループと精度測定を設定するための残りのコードは train.py にあります。続けましょう。前述のように、SPINN エンコーダーには、パラメーター化された Reduce レイヤーと、文のコンテキストを追跡するためのオプションの再帰トラッカーが含まれており、ネットワークが単語を読んだり Reduce を適用したりするたびに、隠れ状態が更新されます。次のコードは、SPINN を作成するということは、これらの 2 つのサブモジュール (そのコードは後ほど説明します) を作成し、後で使用するためにコンテナーに配置するだけであることを示しています。
SPINN.__init__ は、モデルの作成時に 1 回呼び出されます。パラメータを割り当てて初期化しますが、ニューラル ネットワーク操作を実行したり、計算グラフを構築したりすることはありません。新しいデータ バッチごとに実行されるコードは、SPINN.forward メソッドによって定義されます。これは、モデルのフォワード パスを定義するユーザー実装メソッドの標準的な PyTorch 名です。上記は、スタック操作アルゴリズムの効率的な実装です。つまり、一般的な Python では、各例ごとに 1 つずつ、バッファーとスタックのコレクションに対して操作を行います。遷移マトリックスに含まれる「シフト」および「削減」操作のセットを反復処理し、トラッカー (存在する場合) を実行し、バッチ内の各サンプルを反復処理して「シフト」操作を適用するか (要求された場合)、「削減」操作が必要なサンプルのリストに追加します。次に、このリスト内のすべてのサンプルに対して Reduce レイヤーが実行され、結果がそれぞれのスタックにプッシュバックされます。
self.tracker または self.reduce を呼び出すと、それぞれ Tracker または Reduce サブモジュールの forward メソッドが実行され、サンプルのリストに forward 操作を適用する必要があります。メイン関数の forward メソッドでは、バッチ実行のメリットを享受するすべての数学的負荷の高い操作と GPU アクセラレーション操作が Tracker と Reduce で実行されるため、異なるサンプルに対して独立して操作する、つまりバッチ内の各サンプルに個別のバッファーとスタックを用意することが理にかなっています。これらの関数をよりきれいに記述するために、いくつかのヘルパー (後ほど定義します) を使用して、これらのサンプルのリストをバッチ テンソルに変換したり、その逆を行ったりします。 Reduce モジュールで引数を自動的にバッチ処理して計算を高速化し、その後バッチ処理を解除して個別にプッシュおよびポップできるようにしたいと思います。左と右のサブフレーズ表現の各ペアを親フレーズに結合するために使用される実際の結合関数は TreeLSTM であり、これは通常の再帰型ニューラル ネットワーク ユニット LSTM のバリエーションです。組み合わせ関数では、各サブフレーズの状態が実際には 2 つのテンソル (隠し状態 h とメモリ セル状態 c) で構成されている必要があり、関数はサブフレーズ隠し状態で動作する 2 つの線形レイヤー (nn.Linear) と、線形レイヤーの結果とサブフレーズのメモリ セル状態を組み合わせる非線形組み合わせ関数 tree_lstm を使用します。 SPINN では、トラッカーの隠し状態で動作する 3 番目の線形レイヤーを追加することで、このアプローチが拡張されます。 図 2: TreeLSTM コンバイナー関数は 3 番目の入力 (x、この場合は Tracker 状態) を追加します。以下に示す PyTorch 実装では、3 つの線形変換の 5 つのグループ (青、黒、赤の矢印の 3 つで表されます) が 3 つの nn.Linear モジュールに結合され、tree_lstm 関数がボックス内のすべての計算を実行します。 Chen et al. (2016) の図。
Reduce レイヤーと Tracker の同様の実装は LSTM で動作するため、バッチ処理とアンバッチ処理のヘルパー関数は、隠し状態とメモリ状態のペア (h,c) に対して動作します。
それだけです。残りの必要なコード (Tracker を含む) は spinn.py にありますが、2 つの文のエンコーディングから SNLI カテゴリを計算し、最終的な損失変数を与えられたターゲットとこの結果を比較する分類子レイヤーは model.py にあります。 SPINN とそのサブモジュールのフォワード コードは非常に複雑な計算グラフ (図 3) を生成します。このグラフは最終的に、データセット内のバッチごとに詳細が完全に異なる損失関数を計算しますが、グラフ内の任意のポイントからバックプロパゲーションを実行できる PyTorch に組み込まれた関数 loss.backward() を呼び出すことで、わずかなオーバーヘッドで毎回自動的にバックプロパゲーションを実行できます。 完全なコード内のモデルとハイパーパラメータは、オリジナルの SPINN 論文で報告されたパフォーマンスと一致しますが、バッチ処理と PyTorch の効率性を活用することで、GPU 上で数倍高速にトレーニングされます。元の実装では計算グラフのコンパイルに 21 分かかり (実装中のデバッグ サイクルが少なくともそのくらい長かったことを意味します)、その後トレーニングに約 5 日かかりますが、ここで説明するバージョンにはコンパイル ステップがなく、トレーニングには Tesla K40 GPU で約 13 時間、Quadro GP100 で約 9 時間かかります。 図 3: この論文で提供されている Chainer コードのバージョンを実行している、バッチ サイズ 2 の SPINN 計算グラフの一部。 強化学習のすべて 上記のトラッカーなしのモデルのバージョンは、動的グラフに特化した TensorFlow の新しい tf.fold ドメイン固有言語に実際に適していますが、トラッカー付きのバージョンは実装が困難です。これは、トレーサーを追加すると、再帰的なアプローチからスタックベースのアプローチに切り替えることになるためです。これは、入力値に依存する条件分岐を使用して実装するのが最も簡単です。しかし、Fold には条件分岐操作が組み込まれていないため、これを使用して構築されたモデルのグラフ構造は、入力の値ではなく入力の構造にのみ依存します。さらに、入力サンプルが読み込まれると Fold のグラフ構造は完全に固定される必要があるため (グラフ構造は入力サンプルの構造に依存する)、トラッカーが入力文を読みながら解析する方法を決定する SPINN バージョンを構築することはできません。 そのようなモデルの 1 つは、DeepMind と Google Brain の研究者によって研究されました。研究者らは強化学習を適用して、SPINN トラッカーをトレーニングし、外部の解析データを使用せずに入力文を解析できるようにしました。本質的に、このようなモデルはランダムな推測から始まり、その解析によって全体的な分類タスクで良好な精度が得られると、自己報酬を生成し、その報酬を通じて学習します。研究者らは、「ポリシー ネットワークからの各サンプルごとに計算グラフを各反復で再構築する必要があるため、バッチ サイズを 1 にしました [Tracker]」と書いていますが、PyTorch を使用すると、ランダムに変化する構造を持つこのような複雑なネットワークでバッチ トレーニングを実行できます。 PyTorch は、確率的計算グラフの形式で強化学習 (RL) ライブラリを構築する最初のフレームワークでもあり、ポリシー勾配強化学習をバックプロパゲーションと同じくらい簡単に使用できるようになります。これを上記のモデルに追加するには、メインの SPINN for ループの最初の数行を次のように書き換えるだけで、Tracker が解析された各遷移マトリックスを作成する確率を定義できるようになります。
次に、バッチが実行され、モデルがクラスの予測精度を把握すると、これらのランダム計算グラフのノードを通じて報酬信号を送信し、従来の方法でグラフの残りの部分をバックプロパゲートできます。
Google の研究者は、強化学習を組み込んだ SPINN の結果が、SNLI データセットにおけるオリジナルの SPINN よりもわずかに優れていると報告しています。ただし、強化学習バージョンでは、事前に計算された解析ツリー情報を使用していません。自然言語処理のための深層強化学習の分野は新しく、この分野の研究テーマは非常に広範囲にわたります。PyTorch は強化学習をフレームワークに組み込むことで、参入障壁を大幅に下げました。 今すぐPyTorchを使い始めましょう pytorch.org Web サイトのインストール手順に従って、プラットフォームを選択します (Windows サポートは近日中に開始されます)。 PyTorch は Python 2 および 3 をサポートし、CUDA 7.5 または 8.0 と CUDNN 5.1 または 6.0 を使用した CPU または NVIDIA GPU での計算をサポートします。 conda および pip 用の Linux バイナリがあり、CUDA 自体も含まれているため、自分で設定する必要はありません。 公式チュートリアルには、Deep Q-Learning (最新の強化学習モデル) の 60 分間の紹介とウォークスルーが含まれています。スタンフォード大学のジャスティン・ジョンソン教授は非常に包括的なチュートリアルを公開しており、公式の例には、Deep Convolutional Generative Adversarial Network (DCGAN)、ImageNet モデル、ニューラル機械翻訳モデルも含まれています。シンガポール国立大学の Richie Ng 氏は、その他の PyTorch 実装、例、チュートリアルの最新リストを作成しました。 PyTorch 開発者およびユーザー コミュニティは、ディスカッション フォーラムでいつでも喜んで質問にお答えしますが、必ず最初に API ドキュメントを確認してください。 PyTorch はまだ使用されて間もないですが、3 つの研究論文で使用されており、いくつかの学術研究室や産業界の研究室でも PyTorch が採用されています。動的計算グラフが今日ほど知られていなかった当時、私と Salesforce Research (https://metamind.io/research.html) の同僚は Chainer を秘密のソースだと考えていました。現在、大企業の支援を受けて、PyTorch がこのレベルのパワーと柔軟性を主流にもたらすことに興奮しています。 |
<<: 畳み込みニューラル ネットワークの実践 - Keras を使用して猫を識別する
>>: Caffeでのディープラーニングトレーニングの全プロセス
[[431145]]過去1年間、COVID-19パンデミックにより、多くの業界が開発戦略を再考し、変...
[51CTO.com クイック翻訳]フィリップ・K・ディックの1968年の小説『アンドロイドは電気羊...
[[410183]] 7月8日のニュース 2021年世界人工知能大会の開幕式で、工業情報化部の肖亜青...
今日の AI 顔認識アルゴリズムは完璧ではありません。あなたの会社がこのテクノロジーの導入を検討して...
編集者注:この記事は、WeChatのパブリックアカウント「New Intelligence」(ID:...
フォレスターのアジア太平洋地域における 2022 年の予測によると、地域特有の圧力により、どこからで...
無人運転車による配達に続き、ドローンによる食品配達も現実化に向かって加速している。先日終了した202...
人工知能は、人間の知能をシミュレート、拡張、拡大するための理論、方法、技術、アプリケーション システ...
今日のサイバーセキュリティの脅威がますます深刻化する中、セキュリティ オペレーション センター (S...
昨年から、AIの普及に関わる仕事がたくさん必要になりました。私は長い間、ディープラーニングがなぜ特に...