从零开始实现LSTM模型进行单变量时间序列预测.pdf
- 文档编号:18631306
- 上传时间:2023-08-23
- 格式:PDF
- 页数:7
- 大小:249.77KB
从零开始实现LSTM模型进行单变量时间序列预测.pdf
《从零开始实现LSTM模型进行单变量时间序列预测.pdf》由会员分享,可在线阅读,更多相关《从零开始实现LSTM模型进行单变量时间序列预测.pdf(7页珍藏版)》请在冰点文库上搜索。
从零开始实现,LSTM模型进单变量时间序列预测上篇博客讲了,这篇档使pytorch动实现如何基于LSTM模型单变量时间预测。
同样使snsflight(数据盘下载链接见末)作为数据源,这将数据下载下来存放在本机中。
先读取存储在本机中的flights.csv数据:
importtorchimporttorch.nnasnnimportnumpyasnpimportpandasaspdimportmatplotlib.pyplotasplt%matplotlibinlineflight_data=pd.read_csv(flights.csv)flight_data.shape#(144,3)绘制数据看看致的向fig_size=plt.rcParamsfigure.figsizefig_size0=15fig_size1=5plt.rcParamsfigure.figsize=fig_sizeplt.title(MonthvsPassenger)plt.ylabel(TotalPassengers)plt.xlabel(Months)plt.grid(True)plt.autoscale(axis=x,tight=True)plt.plot(flight_datapassengers)#提取所有乘客量的数据all_data=flight_datapassengers.values.astype(float)print(all_data)输出为112.118.132.129.121.135.148.148.136.119.104.118.115.126.141.135.125.149.170.170.158.133.114.140.145.150.178.163.172.178.199.199.184.162.146.166.171.180.193.181.183.218.230.242.209.191.172.194.196.196.236.235.229.243.264.272.237.211.180.201.204.188.235.227.234.264.302.293.259.229.203.229.242.233.267.269.270.315.364.347.312.274.237.278.284.277.317.313.318.374.413.405.355.306.271.306.315.301.356.348.355.422.465.467.404.347.305.336.340.318.362.348.363.435.491.505.404.359.310.337.360.342.406.396.420.472.548.559.463.407.362.405.417.391.419.461.472.535.622.606.508.461.390.432.可知,共有144个数据,我们将前132个数据作为训练集,后12个数据作为测试集#将数据区分为训练数据和测试数据test_data_size=12train_data=all_data:
-test_data_sizetest_data=all_data-test_data_size:
根据数据绘制结果,可以发现数据呈现较快的增长趋势,范围跨度也较,为便于训练,我们将训练数据进归化处理,归化的法是min/max法,该法归化后的数据值域为-1,1。
这注意,我们仅仅对训练数据进归化未考虑测试数据,这样做的的为了防信息从训练数据泄露到的测试数据。
#由于训练数据存在相差较的,因此使min/max尺度变换对训练数据进归化#注意只对训练数据进归化,为了防有些信息从训练数据泄露到的测试数据fromsklearn.preprocessingimportMinMaxScalerscaler=MinMaxScaler(feature_range=(-1,1)train_data_normalized=scaler.fit_transform(train_data.reshape(-1,1)现在我们看看归化以后的数据,全部位于-1,1区间内:
#现在可以看到所有训练值都在-1,1的范围内print(train_data_normalized:
5)print(train_data_normalized-5:
)输出-0.96483516-0.93846154-0.87692308-0.89010989-0.925274731.0.578021980.331868130.134065930.32307692然后将数据转化为tensor以便于训练#将数据转换为torchtensortrain_data_normalized=torch.FloatTensor(train_data_normalized).view(-1)这我们的的是使LSTM进时间序列预测,那么我们先需要明确输LSTM的时间序列的步长,由于我们输出的是多个年份的数据、且数据以为单位,所以可以很然想到使12作为我们输时间序列长度。
通过当前12个数据预测第13个数据的值。
以sequencelength为参数,我们构建个函数来提取时间序列的输输出:
#由于我们使的是以为单位的乘客数据,所以很然想到的是#使12作为个时间序列,我们使12个的数据来预测第13个的乘客量#定义如下函数来构建输输出#tw为sequencelengthdefcreate_inout_sequences(input_data,tw):
inout_seq=L=len(input_data)foriinrange(L-tw):
train_seq=input_datai:
i+twtrain_label=input_datai+tw:
i+tw+1inout_seq.append(train_seq,train_label)returninout_seq定义sequencelength为12train_window=12train_inout_seq=create_inout_sequences(train_data_normalized,train_window)接下来我们定义LSTM模型,注意LSTM模型的输出为(sequence_legth,bacth_size,hidden_size),其中输出指的是隐藏层在各个时间步上计算并输出的隐藏状态,它们通常作为后续输出层的输。
需要强调的是,该“输出”本并不涉及输出层计算,形状为(时间步数,批量,隐藏单元个数)。
所以这在输出后再加个线性层来获得最终输出。
classLSTM(nn.Module):
def_init_(self,input_size=1,hidden_size=100,output_size=1):
super()._init_()self.hidden_size=hidden_size#定义lstm层self.lstm=nn.LSTM(input_size,hidden_size)#定义线性层,即在LSTM的的输出后再加个线性层self.linear=nn.Linear(hidden_size,output_size)#input_seq参数表输sequencedefforward(self,input_seq):
#lstm默认的输X是(sequence_legth,bacth_size,input_size)lstm_out,self.hidden_cell=self.lstm(input_seq.view(len(input_seq),1,-1),self.hidden_cell)#lstm_out的默认是(sequence_legth,bacth_size,hidden_size)#转化之后lstm_out的是(sequence_legth,bacth_size*hidden_size)predictions=self.linear(lstm_out.view(len(input_seq),-1)#由于bacth_size=1,可知predictions的维度为(sequence_legth,output_size)#-1表的是取最后个时间步长对应的输出returnpredictions-1#另种常见的lstm_out的变换式是将其转换为(sequence_legth*batch_size,num_hiddens)即predictions=self.linear(lstm_out.view(-1,lstm_out.shape-1)returnpredictions-1但是,当batch_size!
=1时,这种转换在这就不合适了,因为这的predictions-1对应的并不是最后个步长的输出。
这种转换更常于预测每个步长都有对应输出的情况,如http:
/tangshusen.me/Dive-into-DL-PyTorch/#/chapter06_RNN/6.4_rnn-scratch中的“6.4.7定义模型训练函数”对应的就是这种情况。
接下来,定义模型实例、损失函数、优化函数#模型实例化并定义损失函数和优化函数model=LSTM()loss_function=nn.MSELoss()optimizer=torch.optim.Adam(model.parameters(),lr=0.001)print(model)输出LSTM(lstm):
LSTM(1,100)(linear):
Linear(in_features=100,out_features=1,bias=True)训练模型,设置迭代的次数为150,这的batch为1,所以我们取train_inout_seq的每数据即为个batchepochs=150foriinrange(epochs):
forseq,labelsintrain_inout_seq:
optimizer.zero_grad()#下这步是对隐含状态以及细胞转态进初始化#这步是必须的,否则会报错RuntimeError:
Tryingtobackwardthroughthegrapha#secondtime,butthebuffershavealreadybeenfreedmodel.hidden_cell=(torch.zeros(1,1,model.hidden_size),torch.zeros(1,1,model.hidden_size)y_pred=model(seq)single_loss=loss_function(y_pred,labels)single_loss.backward()optimizer.step()ifi%25=1:
print(fepoch:
i:
3loss:
single_loss.item():
10.8f)print(fepoch:
i:
3loss:
single_loss.item():
10.10f)输出epoch:
1loss:
0.00139548epoch:
26loss:
0.01831282epoch:
51loss:
0.00002390epoch:
76loss:
0.00029238epoch:
101loss:
0.00020424epoch:
126loss:
0.00000069epoch:
149loss:
0.0001339361提取traindata中最后12个数据,作为预测的输#以traindata的最后12个数据进预测fut_pred=12test_inputs=train_data_normalized-train_window:
.tolist()print(test_inputs)输出0.12527473270893097,0.04615384712815285,0.3274725377559662,0.2835164964199066,0.3890109956264496,0.6175824403762817,0.9516483545303345,1.0,0.5780220031738281,0.33186814188957214,0.13406594097614288,0.32307693362236023进模型的预测,先我们将模型设置为模型评价模式防出现模型预测不致的情况(如说采了dropout层)。
可以看到,下预测基本思路是将新的预测值加到数据集当中于进步的预测,我们最开始使是第121-132个值去预测第133值,然后我们在第122-133去预测第134个值,依次类推直到第144个值被预测。
model.eval()#基于最后12个数据来预测第133个数据,并基于新的预测数据进步预测#134-144的数据foriinrange(fut_pred):
seq=torch.FloatTensor(test_inputs-train_window:
)#模型评价时候关闭梯度下降withtorch.no_grad():
model.hidden=(torch.zeros(1,1,model.hidden_size),torch.zeros(1,1,model.hidden_size)test_inputs.append(model(seq).item()test_inputsfut_pred:
输出LSTM(lstm):
LSTM(1,100)(linear):
Linear(in_features=100,out_features=1,bias=True)0.5331172943115234,0.5856705904006958,0.8344773650169373,1.0538733005523682,1.2378138303756714,1.3108998537063599,1.1621872186660767,1.4777841567993164,1.5506138801574707,1.7615976333618164,1.7539771795272827,1.5737073421478271由于输出输时,我们采了归化的操作,所以这通过反向变换,将预测之后的数据进转换。
#通过反向尺度变换,将预测数据抓换成归化的数据actual_predictions=scaler.inverse_transform(np.array(test_inputstrain_window:
).reshape(-1,1)print(actual_predictions)输出452.78418446464.74005932521.34360054571.25617588613.10264641629.72971672595.89759225667.69589567684.26465774732.26346159730.52980834689.51842034接下来,我们通过可视化看看预测的值和实际的值之间的关系#绘制图像查看预测的133-144的数据和实际的133-144之间的数据差别x=np.arange(132,144,1)print(x)plt.title(MonthvsPassenger)plt.ylabel(TotalPassengers)plt.grid(True)plt.autoscale(axis=x,tight=True)plt.plot(flight_datapassengers)plt.plot(x,actual_predictions)plt.show()可以发现预测的值在总体的趋势上与实际类似,但是在预测数值还存在定的差距,这只是为了说明如何使LSTM进单变量进预测,所以不过分追求精度。
实际应中,需要通过调参不断的优化模型来提预测的精度。
flight数据下载连接
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 从零开始 实现 LSTM 模型 进行 变量 时间 序列 预测
![提示](https://static.bingdoc.com/images/bang_tan.gif)