I am trying to implement the following model (from coursera) in pytorch. The model is used on time series data with a sliding window of 30. The output is a single value that represents what comes in the next in the sequence. The Tensorflow Model from coursera
from tensorflow.keras.layers import Conv1D, LSTM, Dense, Lambda
from tensorflow.keras.models import Sequential
(window_size, batch_size, shuffle_buffer_size) = (30,32,1000)
model = Sequential([
Conv1D(filters = 64, kernel_size = 3, strides = 1, activation = "relu", padding = "causal", input_shape = [window_size, 1]),
LSTM(64, return_sequences = True),
LSTM(64),
Dense(30, activation = "relu"),
Dense(30, activation = "relu"),
Dense(1),
Lambda(lambda x: x * 400)
])
Implementation of model in pytorch (what I have done so far). In PyTorch, LSTM outputs a sequence of values (len(window_size)) and you select the last one as the prediction (out[-1]). However, I am not quite sure how to input the values from LSTM to the fully-connected layers in this instance. Also, it would be nice if you can tell me if what I have done so far is correct. Thanks
import torch
import torch.nn as nn
import torch.nn.functional as F
#input data
x = torch.rand((32,30), dtype = torch.float32).unsqueeze(0)
class LSTM(nn.Module):
def __init__(self):
super(LSTM,self).__init__():
#in : (batch, sequence, channel) ---> Out : (batch, channel, sequence)
#in shape (1,32,30) ---> out shape (1,64,32)
self.conv = nn.Conv1d(in_channels = 32, out_channels = 64, kernel_size = 3, stride = 1, padding = 2)
#in : (batch, sequence, input_size/features) ---> Out : (batch, sequence, channel)
#in shape (1,64,32) ---> out shape (1,32,64)
self.lstm1 = nn.LSTM(input_size = 64, hidden_size = 64, batch_first = True)
#in : (batch, sequence, input_size/features) ---> Out : (batch, sequence, channel)
#in shape (1,32,64) ---> out shape (1,32,64)
self.lstm2 = nn.LSTM(input_size = 64, hidden_size = 64, batch_first = True)
# ---------------------------------------------------- ??? ------------------------------------------------
#in : (*, in_features) ---> out : (*, out_features)
#in shape (1,32,64) ---> out shape (1,???) - NOT SURE
# NOT SURE WHAT TO INPUT AS THE in_features
self.fc1 = nn.Linear(in_features = 32 * 64, out_features = 30)
# ---------------------------------------------------- --- -----------------------------------------------
#in : (*, in_features) ---> out : (*, out_features)
self.fc2 = nn.Linear(in_features = 30, out_features = 30)
#in : (*, in_features) ---> out : (*, out_features)
self.fc3 = nn.Linear(in_features = 30, out_features = 1)
def forward(self,x):
out = self.conv(x)
out,ht1 = self.LSTM(out.permute(0,2,1)
out,ht2 = self.LSTM(out)
# ---------------------------------------------- ??? --------------------------------------------------------
# AGAIN THIS WHERE I AM NOT SURE, BUT GENERALLY YOU UNROLL THE TENSOR BEFORE FEEDING INTO FC-LAYER
out = out.view(-1,64)
out = F.relu(self.fc1(out))
# -------------------------------------------------------------------------------------------------------
# ...