web-dev-qa-db-ja.com

Pytorchでの多変量入力LSTM

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パラメータは実際には機能の数を意味します(並列シーケンスの数を意味する場合)

3
Tomas Trdla

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()
0
user8426627