gpt4 book ai didi

python - pytorch中的多元输入LSTM

转载 作者:行者123 更新时间:2023-11-28 22:10:21 26 4
gpt4 key购买 nike

我想在 Pytorch 中为多元输入实现 LSTM。

关注本文https://machinelearningmastery.com/how-to-develop-lstm-models-for-time-series-forecasting/使用keras,输入数据的形状为(样本数,时间步数,并行特征数)

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

在keras中这似乎很容易:

model.add(LSTM(50, activation='relu', input_shape=(n_timesteps, n_features)))

除了创建 LSTM 的 n_features 作为第一层并分别馈送每个(想象为多个序列流)然后将它们的输出展平到线性层之外,是否可以通过其他方式完成?

我不是 100% 确定,但根据 LSTM 的性质,输入不能被展平并作为一维数组传递,因为每个序列“按照 LSTM 应该学习的不同规则播放”。

那么这样的keras实现如何等于PyTorch形状输入(seq_len、batch、input_size)(来源 https://pytorch.org/docs/stable/nn.html#lstm )


编辑:

Can it be done in other way, than creating n_features of LSTMs as first layer and feed each separately (imagine as multiple streams of sequences) and then flatten their output to linear layer?

根据 PyTorch docs input_size 参数实际上意味着特征的数量(如果它意味着并行序列的数量)

最佳答案

我希望有问题的部分被注释成有意义的:

数据准备

import random
import numpy as np
import torch

# multivariate data preparation
from numpy import array
from numpy import hstack

# split a multivariate sequence into samples
def split_sequences(sequences, n_steps):
X, y = list(), list()
for i in range(len(sequences)):
# find the end of this pattern
end_ix = i + n_steps
# check if we are beyond the dataset
if end_ix > len(sequences):
break
# gather input and output parts of the pattern
seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1, -1]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)

# define input sequence
in_seq1 = array([x for x in range(0,100,10)])
in_seq2 = array([x for x in range(5,105,10)])
out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))])
# convert to [rows, columns] structure
in_seq1 = in_seq1.reshape((len(in_seq1), 1))
in_seq2 = in_seq2.reshape((len(in_seq2), 1))
out_seq = out_seq.reshape((len(out_seq), 1))
# horizontally stack columns
dataset = hstack((in_seq1, in_seq2, out_seq))

多变量 LSTM 网络

class MV_LSTM(torch.nn.Module):
def __init__(self,n_features,seq_length):
super(MV_LSTM, self).__init__()
self.n_features = n_features
self.seq_len = seq_length
self.n_hidden = 20 # number of hidden states
self.n_layers = 1 # number of LSTM layers (stacked)

self.l_lstm = torch.nn.LSTM(input_size = n_features,
hidden_size = self.n_hidden,
num_layers = self.n_layers,
batch_first = True)
# according to pytorch docs LSTM output is
# (batch_size,seq_len, num_directions * hidden_size)
# when considering batch_first = True
self.l_linear = torch.nn.Linear(self.n_hidden*self.seq_len, 1)


def init_hidden(self, batch_size):
# even with batch_first = True this remains same as docs
hidden_state = torch.zeros(self.n_layers,batch_size,self.n_hidden)
cell_state = torch.zeros(self.n_layers,batch_size,self.n_hidden)
self.hidden = (hidden_state, cell_state)


def forward(self, x):
batch_size, seq_len, _ = x.size()

lstm_out, self.hidden = self.l_lstm(x,self.hidden)
# lstm_out(with batch_first = True) is
# (batch_size,seq_len,num_directions * hidden_size)
# for following linear layer we want to keep batch_size dimension and merge rest
# .contiguous() -> solves tensor compatibility error
x = lstm_out.contiguous().view(batch_size,-1)
return self.l_linear(x)

初始化

n_features = 2 # this is number of parallel inputs
n_timesteps = 3 # this is number of timesteps

# convert dataset into input/output
X, y = split_sequences(dataset, n_timesteps)
print(X.shape, y.shape)

# create NN
mv_net = MV_LSTM(n_features,n_timesteps)
criterion = torch.nn.MSELoss() # reduction='sum' created huge loss value
optimizer = torch.optim.Adam(mv_net.parameters(), lr=1e-1)

train_episodes = 500
batch_size = 16

训练

mv_net.train()
for t in range(train_episodes):
for b in range(0,len(X),batch_size):
inpt = X[b:b+batch_size,:,:]
target = y[b:b+batch_size]

x_batch = torch.tensor(inpt,dtype=torch.float32)
y_batch = torch.tensor(target,dtype=torch.float32)

mv_net.init_hidden(x_batch.size(0))
# lstm_out, _ = mv_net.l_lstm(x_batch,nnet.hidden)
# lstm_out.contiguous().view(x_batch.size(0),-1)
output = mv_net(x_batch)
loss = criterion(output.view(-1), y_batch)

loss.backward()
optimizer.step()
optimizer.zero_grad()
print('step : ' , t , 'loss : ' , loss.item())

结果

step :  499 loss :  0.0010267728939652443 # probably overfitted due to 500 training episodes

关于python - pytorch中的多元输入LSTM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56858924/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com