我在几个月前接触深度学习,学习LSTM,后来写了一篇文章《基于pytorch的LSTM预测实现(入门级别)https://blog.csdn.net/m0_68676807/article/details/131033853》。
def sliding_windows(data, seq_length):
'''
Output:The data form we can feed GRU
'''
x = []
y = []
for i in range(len(data)-seq_length-1):
_x = data[i:(i+seq_length),:]
_y = data[i+seq_length,-1]
# _y = data[i + seq_length-1, -1]
x.append(_x)
y.append(_y)
1.首先是编程理念,要跳出入门的时候的那种编程思路,如果你跳不出来,就是你还是不够深刻,这个时候就要多读优秀论文及他们的开源代码! 这里我也是非常幸运,在一开始接触时间序列预测,我就知道了Informer,当时不理解他的代码和论文,但是我始终没有放弃他,我一遍遍的看,每次都有收货,做学术这个东西,还是得看TOP学校和企业。Informer的代码地址我也给出了。
GitHub - zhouhaoyi/Informer2020: The GitHub repository for the paper "Informer" accepted by AAAI 2021.
“就好比有的人看起来什么都会一点,但实际上根本没有付出实际努力,总是想要走捷径。”
“不用担心,真正优秀的人不需要走捷径,因为只要他走起路来,脚下都是捷径。”
在过去的半年里面,我遇到了许许多多的学习上的难题,我就是把他放在一边,因为我坚信自己未来的某一刻可以攻克他,只需要我再努力一点点,积累一点点,事实证明也确实是这样!与君共勉!
这是用于训练的数据集Dataset_Custom(Dataset),在实现预测的时候会再创建一个数据集。在这里就不给出了。
class Dataset_Custom(Dataset):
def __init__(self,
file_path='./ETTm1.csv', split_rate=0.75, flag='train', target='OT',
seq_len=32,pred_len = 12,inverse=False,freq='15min',features='M'):
'''自定义参数设置'''
self.file_path = file_path
self.split_rate = split_rate
self.target = target
self.seq_len = seq_len
self.pred_len = pred_len
self.inverse = inverse
self.features = features
self.freq = freq
assert flag in ['train', 'test', 'val']
type_map = {'train': 0, 'val': 1, 'test': 2}
self.set_type = type_map[flag]
self.__read_data__()
def __read_data__(self):
df_raw = pd.read_csv(self.file_path)
self.scaler = StandardScaler()
cols = list(df_raw.columns)
cols.remove(self.target)
cols.remove('date')
df_raw = df_raw[['date'] + cols + [self.target]]
num_train = int(len(df_raw) * self.split_rate)
num_vali = int(len(df_raw) * 0.1)
num_test =len(df_raw) - num_train - num_vali
border1s = [0, num_train - self.seq_len, len(df_raw) - num_test - self.seq_len]
border2s = [num_train, num_train + num_vali, len(df_raw)]
border1 = border1s[self.set_type]
border2 = border2s[self.set_type]
cols_data = df_raw.columns[1:]
df_data = df_raw[cols_data]
train_data = df_data[border1s[0]:border2s[0]]
self.scaler.fit(train_data.values)
data = self.scaler.transform(df_data.values)
self.data_x = data[border1:border2]
# print('self.data_x, self.data_x[0])', len(self.data_x), self.data_x[0], self.data_x.shape)
if self.inverse:
self.data_y = df_data.values[border1:border2]
else:
self.data_y = data[border1:border2]
def __getitem__(self, index):
s_begin = index
s_end = s_begin + self.seq_len
r_begin = s_end
r_end = r_begin + self.pred_len
seq_x = self.data_x[s_begin:s_end]
seq_y = self.data_y[r_begin:r_end]
return seq_x, seq_y
def __len__(self):
return len(self.data_x)-self.seq_len-self.pred_len + 1
def inverse_transform(self, data):
return self.scaler.inverse_transform(data)
class LSTM(nn.Module):
def __init__(self,
input_size=7,
hidden_size=256,
num_layers=2,
output_size=7,
dropout=0.2,
seq_len =32,
pred_len=12,
device=torch.device('cuda:0')
):
super(LSTM,self).__init__()
self.outout_size = output_size
self.hidden_size = hidden_size
self.num_layers = num_layers
self.dropout = dropout
self.input_size = input_size
self.device = device
self.pred_len = pred_len
self.seq_len = seq_len
self.batch_first = True
self.bidirectional = False
self.lstm = nn.LSTM(input_size=self.input_size, hidden_size=self.hidden_size,
num_layers=self.num_layers, dropout=self.dropout,batch_first=self.batch_first, bidirectional=self.bidirectional)
self.reg = nn.Sequential(nn.Linear(self.hidden_size, self.hidden_size),
nn.Tanh(),
nn.Linear(self.hidden_size, self.outout_size),
)
self.Linear = nn.Linear(self.seq_len, self.pred_len)
def initial_hidden_state(self,batch_size):
'''(num_layers * num_directions, batch_size, hidden_size )'''
if self.bidirectional==False:
num_directions = 1
else:
num_directions = 2
h_0 = torch.randn(self.num_layers * num_directions, batch_size, self.hidden_size).to(self.device)
c_0 = torch.randn(self.num_layers * num_directions, batch_size, self.hidden_size).to(self.device)
# print(num_directions)
hidden_state = (h_0, c_0)
return hidden_state
def forward(self,x):
hidden_state = self.initial_hidden_state(x.size(0))
lstm_out, hidden = self.lstm(x, hidden_state)
outputs = self.reg(lstm_out)
# print(outputs.shape)
outputs = self.Linear(outputs.permute(0,2,1)).permute(0,2,1)
return outputs
训练集上:左侧为单输出的loss,右侧为多输出的loss,效果都不怎么好!
验证集上:左侧为单输出的loss,右侧为多输出的loss,我发现训练的epoch越多,loss也逐渐降低。
测试集上:测试效果都不好,所以需要改进一些细节地方!