implement LSTM for multivariate input in Pytorchを使用します。
この記事に続いて https://machinelearningmastery.com/how-to-develop-lstm-models-for-time-series-forecasting/ ケラスを使用して、入力データは(number ofサンプル、タイムステップの数、並列フィーチャの数)
_in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90])
in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95])
out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))])
. . .
Input Output
[[10 15]
[20 25]
[30 35]] 65
[[20 25]
[30 35]
[40 45]] 85
[[30 35]
[40 45]
[50 55]] 105
[[40 45]
[50 55]
[60 65]] 125
[[50 55]
[60 65]
[70 75]] 145
[[60 65]
[70 75]
[80 85]] 165
[[70 75]
[80 85]
[90 95]] 185
n_timesteps = 3
n_features = 2
_
ケラスではそれは簡単なようです:
model.add(LSTM(50, activation='relu', input_shape=(n_timesteps, n_features)))
最初のレイヤーとしてLSTMの_n_features
_を作成し、それぞれを個別にフィードして(シーケンスの複数のストリームとして想定)、出力を線形レイヤーに平坦化する以外の方法でそれを行うことはできますか?
私は100%確信はありませんが、LSTMが学習するはずの各シーケンスが「異なるルールで再生される」ため、LSTMの性質上、入力をフラット化して1D配列として渡すことはできません。
では、kerasを使用したこのような実装はPyTorch input of shape (seq_len, batch, input_size)
(source https://pytorch.org/docs/stable/nn.html#lstm )とどのように等しくなりますか?
編集:
最初のレイヤーとしてLSTMの_
n_features
_を作成し、それぞれを個別にフィードして(シーケンスの複数のストリームとして想定)、出力を線形レイヤーに平坦化する以外の方法でそれを行うことはできますか?
PyTorchによると docsinput_sizeパラメータは実際には機能の数を意味します(並列シーケンスの数を意味する場合)
pytorchの任意のrnnセルの入力は3d入力であり、(seq_len、batch、input_size)または(batch、seq_len、input_size)としてフォーマットされます。
bach_first = True
https://discuss.pytorch.org/t/could-someone-explain-batch-first-true-in-lstm/15402
また、セットアップでは再帰的な関係はありません。多対1のカウンターを作成する場合は、サイズ(-1、n、1)の場合に入力を作成します。ここで、-1は必要なサイズで、nは桁数で、入力のように1ティックあたり1桁です[[10] [20] [30]]、出力-60、入力[[30、] [70]]出力100など、rnn関係を学習するには、入力は1から最大値までの異なる長さでなければなりません
import random
import numpy as np
import torch
def rnd_io():
return np.random.randint(100, size=(random.randint(1,10), 1))
class CountRNN(torch.nn.Module):
def __init__(self):
super(CountRNN, self).__init__()
self.rnn = torch.nn.RNN(1, 20,num_layers=1, batch_first=True)
self.fc = torch.nn.Linear(20, 1)
def forward(self, x):
full_out, last_out = self.rnn(x)
return self.fc(last_out)
nnet = CountRNN()
criterion = torch.nn.MSELoss(reduction='sum')
optimizer = torch.optim.Adam(nnet.parameters(), lr=0.0005)
batch_size = 100
batches = 10000 * 1000
printout = max(batches //(20* 1000),1)
for t in range(batches):
optimizer.zero_grad()
x_batch = torch.unsqueeze(torch.from_numpy(rnd_io()).float(),0)
y_batch = torch.unsqueeze(torch.sum(x_batch),0)
output = nnet.forward(x_batch)
loss = criterion(output, y_batch)
if t % printout == 0:
print('step : ' , t , 'loss : ' , loss.item())
torch.save(nnet.state_dict(), './rnn_summ.pth')
loss.backward()
optimizer.step()