CNN-LSTM-Attention深度学习:时空特征结合融合注意力机制的预测

CNN-LSTM-SelfAttention 是一种深度学习模型结构,专为处理具有时空相关性的序列数据而设计。这种结构结合了卷积神经网络(CNN)、长短时记忆网络(LSTM)和自注意力机制(Self-Attention)三种神经网络层,能够有效捕捉数据中的空间和时间特征,主要的作用和功能如下:

长短时记忆网络 (LSTM)是一种循环神经网络(RNN)的变体,擅长处理序列数据中的时间依赖关系。LSTM通过输入门、遗忘门和输出门的控制机制,有效记住或忽略序列中的关键信息。在时间序列预测中,LSTM可以捕捉到数据中的长期依赖关系。例如,在发电功率预测中,LSTM能够识别出日间和夜间的功率变化规律,帮助模型更准确地进行未来时间步的预测。

自注意力层 (Self-Attention)用于计算输入序列中各个时间步之间的相关性。通过计算每个时间步与其他时间步之间的注意力权重,模型可以对整个序列的信息进行加权求和。在序列数据处理过程中,Self-Attention能够帮助模型关注到序列中重要的时间步,忽略次要的部分。例如,在碳价预测中,Self-Attention 机制可以自动识别并重点关注对碳价波动影响较大的历史时间点。

CNN-LSTM-SelfAttention首先通过CNN层提取序列的空间特征,接着通过LSTM层捕捉时间依赖性,最后通过Self-Attention层增强对序列中重要时间步的关注。多层次特征捕捉该模型综合了CNN的空间特征提取能力、LSTM的时间依赖建模能力以及Self-Attention的全局相关性捕捉能力,能够更准确地处理复杂的序列数据。 由于其强大的特征提取和序列建模能力,该模型可广泛应用于各种时空数据的预测和分析任务,为实际应用提供了有力的支持。

NO.1|卷积神经网络(CNN)

CNN主要用于提取序列数据中的空间特征。通过卷积核在输入数据上滑动,CNN可以识别局部区域内的模式,如图像中的边缘或时序数据中的特定波形。在序列数据处理中,CNN能够检测到局部特征,如风速数据中的局部波动或光伏功率数据中的日间模式。卷积操作通常伴随着池化层,用于减小特征图的空间维度,降低计算复杂度,同时保留最重要的特征。

卷积神经网络(Convolutional Neural Networks, CNN)是一种深度学习模型。在处理原始数据信息量较大的问题时,卷积神经网络可对其进行降维,继而减少参数,使学习效果更精确且简洁。CNN网络包括以下五部分:输入层、卷积层、池化层、全连接层、输出层。结构如图所示。

CNN-LSTM

(1)输入层将每个数据视为一个特征点。

(2)卷积层通常包含多个卷积核,各个卷积核的尺寸大小一般不同,卷积层的主要作用是在原始输入数据上提取出重要信息。

(3)池化层对卷积结果进行降维和压缩,提取出重要特征,减少网络参数。

(4)全连接层将池化层输出的三维张量变成向量的形式,传递给下一层。

(5)输出层为Softmax层,Softmax层的输入为全连接层的输出,Softmax层的输出作为整个神经网络的输出。

NO.2|LSTM原理

长短期记忆网络(Long Short-Term Memory Networks, LSTM)是RNN神经网络的一种改进网络,能够解决RNN在学习过长时间序列时出现的梯度消失问题,可以避免长期依赖问题。LSTM引入了细胞状态的连接,同时给隐藏层加入三个门,可以选择性保留有用的信息。加入的三个门分别是遗忘门、输入门和输出门,通过这些门控机制来控制信息的流动。

CNN-LSTM

NO.3|注意力机制

注意力机制分为硬注意力机制和软注意力机制。硬注意力可看作一种随机过程,某时刻只关注一个位置的信息,采用One-hot形式表现该时刻此位置信息是否被选中,不适合用于时间序列预测问题;软注意力机制某时刻会考虑所有位置的输入,为每一个特征分配一个注意力权值,再进行训练,更适用于时间序列预测问题。注意力机制计算公式如下:       式中,hi为现有数据;h*为计算得到的最终结果。注意力机制主要是计算权重值α,本实验选用加性注意力机制计算权值,计算公式如下:     为权重矩阵       式中,s(t-1)为t-1时刻的模型隐状态;  为求取的t时刻、第j个参数的权重值。

NO.4|CNN-LSTM-Attention网络模型

CNN-LSTM-Attention网络模型,是由CNN网络、LSTM网络和Attention机制组合得到的一种网络模型。该模型的数据处理过程包括五个步骤:

1.将输入的时间序列变换为神经网络需要的矩阵形式。

2.将矩阵输入CNN网络中进行数据的特征提取和降维。

3.将提取的特征序列输入LSTM网络中进行训练。

4.利用Attention机制对LSTM网络的输出进行自动加权平均计算。

5.采用全连接层计算预测数据

CNN-LSTM

NO.5|引入Attention的LSTM

针对LSTM网络对隐藏层的输出层泛化处理的问题,将Attention模型引入隐藏层和输出层之间。

CNN-LSTM

图中  代表某时刻LSTM的输入数据,  代表该时刻LSTM的隐藏层输出。在隐藏层后加入注意力模型,便可计算各个LSTM单元隐藏层输出的注意力权重值,即  ,然后进行加权平均计算得到输出v,将v 值传到Softmax层,进行全连接计算得到最终输出结果。部分代码及运行结果如下:

%% 导入数据data = xlsread('data.xlsx');%% 数据分析train_ratio = 0.875;                               % 训练集占数据集比例output_dim = 1;                                    % 最后一列为输出total_samples = size(data, 1);                     % 样本个数% data = data(randperm(total_samples), :);          % 打乱数据集(不希望打乱时,注释该行)num_train_samples = ceil(train_ratio * total_samples) + 1;  % 训练集样本个数input_dim = size(data, 2) - output_dim;            % 输入特征维度
%% 划分训练集和测试集X_train = data(1:num_train_samples, 1:input_dim)';Y_train = data(1:num_train_samples, input_dim + 1:end)';train_size = size(X_train, 2);
X_test = data(num_train_samples + 1:end, 1:input_dim)';Y_test = data(num_train_samples + 1:end, input_dim + 1:end)';test_size = size(X_test, 2);
%% 数据归一化[X_train_norm, input_norm_params] = mapminmax(X_train, 0, 1);X_test_norm = mapminmax('apply', X_test, input_norm_params);
[Y_train_norm, output_norm_params] = mapminmax(Y_train, 0, 1);Y_test_norm = mapminmax('apply', Y_test, output_norm_params);
%% 数据平铺X_train_norm = double(reshape(X_train_norm, input_dim, 1, 1, train_size));X_test_norm  = double(reshape(X_test_norm , input_dim, 1, 1, test_size));Y_train_norm = double(Y_train_norm)';Y_test_norm  = double(Y_test_norm )';
%% 数据格式转换for i = 1 : train_size    X_train_cells{i, 1} = X_train_norm(:, :, 1, i);end
for i = 1 : test_size    X_test_cells{i, 1}  = X_test_norm(:, :, 1, i);end    %% 建立模型net_graph = layerGraph();                                                 % 建立空白网络结构
input_layers = [    sequenceInputLayer([input_dim, 1, 1], "Name", "sequence_input")       % 建立输入层,输入数据结构为[input_dim, 1, 1]    sequenceFoldingLayer("Name", "sequence_fold")];                       % 建立序列折叠层net_graph = addLayers(net_graph, input_layers);                           % 将上述网络结构加入空白结构中
conv1_layers = convolution2dLayer([1, 1], 32, "Name", "conv_layer_1");    % 卷积层 卷积核[1, 1] 步长[1, 1] 通道数 32net_graph = addLayers(net_graph, conv1_layers);                           % 将上述网络结构加入空白结构中 relu_conv_layers = [    reluLayer("Name", "relu_layer_1")                                     % 激活层    convolution2dLayer([1, 1], 64, "Name", "conv_layer_2")                % 卷积层 卷积核[1, 1] 步长[1, 1] 通道数 64    reluLayer("Name", "relu_layer_2")];                                   % 激活层net_graph = addLayers(net_graph, relu_conv_layers);                       % 将上述网络结构加入空白结构中
se_attention_layers = [    globalAveragePooling2dLayer("Name", "global_avg_pool")                % 全局平均池化层    fullyConnectedLayer(16, "Name", "fc_layer_2")                         % SE注意力机制,通道数的1 / 4    reluLayer("Name", "relu_layer_3")                                     % 激活层    fullyConnectedLayer(64, "Name", "fc_layer_3")                         % SE注意力机制,数目和通道数相同    sigmoidLayer("Name", "sigmoid_layer")];                               % 激活层net_graph = addLayers(net_graph, se_attention_layers);                    % 将上述网络结构加入空白结构中
multiply_layer = multiplicationLayer(2, "Name", "multiply_layer");        % 点乘的注意力net_graph = addLayers(net_graph, multiply_layer);                         % 将上述网络结构加入空白结构中
lstm_layers = [    sequenceUnfoldingLayer("Name", "sequence_unfold")                     % 建立序列反折叠层    flattenLayer("Name", "flatten_layer")                                 % 网络铺平层    lstmLayer(6, "Name", "lstm_layer", "OutputMode", "last")              % lstm层    fullyConnectedLayer(1, "Name", "output_fc_layer")                     % 全连接层    regressionLayer("Name", "regression_output")];                        % 回归层net_graph = addLayers(net_graph, lstm_layers);                            % 将上述网络结构加入空白结构中
net_graph = connectLayers(net_graph, "sequence_fold/out", "conv_layer_1");               % 折叠层输出 连接 卷积层输入;net_graph = connectLayers(net_graph, "sequence_fold/miniBatchSize", "sequence_unfold/miniBatchSize");                                                                        % 折叠层输出 连接 反折叠层输入  net_graph = connectLayers(net_graph, "conv_layer_1", "relu_layer_1");                    % 卷积层输出 链接 激活层net_graph = connectLayers(net_graph, "conv_layer_1", "global_avg_pool");                    % 卷积层输出 链接 全局平均池化net_graph = connectLayers(net_graph, "relu_layer_2", "multiply_layer/in2");        % 激活层输出 链接 相乘层net_graph = connectLayers(net_graph, "sigmoid_layer", "multiply_layer/in1");       % 全连接输出 链接 相乘层net_graph = connectLayers(net_graph, "multiply_layer", "sequence_unfold/in");      % 点乘输出
%% 参数设置train_options = trainingOptions('adam', ...      % Adam 梯度下降算法    'MaxEpochs', 100, ...                        % 最大迭代次数    'InitialLearnRate', 1e-2, ...                % 初始学习率为0.01    'LearnRateSchedule', 'piecewise', ...        % 学习率下降    'LearnRateDropFactor', 0.5, ...              % 学习率下降因子 0.5    'LearnRateDropPeriod', 150, ...              % 经过700次训练后 学习率为 0.01 * 0.1    'Shuffle', 'every-epoch', ...                % 每次训练打乱数据集    'Plots', 'training-progress', ...            % 画出曲线    'Verbose', false);
%% 训练模型trained_net = trainNetwork(X_train_cells, Y_train_norm, net_graph, train_options);
%% 模型预测Y_train_pred = predict(trained_net, X_train_cells);Y_test_pred = predict(trained_net, X_test_cells);

CNN-LSTM

CNN-LSTM

-----------------------误差计算--------------------------评价结果如下所示:平均绝对误差MAE为:0.86055均方误差MSE为:       1.077均方根误差RMSE为:  1.0378决定系数R^2为:  0.93582剩余预测残差RPD为:  3.9505

Suthel 群智能算法小狂人

THE END