LSTM ノート

Lstm は、改良されたリカレント ニューラル ネットワークである RNN の特殊な形式とみなすことができます。

RNN が長距離の依存関係を処理できないという問題を解決できます。

a134fc88798640889b03c1930cbc303c.png

 LSTM の具体的な特徴は、隠れ層が転送されるときのもう 1 つのユニット状態と 3 つのゲート (忘却ゲート、入力ゲート、出力ゲート) として要約できます。これらは元の RNN の隠れ層ユニットで連携して動作します。

279cdb65e0db4f08aec06b6e08dcd18a.png

 忘却ゲートは、eq?f_%7Bt%7D前のシーケンスの隠れた状態に作用しますeq?C_%7Bt-1%7D以前の時系列の隠れユニットの状態が現在の隠れユニットに及ぼす影響を判断します。

eq?f_%7Bt%7D*C_%7Bt-1%7D

入力ゲートは、eq?i_%7Bt%7D現在の隠れユニットの入力に作用しますeq?%5Ctilde%7BC%7D_%7Bt%7D(入力は前の隠れユニットの出力eq?h_%7Bt-1%7Dと現在の隠れユニットの入力です)。現在の隠れユニットに対する現在の入力の効果を決定します。

eq?%5Ctilde%7BC%7D_%7Bt%7D%3Dtanh%28W_%7BC%7D%5Ccdot%20%5Bh_%7Bt-1%7D%2CX_%7Bt%7D%5D+b_%7BC%7D%29

eq?i_%7Bt%7D*%5Ctilde%7BC%7D_%7Bt%7D

入力ゲートと組み合わせた忘却ゲートは現在の隠れ層状態出力を決定しeq?C_%7Bt%7D、出力ゲートはeq?o_%7Bt%7D現在の出力に作用して現在の隠れユニット出力を生成します。

eq?C_%7Bt%7D%3Df_%7Bt%7D*C_%7Bt-1%7D+i_%7Bt%7D*%5Ctilde%7BC%7D_%7Bt%7D

eq?h_%7Bt%7D%3Dtanh%28o_%7Bt%7D*C_%7Bt%7D%29

ここで、eq?f_%7Bt%7D%2Ci_%7Bt%7D%2Co_%7Bt%7Dは現在の隠れユニットの入力のすべての線形結合であり、シグモイド関数によって正規化されます。

eq?f_%7Bt%7D%3D%5Csigma%28W_%7Bf%7DX_%7Bt%7D+U_%7Bf%7Dh_%7Bt-1%7D+b_%7Bf%7D%29

eq?i_%7Bt%7D%3D%5Csigma%28W_%7Bi%7DX_%7Bt%7D+U_%7Bi%7Dh_%7Bt-1%7D+b_%7Bi%7D%29

eq?o_%7Bt%7D%3D%5Csigma%28W_%7Bo%7DX_%7Bt%7D+U_%7Bo%7Dh_%7Bt-1%7D+b_%7Bo%7D%29

1. Pytorch での Lstm 実装---torch.nn.lstm 関数

パラメータ:

  • input_size: 入力データの特徴数、上図の X の次元

  • hidden_​​size: 隠れユニットのサイズ、上図の h の次元

  • num_layer: 隠れ層の数。LSTMは空間内で複数の層に積み重ねることができます

  • バイアス:バイアス

  • 双方向: 双方向 LSTM かどうか

  • batch_first: 入力データを操作する場合、最初の次元としてバッチを使用します。

2. モデル入力データ全体は、(seq_len、batch、input_size) のサイズの 3 次元テンソルです。

  • seq_len: タイムステップ数。

これは、複数の単語を含む文を入力することに相当します。文の各単語が順番にモデルに入力され、時間内のステップが生成されます。通常、すべての文のパディングは固定長です

  • input_size: 入力データの特徴の数。これは入力隠れ単位データのサイズでもあり、各単語の特徴次元 (次元) に相当します。

  • バッチ: バッチサイズ。これは、モデルに一度に入力され、同時に処理される文の数に相当します。

たとえば、次の詩を入力します。

ガチョウ

クシアン・シャンティアンゲ

緑の水に浮かぶ白髪

アンスリウムは澄んだ波を起こす

各単語の特徴次元が 6 で、バッチ サイズが 4 に指定されているとします。

この例では、 seq_len=5 (最初の文は自動的に 5 文字に埋め込まれます)、batch=4、input_size=6 となります。

モデルに 4 文字が入力されるたびに、最初のバッチは「goose」、「qu」、「white」、「red」になります。

ここで疑問が生じます。これら 4 つの単語は同じ文内にありません。それらの隠された状態は互いに独立している必要があり、別の文内の次の連続する単語に影響を与えるべきではありません。

隠しユニット データを記録する 2 つのパラメーター h、c があります。h,c では、同じバッチ内の各文の各単語の状態 (タイミング) が個別に保存されます。

 

3. 入力データに加えて、入力モデルには各隠れユニットの 2 つの初期状態 ( )もあります。pytorch では、初期状態を初期化する必要がないことに注意してください。 eq?h_%7B0%7Deq?c_%7B0%7D

そのサイズは依然としてテンソルです

  • h0(レイヤー数*方向数,バッチ,隠しサイズ)

  • c0(レイヤー数*方向数,バッチ,隠しサイズ)

num_layers: LSTM 層の数、隠れユニットの層数 (空間次元)

hidden_​​size: 隠れユニットの次元 ( の次元)

バッチ: バッチサイズ

34a81d8bab3d426c8590505b80de5b92.png

別の次元であるバッチ (バッチ サイズ) は図には示されていませんが、実際には、同じバッチ内の異なる単語がそれぞれ独自のステータス データを持つことが保証されます。同じシーケンスを何回も繰り返すことを想像してみてください。

4. LSTM の出力データも、(seq_len,batch,num_directions*hidden_​​size) のサイズの 3 次元テンソルです。

コンテンツは、隠れユニットの最後の層の出力です。

パラメータの意味は上記と同じです

また、

5. 出力データには ( eq?h_%7Bn%7Deq?c_%7Bn%7D) も含まれており、n 番目の時系列の各隠れユニットのステータスが保存されます。

そのサイズは次のとおりです。

  • hn(レイヤー数*方向数,バッチ,隠しサイズ)

  • cn( num_layers*num_directions,バッチ,hidden_​​size)

パラメータの意味は上記と同じです

上の画像を90度回転させて、異なるタイミングに拡大してみます。入力、出力、隠れユニットの出力、および全体の状態を次の図に示します。

2264775370954c2295bdefaa225ecef2.png

 

 

6.呼び出し例:

     input_size=300、hidden_​​size=100、num_layers=1、batch_size=64、seq_len=7

3cfe278e617b495dbbaa881a0bcebebe.png

7.応用例

 

LSTM モデルをエンコーダー層として使用し、線形変換モデル (nn.Linear) をデコーダー層として結合して、感情分類モデルを実装します。

モデル作成のコード スニペットは次のとおりです。

class SentimentNet(nn.Module):
    def __init__(self, vocab_size, embed_size, num_hiddens, num_layers,
                 bidirectional, weight, labels, use_gpu, **kwargs):
        super(SentimentNet, self).__init__(**kwargs)
        self.num_hiddens = num_hiddens
        self.num_layers = num_layers
        self.use_gpu = use_gpu
        self.bidirectional = bidirectional
        self.embedding = nn.Embedding.from_pretrained(weight)
        self.embedding.weight.requires_grad = False
        self.encoder = nn.LSTM(input_size=embed_size, hidden_size=self.num_hiddens,
                               num_layers=num_layers, bidirectional=self.bidirectional,
                               dropout=0)
        if self.bidirectional:
            self.decoder = nn.Linear(num_hiddens * 4, labels)
        else:
            self.decoder = nn.Linear(num_hiddens * 2, labels)

    def forward(self, inputs):
        embeddings = self.embedding(inputs)
        states, hidden = self.encoder(embeddings.permute([1, 0, 2]))
        encoding = torch.cat([states[0], states[-1]], dim=1)
        outputs = self.decoder(encoding)
        return outputs

 

データ クリーニングやモデル トレーニングなどの他のコードについては、このプロジェクトを参照してください。

https://github.com/SamaelChen/machine-learning-practice-code/blob/master/pytorch/langage%20model/lstm-sentiment.ipynb

 

おすすめ

転載: blog.csdn.net/leyzhao_421587457/article/details/132419897