pytorch ケース コード 3

双方向リカレント ニューラル ネットワーク
双方向リカレント ニューラル ネットワークは、RNN/LSTM/GRU で利用できます。たとえば、RNN セルでは、線形変換のために h0 と x1 を渡すだけで h1 が生成され、線形変換のために同じセルに引き続き渡されます。線形変換の W と b は共有され、すべての隠れ層と最終出力はそれに沿って計算されます。この方向に。
次に、Xn-1の出力などの各ノードは、その以前の情報のみを考慮します。つまり、過去のすべての情報のみを考慮しますが、実際には自然言語で、将来の情報も考慮する必要がある場合があります。単語はそれに続く単語に影響を与えます。そこで双方向巡回ニューラルネットワークは、seqlenの順方向(勾配の順方向とは異なり、ここでは数列の順方向計算)の後に逆方向があり、それから再度逆方向に計算し、計算結果をつなぎ合わせます。フォワードで最終結果を取得します。
写真の説明を追加してください
逆方向で別の計算を行うと、順方向と逆方向の結果が結合されます. たとえば、HN には [H1(b), HN(f)] が含まれ、HN-1 には [H2(b), HN-1(f )] が含まれます. 逆方向計算の最終結果は HN(b) です. たとえば, GRU が呼び出されると, out と hidden が出力されます. hidden は, 順方向と逆方向の最終結果 HN(f) と HN(b) の連結です. out それ上記のすべての隠れ層 h0 から hN 出力です。
したがって、双方向ネットワークの場合、最終的な出力の隠れ層は前のものの 2 倍のサイズになり、出力も接合されるため、サイズも 2 倍になります。
写真の説明を追加してください
写真の説明を追加してください

リカレント ニューラル ネットワーク - リカレント ニューラル ネットワーク分類器を実装して
、名前の分類の問題を解決します。18 言語の何千もの人の名前でトレーニングされたモデルは、スペルに基づいて人の名前がどの言語に属しているかを予測できます。写真の説明を追加してください
姓の分類のみを考慮しているため、モデルはより単純になります. 下の図 1 から図 2 まで、最終的な隠れ層の状態のみを考慮し、完全な接続を介して 18 のカテゴリに分割します.
写真の説明を追加してください
写真の説明を追加してください
そして定義モデルを gru を使うように変更したところ、x は 1 つのデータしか持たないように見えますが、実際には x1、x2、x3... という複数の単語で構成されて単語を形成しています。 x1、x2、x3... のようなシーケンスの場合、名前の長さが異なるため、入力も異なります.これは、考慮する必要があることです.
写真の説明を追加してください




独自に定義した分類子 RNNClassfier を使用し、渡されるパラメータは、渡された文字数 (名前の文字数)、隠れ層の数 (gru の出力結果のサイズ)、分類の数です。 、および使用される gru の層数。
次のコードは、定義された time_since 関数に渡すことができる時間変数を定義し、トレーニング開始からのトレーニング時間の長さを出力します。
ループでは、トレーニング パッケージとテスト パッケージを個別に呼び出し、テスト結果をリストに追加して、記録された精度を描画に使用できるようにします。

写真の説明を追加してください
写真の説明を追加してください


データの準備としては、入力がシーケンスなので、まず文字列を文字に変換する必要があります.文字はASCIIに対応できるので、128次元のASCIIテーブルを使用することもできます.埋め込みレイヤーにそれを伝えるだけで済みます.各文字は、ワンホット ベクトルの最初の次元が 1 に対応します。埋め込みレイヤーを使用して、それを密な形式に変換できるため、ASCII コード値を渡すだけで済みます。
データの長さが異なるため, パディングも行う必要があります. トレーニング入力は個々のデータで構成されたbatch_sizeだからです. この種の長さの異なるデータはテンソルバッチ操作を形成できません. パディングの長さは最長の文字列. .
国名も索引付けする必要があります。
写真の説明を追加してください
写真の説明を追加してください
写真の説明を追加してください


名前のデータ読み込みに関しては、数千の名前はメモリをあまり消費しないため、一度に読み込むことができます.もちろん、それらすべてを一度にテンソルに変換すると、データ量は比較的大きくなります. . is_train_set を渡して、トレーニング セットとテスト セットのどちらを読み取るかを決定します。gz は Linux の圧縮ファイル形式であり、gzip を介して圧縮パッケージを読み取ることができます。
csv のすべての行を行に読み取り、各行は名前と国を含むタプルであり、名前と国を読み取ります。国はインデックスを作成する必要があるため、set を使用してリストをコレクションに変換し、重複する要素を削除してから、並べ替えてリストを作成し、getCountryDict を呼び出してリストを上の図のインデックス ディクショナリに変換します。 getitem でインデックスにアクセスし、対応するインデックスに名前と国を出力できます。
写真の説明を追加してください
写真の説明を追加してください
写真の説明を追加してください
パラメータは下の図に示されています. データの各バッチのサイズは 256 であり, 隠れ層のサイズは 100 であり, 2 層の gru は 100 ラウンドのトレーニングに使用されます. 文字の長さは に従って 128 に設定されます.アスキーコード。
写真の説明を追加してください



モデルの設計については、渡されたパラメータを見てください。hidden_​​size は GRU の入力と出力のサイズ、n_layers は GRU の層の数、input_size (入力辞書の長さを表す) と hidden_​​size も構成パラメータです。埋め込み層. 埋め込み層の構築パラメータを忘れないでください. 入力パラメータとは概念が異なります. 構築パラメータは, 埋め込み層を構築するときに使用されます. 入力パラメータは, 埋め込み層を構築するときに使用されるデータパラメータです.入力データを処理します. 入力パラメータを図 2 に示します. bidirectional このパラメーターは、GRU が単方向か双方向かを示すために使用されます。最後に、hidden_​​size を output_size に変換するには完全な接続が必要です。双方向の場合は、n_bidirections を掛ける必要があります。次に、h0 を初期化する機能がありますが、GRU の層が複数ある場合は、構築時に H0 に n_layers を掛ける必要があることに注意してください。

写真の説明を追加してください

写真の説明を追加してください
写真の説明を追加してください




次に進む過程を見る.まずデータを転置する.このとき,二次元行列は横にバッチ,縦にseqされ,入力データは(batch_size, seq_len)から(seq_len,batch_size)に変換され,これは、埋め込みレイヤーが必要とするものであるため、最初の隠れレイヤーを構築するために、batch_size データを保存します。
その後、データを埋め込みレイヤーに投入すると、データは (seq_len, batch_size, hidden_​​size) に変換されます
. 以下では、pytorch が提供する pack_padded_sequence 関数を使用します. 意味解析に LSTM, GRU または RNN を使用する場合、この関数は次の場合に使用できます.データ長が異なります.短いデータは0で埋められ、これらのデータは操作に参加する必要がないため、操作を高速化します.
図 3 ~ 5 に示すように、パディング後のデータは、最初に長さで並べ替える必要があり、並べ替え後に埋め込みレイヤーを介して密なベクトルに変換する必要があります. データを取得した後、関数に渡してパックし、処理のために GRU に渡される最終的な PackedSquence オブジェクト 操作は、必要な最終結果を取得しますが、これは非表示になっています。
ダブルブレーク リカレント ニューラル ネットワークの場合、2 つ隠れていることに注意してください。したがって、これら 2 つをつなぎ合わせ、最終的に fc 層に配置して、必要な次元に変換する必要があります。
写真の説明を追加してください
写真の説明を追加してください

写真の説明を追加してください
写真の説明を追加してください
写真の説明を追加してください



次に、データ処理プロセスを見てください. データはテンソルに変換する必要があり、埋め込み層ではすべてのデータが長整数である必要があります。まず name2list は次のようになります. 各名前をリストにします. 各文字のアスキーコード値を取り出してアスキーコードリストを生成し, 名前に対応するリストとそのタプルを返します.リストの長さ。
def name2list(name):
	arr = [ord(c) for c in name]
	return arr, len(arr)

次に、名前と長さを別々に 2 つのリストに抽出し、長さを長整数に変換します.名前に対応する国は整数として渡されるので、そのまま長整数に変換されます.
次のステップはパディング プロセスです. 最初にすべて 0 のテンソルを作成し、コピー操作を使用して名前リストをすべて 0 のテンソルに貼り付けます。
パディングが行われた後、シーケンスの長さに従ってソートされ、ソートによって得られたインデックス添え字で名前と国がソートされます。最後に、gpu を使用するかどうかの判断関数を介してデータが出力されます。
写真の説明を追加してください



次に、以前とあまり変わらないトレーニング プロセスがあります。検定の流れは前回と同じで、分類器が完成したら、確率が最も高い国を探し、正解数の合計を計算します。

写真の説明を追加してください
写真の説明を追加してください

トレーニング結果は次のとおりです. トレーニングが 20 ラウンドに達したときに最良の結果が得られることがわかります. model.save を使用して保存し、現在のモデルが最高の正解率を持っているかどうかをテストできます. 最高の場合,現在のモデルを保存します。
写真の説明を追加してください



PS: 詩を書くためのモデル、またはタイトルに基づいてエッセイを書くためのモデルなどのモデルをトレーニングした場合、固定値を入力するたびに同じ結果を得たくない場合は、 「重要度サンプリング」は、線形層の出力が各結果の確率であるためです. 確率が最も高い結果を毎回使用する必要があります. 重要度サンプリングを使用すると、確率の低い結果を採用することができますが、比較的いわば確率の高い方が選ばれやすいので、入力内容は同じで、値によって結果が異なる場合があります。

おすすめ

転載: blog.csdn.net/weixin_43739821/article/details/128052368