I’m trying to train LSTM model with short time series & many individual persons data
Prior to the training with actual data, I went with dummy data.
The structure of the dummy data looks normal and they have unique values
But the final prediction shows same values in 3 arrays
What did I do wrong?
# tensor([[[0.0496, 0.6693, 0.6575],
# [0.3207, 0.6082, 0.0967],
# [0.3982, 0.5984, 0.0644],
# [0.4094, 0.5971, 0.0608],
# [0.4109, 0.5969, 0.0603],
# [0.4111, 0.5969, 0.0603]],
# [[0.0496, 0.6693, 0.6575],
# [0.3207, 0.6082, 0.0967],
# [0.3982, 0.5984, 0.0644],
# [0.4094, 0.5971, 0.0608],
# [0.4109, 0.5969, 0.0603],
# [0.4111, 0.5969, 0.0603]],
# [[0.0496, 0.6693, 0.6575],
# [0.3207, 0.6082, 0.0967],
# [0.3982, 0.5984, 0.0644],
# [0.4094, 0.5971, 0.0608],
# [0.4109, 0.5969, 0.0603],
# [0.4111, 0.5969, 0.0603]]], grad_fn=<SigmoidBackward>)
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.nn.functional as F
import numpy as np
torch.manual_seed(777) # reproducibility
# ================================================================================
x_one_hot = [[[50, 0, 120, 70, 90], # 2008 medical data (patientA): age, sex, max blood pressure, min blood pressure, glucose
[50, 0, 124, 74, 91], # 2009 medical data (patientA): age, sex, max blood pressure, min blood pressure, glucose
[51, 0, 122, 60, 92], # 2010 medical data (patientA): age, sex, max blood pressure, min blood pressure, glucose
[52, 0, 110, 76, 91], # 2011 medical data (patientA): age, sex, max blood pressure, min blood pressure, glucose
[53, 0, 140, 83, 68], # 2012 medical data (patientA): age, sex, max blood pressure, min blood pressure, glucose
[54, 0, 130, 81, 85]], # 2013 medical data (patientA): age, sex, max blood pressure, min blood pressure, glucose
[[60, 1, 151, 70, 100], # 2008 medical data (patientB): age, sex, max blood pressure, min blood pressure, glucose
[60, 1, 152, 94, 101], # 2009 medical data (patientB): age, sex, max blood pressure, min blood pressure, glucose
[61, 1, 151, 90, 102], # 2010 medical data (patientB): age, sex, max blood pressure, min blood pressure, glucose
[62, 1, 133, 96, 101], # 2011 medical data (patientB): age, sex, max blood pressure, min blood pressure, glucose
[63, 1, 162, 83, 108], # 2012 medical data (patientB): age, sex, max blood pressure, min blood pressure, glucose
[64, 1, 151, 71, 105]], # 2013 medical data (patientB): age, sex, max blood pressure, min blood pressure, glucose
[[30, 0, 111, 60, 60],
[30, 0, 112, 64, 61],
[31, 0, 111, 60, 62],
[32, 0, 113, 66, 61],
[33, 0, 112, 63, 68],
[34, 0, 111, 61, 65]]]
# print("x_one_hot",np.array(x_one_hot).shape)
# x_one_hot (3, 6, 5)
y_data = [[[0,1,1], # 2008 disease status: high blood pressure, diabetes, obesity
[1,1,0], # 2009 disease status: high blood pressure, diabetes, obesity
[0,0,0], # 2010 disease status: high blood pressure, diabetes, obesity
[0,0,0], # 2011 disease status: high blood pressure, diabetes, obesity
[0,0,0], # 2012 disease status: high blood pressure, diabetes, obesity
[1,1,0]], # 2013 disease status: high blood pressure, diabetes, obesity
[[0,1,1],
[1,1,0],
[1,1,1],
[0,1,0],
[0,1,0],
[1,1,0]],
[[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[0,1,0],
[1,1,0]]]
# print("y_data",np.array(y_data).shape)
# (3, 6, 3)
# ================================================================================
inputs = Variable(torch.Tensor(x_one_hot))
labels = Variable(torch.Tensor(y_data))
# ================================================================================
num_classes = 5
input_size = 5
hidden_size = 20
sequence_length = 6
num_layers = 1
final_output_dim=3
# ================================================================================
class RNN(nn.Module):
def __init__(self, num_classes, input_size, hidden_size, num_layers, final_output_dim):
super(RNN, self).__init__()
self.num_classes = num_classes
self.num_layers = num_layers
self.input_size = input_size
self.hidden_size = hidden_size
self.sequence_length = sequence_length
self.final_output_dim = final_output_dim
self.rnn = nn.LSTM(input_size=input_size, hidden_size=hidden_size, batch_first=True)
self.linear = nn.Linear(hidden_size, hidden_size)
self.linear2 = nn.Linear(hidden_size, final_output_dim)
def forward(self, x):
h_0 = Variable(torch.zeros(self.num_layers, x.size(0), self.hidden_size))
c_0 = Variable(torch.zeros(self.num_layers, x.size(0), self.hidden_size))
x.view(x.size(0), self.sequence_length, self.input_size)
out, _ = self.rnn(x, (h_0, c_0))
out=self.linear(out).squeeze()
out=self.linear2(out).squeeze()
out=F.sigmoid(out)
return out
# ================================================================================
rnn = RNN(num_classes, input_size, hidden_size, num_layers, final_output_dim)
print(rnn)
criterion = nn.BCELoss()
optimizer = torch.optim.Adam(rnn.parameters(), lr=0.1)
# ================================================================================
for epoch in range(5000):
outputs = rnn(inputs)
optimizer.zero_grad()
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
_, idx = outputs.max(1)
idx = idx.data.numpy()
print("epoch: %d, loss: %1.3f" % (epoch + 1, loss.item()))
print("Learning finished!")
# ================================================================================
# Test
outputs = rnn(inputs)
# print("outputs",outputs)
# All are same values
# tensor([[[0.0496, 0.6693, 0.6575],
# [0.3207, 0.6082, 0.0967],
# [0.3982, 0.5984, 0.0644],
# [0.4094, 0.5971, 0.0608],
# [0.4109, 0.5969, 0.0603],
# [0.4111, 0.5969, 0.0603]],
# [[0.0496, 0.6693, 0.6575],
# [0.3207, 0.6082, 0.0967],
# [0.3982, 0.5984, 0.0644],
# [0.4094, 0.5971, 0.0608],
# [0.4109, 0.5969, 0.0603],
# [0.4111, 0.5969, 0.0603]],
# [[0.0496, 0.6693, 0.6575],
# [0.3207, 0.6082, 0.0967],
# [0.3982, 0.5984, 0.0644],
# [0.4094, 0.5971, 0.0608],
# [0.4109, 0.5969, 0.0603],
# [0.4111, 0.5969, 0.0603]]], grad_fn=<SigmoidBackward>)