1. LSTM構造を定義する
bilstm = nn.LSTM(input_size=10, hidden_size=20, num_layers=2, bidirectional=True)
入力サイズが10、非表示サイズが20の2層双方向LSTMを定義します。
注:LSTMの構造が定義された後、同じプログラムの下のinput_size、hidden_size、num_layersはここと同じになります。
2.入力フォーマット
公式ドキュメント:
input = torch.randn(5, 3, 10)#(seq_len, batch, input_size)
(1)入力するデータが1次元データの場合:
seq_len各バッチに入力されるデータの量を示します
バッチデータがバッチに分割されていることを示します
input_sizeこの時点では1です。
たとえば、
元のデータデータ= 1,2,3,4,5,6,7,8,9,10の合計10サンプルがあり、これらのデータは処理のためにLSTMに入れられます。処理する前に、データフォームを変換する必要があります。最初にseq_lenを3に設定します。このときのデータフォームは
、1-2-3、2-3-4、3-4-5、4-5-です。 6、5-6-7、6-7-8、7-8-9、8-9-10、9-10-0、10-0-0(最後の2つのデータは不完全であり、ゼロパディングが実行されます)
次に、batch_sizeを2に設定します。
次に、最初のバッチを1-2-3、2-3-4として取り出します。このバッチのサイズは(2、3、1)です。これをモデルにフィードします。
次のバッチは3-4-5、4-5-6です。
3番目のバッチは5-6-7、6-7-8です。
4番目のバッチは7-8-9、8-9-10です。
5番目のバッチは9-10-0、10-0-0です。データでは合計5つのバッチが生成されました。
(2)入力するデータが2次元データの場合
seq_len各バッチに入力されるデータの量を示します
バッチデータがバッチに分割されていることを示します
input_size各データを表す属性ベクトルの長さ
たとえば、次のとおりです。
data_ = [[1, 10, 11, 15, 9, 100],
[2, 11, 12, 16, 9, 100],
[3, 12, 13, 17, 9, 100],
[4, 13, 14, 18, 9, 100],
[5, 14, 15, 19, 9, 100],
[6, 15, 16, 10, 9, 100],
[7, 15, 16, 10, 9, 100],
[8, 15, 16, 10, 9, 100],
[9, 15, 16, 10, 9, 100],
[10, 15, 16, 10, 9, 100]]
seq_len = 3、バッチ= 2、input_size = 6の
場合、最初のバッチは次のようになります。
tensor([[[ 1., 10., 11., 15., 9., 100.],
[ 2., 11., 12., 16., 9., 100.],
[ 3., 12., 13., 17., 9., 100.]],
[[ 2., 11., 12., 16., 9., 100.],
[ 3., 12., 13., 17., 9., 100.],
[ 4., 13., 14., 18., 9., 100.]]])
最後のバッチは次のとおりです。
tensor([[[ 9., 15., 16., 10., 9., 100.],
[ 10., 15., 16., 10., 9., 100.],
[ 0., 0., 0., 0., 0., 0.]],
[[ 10., 15., 16., 10., 9., 100.],
[ 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0.]]])
3.出力フォーマット
公式ドキュメント:
メモ:
出力形状は(seq_len、batch、num_directions * hidden_size):このテンソルには、LSTMの最後の層の各サイクルの出力特性(h_t)が含まれています。双方向LSTMの場合、各タイムステップの出力h = [hフォワード、hリバース](同じタイムステップのフォワードとリバースhが接続されます)
h_n各レイヤーは、最後のタイムステップの出力hと共に保存されます。双方向LSTMの場合、順方向と逆方向の最後のタイムステップの出力hは別々に保存されます。
c_ncの値を保存することを除いて、h_nと同じ
分析:
出力3次元テンソルです。最初の次元はシーケンスの長さを表し、2番目の次元はサンプルのバッチ(バッチ)を表し、3番目の次元はhidden_size(非表示のレイヤーサイズ)* num_directionsです。num_directionsは、「双方向」かどうかに基づいています1または2です。したがって、出力の3番目の次元のサイズは、双方向であるかどうかに応じて変化します。双方向ではない場合、3番目の次元は、定義する非表示レイヤーのサイズと等しくなります。双方向の場合、3番目の次元のサイズは2と等しくなります。非表示レイヤーのサイズ。
h_n3次元テンソルです。最初の次元はnum_layers num_directions、num_layersは定義したニューラルネットワークのレイヤー数です。num_directionsは上記で紹介したもので、値は1または2で、双方向LSTMかどうかを示します。2番目のディメンションは、バッチのバッチサイズを表します。3番目の次元は、非表示レイヤーのサイズを表します。最初の次元は、h_nを理解するのが難しい場所です。最初に、現在のLSTMを単方向LSTMとして定義し、最初の次元のサイズはnum_layersです。これは、n番目のレイヤーの最後のタイムステップの出力を表します。双方向LSTMの場合、最初の次元のサイズは2 * num_layersです。この時点でも、次元は各層の最後のタイムステップの出力を表しており、最後のタイムステップの出力は、順方向操作と逆方向操作で使用されます。この次元の1つ。
例:双方向LSTMをnum_layers = 3で定義します。h_nの最初の次元のサイズは6(2 3)に等しく、h_n [0]は最初のレイヤーの順方向伝播の最後のタイムステップの出力h_n [1を意味します]最初のレイヤーの後方伝播の最後のタイムステップの出力を表し、h_n [2]は2番目のレイヤーの前方伝播の最後のタイムステップの出力を表し、h_n [3]は2番目のレイヤーの後方伝播の最後のタイムステップの出力を表します、H_n [4]およびh_n [5]は、それぞれ第3レイヤーの最後のタイムステップの出力を順方向および逆方向伝播で表します。
c_n構造はh_nと同じであるため、ここでは繰り返さない。
4.いくつかのパラメーターの理解
seq_lenここでのinput_sizeは、単語またはデータを記述するときに使用されます。これにより、単語またはデータをマシンがより簡単に理解できるようになります。
バッチ バッチ処理とは、トレーニングバッチごとにパラメータを更新することを指します。データをバッチに分割してデータを更新するのではなく、1つずつ更新すると、計算量が多すぎて時間がかかりすぎます。計算全体が完了してからパラメータを更新すると、最終的にはエラーが大きくなります。
5.一緒にリストする
input(seq_len,batch,input_size)
rnn = torch.nn.LSTM(input_size,hidden_size,num_layers)
h0(num_layers*num_directions,batch,hidden_size)
c0(num_layers*num_directions,batch,hidden_size)
output(seq_len,batch,num_direction*hidden_size)
hn(num_layers*num_directions,batch,hidden_size)
cn(num_layers*num_directions,batch,hidden_size)