PyTorch:LSTMの基礎
はじめに
今回はNLPでよく使われるLSTMネットワークについて整理する。
自分で各ゲートのパラメータを記述した
Theano
に比べると簡単。下記のTutorialのコードを説明しながらLSTMの書き方について理解していく。
Sequence Models and Long-Short Term Memory Networks — PyTorch Tutorials 0.3.0.post4 documentation
今回はコードを日本語で説明しただけの備忘録的なもの。
Embedding
まずは、文章のEmbedding。
これは以下のように
nn.Embedding
で簡単に実現できる。
import torch import torch.autograd as autograd import torch.nn as nn torch.manual_seed(1) sent_idx = [1, 3, 2, 5, 3] vocab_size = 10 emb_dim = 5 embeds = nn.Embedding(vocab_size, emb_dim) lookup_tensor = torch.LongTensor(sent_idx) word_embed = embeds(autograd.Variable(lookup_tensor)) print(word_embed)
Variable containing: -0.1661 -1.5228 0.3817 -1.0276 -0.5631 0.2673 -0.4212 -0.5107 -1.5727 -0.1232 -0.8923 -0.0583 -0.1955 -0.9656 0.4224 -0.4791 1.3790 2.5286 0.4107 -0.9880 0.2673 -0.4212 -0.5107 -1.5727 -0.1232 [torch.FloatTensor of size 5x5]
文章単位で処理する場合、ベクトル→行列となる。
文章のEmbeddingは、以下のイメージ。
Tutorialでは、ネットワーク構築部で以下のようにしてEmbeddingしている。
self.word_embeddings = nn.Embedding(vocab_size, embedding_dim)
文章をバッチ化して処理する場合、行列→テンソルとなるが、内容は同じ。
今回は文章単位で処理するとして進めていく。
LSTM
Embeddingの行ベクトルが系列ごとにLSTM層に渡る。
イメージはこんな感じ。
nn.LSTM
のユニットは、入力・出力・忘却ゲートとメモリセルからなるので、実際は下記のような「隠れ層 ×(Embedding×4)」の重み行列で計算が展開される。
self.lstm = nn.LSTM(embedding_dim, hidden_dim)
線形変換
LSTM層の出力は「系列×隠れ層」の行列。
これを「系列×出力ラベル数」の行列に変換する。
※書くほどでも無いがこんな変換を行う。
self.hidden2tag = nn.Linear(hidden_dim, tagset_size)
ここからは他と同じなので割愛する。