前面已经写了很多关于时间序列预测的文章:
上面所有文章一共采用了LSTM、ANN以及CNN三种模型来分别进行时间序列预测。众所周知,CNN提取特征的能力非常强,因此现在不少论文将CNN和LSTM结合起来进行时间序列预测。本文将利用TensorFlow来搭建一个简单的CNN-LSTM混合模型实现负荷预测。
CNN-LSTM模型搭建如下:
class CNN_LSTM(tf.keras.Model):
def __init__(self, args):
super(CNN_LSTM, self).__init__()
self.args = args
# (batch_size=b, seq_len=24, input_size=7)
# (b, 24, 7)-->(b, 22, 64)
self.conv1 = Sequential()
self.conv1.add(layers.Conv1D(64, 2, activation='relu'))
self.conv1.add(layers.MaxPool1D(pool_size=2, strides=1))
# (b, 22, 64)-->(b, 20, 128)
self.conv2 = Sequential()
self.conv2.add(layers.Conv1D(128, 2, activation='relu'))
self.conv2.add(layers.MaxPool1D(pool_size=2, strides=1))
# (b, 20, 128)
self.lstm = layers.LSTM(units=args.hidden_size,
activation='tanh', return_sequences=True)
self.fc = layers.Dense(args.output_size)
def call(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.lstm(x)
x = self.fc(x)
x = x[:, -1, :]
return x
可以看到,该CNN-LSTM由一层一维卷积+LSTM组成。
通过TensorFlow搭建CNN实现时间序列预测(风速预测)我们知道,
一维卷积的原始定义为:
tf.keras.layers.Conv1D(
filters, kernel_size, strides=1, padding='valid',
data_format='channels_last', dilation_rate=1, groups=1,
activation=None, use_bias=True, kernel_initializer='glorot_uniform',
bias_initializer='zeros', kernel_regularizer=None,
bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,
bias_constraint=None, **kwargs
)
这里filters的概念相当于自然语言处理中的embedding,这里输入通道数为15,表示风速+14个环境变量,输出filters设置为64,卷积核大小为2。
原数数据的维度为24,即前24小时的风速+14种气象数据。卷积核大小为2,根据前文公式,原始时序数据经过卷积后维度为:
24 - 2 + 1 = 23
然后经过一个最大池化变成22,然后又是一个卷积层+池化层,变成20。
这里需要注意的是,PyTorch中要求输入数据的shape为(batch_size, input_size, seq_len)
,而TensorFlow中为(batch_size, seq_len, input_size)
,也就是说TensorFlow中不需要对原始数据进行维度交换操作。
然后就是比较常规的LSTM输入输出的,不再细说。
我们根据前24个时刻的负荷以及该时刻的环境变量来预测接下来12个时刻的负荷,这里采用了直接多输出策略,调整output_size即可调整输出步长。
和前文一致。
简单训练100轮,前24个时刻预测未来12个时刻,MAPE为9.80%:
后面将陆续公开~