1.代码与论文
Informer论文链接:arxiv.org/pdf/1706.03762.pdfhttps://arxiv.org/pdf/1706.03762.pdf
2.训练
Informer的github仓库下有原文作者自己制作的时序预测数据集,百度网盘链接如下:百度网盘 请输入提取码 (baidu.com),提取码为6gan。
参数设置
主要参数设置都在main_informer.py文件中,下面进行主要需要调整的参数介绍
# 选择模型,我使用的Informer原始模型,Informerstack是在Informer的基础上增加了一个stack encoder,可以处理更长的输入序列,Informerlight(TBD)为轻量化Informer
parser.add_argument('--model', type=str, default='informer',help='model of experiment, options: [informer, informerstack, informerlight(TBD)]')
# 选择数据类型,这里有ETTh1,ETTh2,ETTm1,ETTm2,WTH和custom的选择,其中前几个为官方给的数据类型,如果使用自己的数据集训练,则可选择custom,但需要在本文件下面定义custom
parser.add_argument('--data', type=str, default='custom', help='data')
# 选择数据位置,这里的是相对根目录的相对路径
parser.add_argument('--root_path', type=str, default='./data/', help='root path of the data file')
# 数据名称
parser.add_argument('--data_path', type=str, default='train.csv', help='data file')
# 选择进行时序预测的类型,M为使用多变量时间序列作为输入,预测多变量的时间序列作为输出;S为使用单变量时间序列作为输入,预测单变量的时间序列作为输出;MS为使用多变量的时间序列作为输入,预测单变量的时间序列作为输出;
parser.add_argument('--features', type=str, default='MS', help='forecasting task, options:[M, S, MS]; M:multivariate predict multivariate, S:univariate predict univariate, MS:multivariate predict univariate')
# 这里的target参数即为在你的csv数据中你想预测的变量,比如我想预测开盘价,我的csv文件中为open,这里则是open
parser.add_argument('--target', type=str, default='open', help='target feature in S or MS task')
# 设置时间特征编码,可以根据你训练集中的时间间隔设置,我这里设置的是天
parser.add_argument('--freq', type=str, default='d', help='freq for time features encoding, options:[s:secondly, t:minutely, h:hourly, d:daily, b:business days, w:weekly, m:monthly], you can also use more detailed freq like 15min or 3h')
# 权重保存位置
parser.add_argument('--checkpoints', type=str, default='./checkpoints/', help='location of model checkpoints')
# 下面的参数设置部分我按照的原作者的设置,只有在batch size进行了更改,如果使用的是笔记本的显卡来训练,则可以将batch size适当调小,比如1,2,4...
# 所使用数据集设置,在--data的参数可以调为下面的名称,即可直接使用下面所定义的
data_parser = {
'ETTh1':{'data':'ETTh1.csv','T':'OT','M':[7,7,7],'S':[1,1,1],'MS':[7,7,1]},
'ETTh2':{'data':'ETTh2.csv','T':'OT','M':[7,7,7],'S':[1,1,1],'MS':[7,7,1]},
'ETTm1':{'data':'ETTm1.csv','T':'OT','M':[7,7,7],'S':[1,1,1],'MS':[7,7,1]},
'ETTm2':{'data':'ETTm2.csv','T':'OT','M':[7,7,7],'S':[1,1,1],'MS':[7,7,1]},
'WTH':{'data':'WTH.csv','T':'WetBulbCelsius','M':[12,12,12],'S':[1,1,1],'MS':[12,12,1]},
'ECL':{'data':'ECL.csv','T':'MT_320','M':[321,321,321],'S':[1,1,1],'MS':[321,321,1]},
'Solar':{'data':'solar_AL.csv','T':'POWER_136','M':[137,137,137],'S':[1,1,1],'MS':[137,137,1]},
# custom是我定义的自己训练的数据集,其中“open”为我所预测的变量,后面拿M:[7,7,7]举例,为用七个特征作为输入,预测7个特征的输出
'custom':{'data':'train.csv','T':'open','M':[7,7,7],'S':[1,1,1],'MS':[7,7,1]}
}
数据调整好后,即可开始训练,本人进行了一个简单的股票预测和碳排放预测(下载的数据已上传,应该能看到,我忘记在哪个网址下的了,也可以去Carbon monitor 这里找),在这里我只采用了美国2019-2023的碳排放数据作为训练集,由于碳排放只有简简单单的一列co2排放量(--features选择S),导致预测的效果很差,趋势图更是惨不忍睹(建议有这个想法的最好把数据集弄好,要有几列相关联的数据,效果会更好),图如下:
由此可以看出碳排放趋势变化不大,但是预测趋势却起伏不定。下面是我用股票数据集(这个数据不能公开)进行预测后绘制的图像(--features选择MS)。
由于Informer有一个early stop机制,当训练过程中的loss值不在下降时,则会主动停止,这也是目前很多新的时序预测模型训练带的一个机制(比如Timesnet),如果大家想不那么早停止,epoch和patience都可以调大一点。
parser.add_argument('--patience', type=int, default=3, help='early stopping patience')
输出:
若想输出对训练时间之后的预测结果,可以把下面的store_true改为store_false,即可在./results/中的一个文件夹中找的real_prediction.npy文件,这里面存储的就是对未来的预测结果。
parser.add_argument('--do_predict', action='store_false', help='whether to predict unseen future data')
下面是绘制上述对比图的python代码:
import matplotlib.pyplot as plt
import numpy as np
setting = 'informer_custom_ftMS_sl96_ll48_pl24_dm512_nh8_el2_dl1_df2048_atprob_fc5_ebtimeF_dtTrue_mxTrue_test_0'
pred = np.load('./results/'+setting+'/pred.npy')
true = np.load('./results/'+setting+'/true.npy')
print(pred.shape)
print(true.shape)
plt.figure()
plt.plot(true[0,:,-1], label='GroundTruth')
plt.plot(pred[0,:,-1], label='Prediction')
plt.legend()
plt.show()
这里的setting即为./results中的文件夹名字。
3.指标
初始的main_informer中的指标只有mse和mae两个,若想做一篇论文可能还是略有欠缺,下面是我添加的几个指标,都是在时序预测中可以作为评判标准的:
def RMSE(pred, true):
return np.sqrt(MSE(pred, true))
def MAPE(pred, true):
return np.mean(np.abs((pred - true) / true))
def MSPE(pred, true):
return np.mean(np.square((pred - true) / true))
def r(preds, trues):
preds = np.squeeze(preds)
trues = np.squeeze(trues)
return np.corrcoef(preds, trues)[0, 1]
def metric(pred, true):
# 计算指标
mae = calculate_mae(pred, true)
mse = calculate_mse(pred, true)
rmse = calculate_rmse(pred, true)
mape = calculate_mape(pred, true)
mspe = calculate_mspe(pred, true)
rse = RSE(pred, true)
return mae, mse, rmse, mape, mspe, rse
然后再在exp_informer中更改test部分的函数:
def test(self, setting):
test_data, test_loader = self._get_data(flag='test')
self.model.eval()
preds = []
trues = []
for i, (batch_x,batch_y,batch_x_mark,batch_y_mark) in enumerate(test_loader):
pred, true = self._process_one_batch(
test_data, batch_x, batch_y, batch_x_mark, batch_y_mark)
preds.append(pred.detach().cpu().numpy())
trues.append(true.detach().cpu().numpy())
preds = np.array(preds)
trues = np.array(trues)
print('test shape:', preds.shape, trues.shape)
preds = preds.reshape(-1, preds.shape[-2], preds.shape[-1])
trues = trues.reshape(-1, trues.shape[-2], trues.shape[-1])
print('test shape:', preds.shape, trues.shape)
# result save
folder_path = './results/' + setting +'/'
if not os.path.exists(folder_path):
os.makedirs(folder_path)
mae, mse, rmse, mape, mspe, rse = metric(preds, trues)
print('mse:{}, mae:{}, rmse: {}, mape: {}, rse: {}'.format(mse, mae, rmse, mape, rse))
np.save(folder_path+'metrics.npy', np.array([mae, mse, rmse, mape, mspe]))
np.save(folder_path+'pred.npy', preds)
np.save(folder_path+'true.npy', trues)
return
这样在预测中,就可以显示mse(均方误差),mae(平均绝对误差),rmse(均方根误差),mape(平均绝对百分比误差),rse(残差标准误差)
4.总结
其实在近几年流行的这几个时序预测模型(Informer,Timesnet,LSTM,Transformer)中,最适合的应该是Informer,个人试了以上几种网络,Timesnet对显存的要求太高,得租用服务器才能进行训练,而LSTM和Transformer时间又有点久远,且不如Informer,所以进行时序预测可以对Informer下手。
Informer作为2021年AAAI会议上的最佳论文,其创新性也非常强,在他的ProbSparse self-attention和生成式解码器机制上做文章也是十分不错。