clc; clear; close all; %% -------------- 1.初始化变量 ------ ---------- opt.Delays = 1:30;%数据滞后30 %opt.dataPreprocessMode为数据预处理,'None'代表无处理,'Data Standardization'代表标准化处理, %'Data Normalization'代表归一化处理 opt.dataPreprocessMode = 'Data Standardization'; %三种数据处理方式 'None' 'Data Standardization' 'Data Normalization' opt.learningMethod = 'LSTM';%选择LSTM作为训练模型 opt.trPercentage = 0.80; % 将数据划分为测试和训练数据集,0.8代表训练集比例 %----2.通用深度学习参数(LSTM和CNN通用参数) opt.maxEpochs = 50; %400 % 深度学习算法中最大训练次数。 opt.miniBatchSize = 32; % 深度学习算法中的样本最小批处理数量大小。 opt.executionEnvironment = 'cpu'; % 运行环境 'cpu' 'gpu' 'auto' opt.LR = 'adam'; %LSTM学习函数 'sgdm' 'rmsprop' 'adam' opt.trainingProgress = 'none'; %是否运行训练图 'training-progress' 'none' % ------------- 3.BILSTM参数 opt.isUseBiLSTMLayer = true; % 如果为true,则为双向 LSTM,如果为false,则转为单向LSTM opt.isUseDropoutLayer = true; % dropout 层避免过拟合 opt.DropoutValue = 0.5; % dropout 层概率为0.5 % ------------ 4.优化参数 opt.optimVars = [ optimizableVariable('NumOfLayer',[1 4],'Type','integer') %优化LSTM隐含层层数(1-4) ,层数数据类型为整数 optimizableVariable('NumOfUnits',[50 200],'Type','integer')%优化LSTM隐含层神经元(50-200) ,数据类型为整数 optimizableVariable('isUseBiLSTMLayer',[1 2],'Type','integer')%优化LSTM结构,1代表LSTM,2代表Bilstm, ,数据类型为整数 optimizableVariable('InitialLearnRate',[1e-2 1],'Transform','log')%优化LSTM初始学习率(0.01-1) ,数据类型为浮点型 optimizableVariable('L2Regularization',[1e-10 1e-2],'Transform','log')];%优化LSTM正则化L2系数(1e-10-1e-2) ,数据类型为浮点型 opt.isUseOptimizer = true;%是否选择贝叶斯优化 opt.MaxOptimizationTime = 14*20;%优化运行的最大时间14*60*60 opt.MaxItrationNumber = 10;%优化运行的最大迭代次数60 opt.isDispOptimizationLog = true;%是否展示优化过程日志 opt.isSaveOptimizedValue = false; % 是否将所有优化输出保存在 mat 文件中 opt.isSaveBestOptimizedValue = true; % 是否将最佳优化输出保存为 mat 文件
运行完以上代码,可生成opt结构数据
PS:导入的数据必须是一列数据!!
%% --------------- 5.加载数据 data = loadData(opt); %导入数据,案例数据为一列数据 ,A2:A145共 144个数据。 if ~data.isDataRead %表示如果数据已经被打开了,那么不会重复导入数据 return; end
运行代码得出界面
原始数据序列图
标准化预处理
其中CompleteData为完整数据table格式,包含你的excel数据的表头,即seriesdataHeder中的’International’,seriesdata为时间序列数据,x为seriesdata数据预处理后的数据。
loadData.m
%% ---------------------------- 加载数据调用函数 ---------------------------
function data = loadData(opt) [chosenfile,chosendirectory] = uigetfile({'*.xlsx';'*.csv'},...%uigetfile函数如果打开了文件,则返回1,如果取消,则返回0 'Select Excel time series Data sets','data.xlsx');% 选择数据,chosenfile为文件名,chosendirectory为文件所在文件夹路径 filePath = [chosendirectory chosenfile];%filePath为该文件的路径 if filePath ~= 0 % 表示如果数据被打开 data.DataFileName = chosenfile;%创建data结构数据,包含文件名 data.CompleteData = readtable(filePath);%创建data结构数据,包含文件路径 if size(data.CompleteData,2)>1 %判断是否是一列数据 warning('输入数据应该是一个excel文件且只有一列!'); disp('Operation Failed... '); pause(.9); disp('Reloading data. '); pause(.9); data.x = [];% x数据空白 data.isDataRead = false;%数据不可阅读 return; end data.seriesdataHeder = data.CompleteData.Properties.VariableNames(1,:);%创建data结构数据,包含数据表头标题 data.seriesdata = table2array(data.CompleteData(:,:));%%创建data结构数据,包含mat格式的序列数据 disp('Input data successfully read.');%输出 输入数据成功读取 data.isDataRead = true;%数据读取成功 data.seriesdata = PreInput(data.seriesdata);%PreInput调用函数,表示如果数据是cell形式,会将cell转化为数值形式 figure('Name','InputData','NumberTitle','off');%绘图 ,时间序列数据绘图, 且标题包含均值和标准值结果 plot(data.seriesdata); grid minor; title({['Mean = ' num2str(mean(data.seriesdata)) ', STD = ' num2str(std(data.seriesdata)) ];}); if strcmpi(opt.dataPreprocessMode,'None') %判断数据处理形式,此处为无预处理 data.x = data.seriesdata; elseif strcmpi(opt.dataPreprocessMode,'Data Normalization') %判断数据处理形式,此处为归一化预处理 data.x = DataNormalization(data.seriesdata); figure('Name','NormilizedInputData','NumberTitle','off'); plot(data.x); grid minor; title({['Mean = ' num2str(mean(data.x)) ', STD = ' num2str(std(data.x)) ];}); elseif strcmpi(opt.dataPreprocessMode,'Data Standardization') %判断数据处理形式,此处为标准化预处理 data.x = DataStandardization(data.seriesdata); figure('Name','NormilizedInputData','NumberTitle','off'); plot(data.x); grid minor; title({['Mean = ' num2str(mean(data.x)) ', STD = ' num2str(std(data.x)) ];}); end else warning(['为了训练网络,请加载数据。' ... %此处表示数据没有读取,会进行相关提示。 '输入数据应该是一个excel文件且只有一个列!']); disp('操作取消.'); data.isDataRead = false; end end %% --------------- 6.数据样本处理 [opt,data] = PrepareData(opt,data);
%代码运行后,会得到样本数据处理结果,前30个数据预测后1个数据 ,输入特征为30,输出特征为1,且训练:测试=8:2
data = 包含以下字段的 struct:
DataFileName: ‘InternationalAirlinePassengers.xlsx’
CompleteData: [144×1 table]
seriesdataHeder: {‘International’}
seriesdata: [144×1 double]
isDataRead: 1
x: [144×1 double]
X: [30×114 double]
Y: [1×114 double]
XTr: {91×1 cell} %样本训练集输入
YTr: [91×1 double]%样本训练集输出
XTs: {23×1 cell} %样本测试集输入
YTs: [23×1 double]%样本测试集输出
XVl: {23×1 cell}
YVl: [23×1 double]
X为样本输入,Y为样本输出。
PrepareData.m
% --------------- 数据准备 --- function [opt,data] = PrepareData(opt,data) % 数据滞后构建时间序列数据 data = CreateTimeSeriesData(opt,data); %根据滑动窗口数值即滞后数,将一列数据,转化为样本输入和样本输出 %将数据划分为测试和训练数据 data = dataPartitioning(opt,data); %建立训练集、测试集样本 % LSTM数据形式 data = LSTMInput(data);%数据类型处理, 如输入数据为cell形式,每个cell单元格包含训练样本数量的30*1个数据 end
%% --------------- 7.使用贝叶斯优化找到最佳 LSTM 参数
[opt,data] = OptimizeLSTM(opt,data);
10次迭代中,误差最小对应的LSTM结构及参数
运行过程__________________________________________________________
优化完成。
达到 MaxObjectiveEvaluations 10。
函数计算总次数: 10
总历时: 82.0708 秒。
总目标函数计算时间: 65.0795
观测到的最佳可行点:
NumOfLayer NumOfUnits isUseBiLSTMLayer InitialLearnRate L2Regularization
__________ __________ ________________ __________________ ____________________
2 65 1 0.0165185146872761 1.73848840686278e-05
观测到的目标函数值 = 0.092506
估计的目标函数值 = 0.094029
函数计算时间 = 3.2681
估计的最佳可行点(根据模型):
NumOfLayer NumOfUnits isUseBiLSTMLayer InitialLearnRate L2Regularization
__________ __________ ________________ __________________ ____________________
2 65 1 0.0165185146872761 1.73848840686278e-05
估计的目标函数值 = 0.094029
估计的函数计算时间 = 4.1336
% - - - - -贝叶斯优化运行Hyperparameters LSTM网络参数
function [opt,data] = OptimizeLSTM(opt,data) if opt.isDispOptimizationLog %如果展示过程运行日志,则isLog为2,不展示则为0 isLog = 2; else isLog = 0; end if opt.isUseOptimizer%如果运用贝叶斯优化 opt.ObjFcn = ObjFcn(opt,data);%目标函数构建(目标函数较为复杂,包含预设几层LSTM结构,是否是Bilstm结构等,不过多介绍) BayesObject = bayesopt(opt.ObjFcn,opt.optimVars, ... 'MaxTime',opt.MaxOptimizationTime, ... %运行最长时间 'IsObjectiveDeterministic',false, ...%目标动态变化 'MaxObjectiveEvaluations',opt.MaxItrationNumber,...%最大迭代次数 'Verbose',isLog,...%运行日志 'UseParallel',false);%并行运算 end end ObjFcn.m部分关键代码 % --------------- 训练网络 try data.BiLSTM.Net = trainNetwork(data.XTr,data.YTr,opt.layers,opt.opts); %如果网络建立没问题,则运行成功 disp('LSTM Netwwork successfully trained.'); data.IsNetTrainSuccess =true; catch me disp('Error on Training LSTM Network'); data.IsNetTrainSuccess = false; return; end close(findall(groot,'Tag','NNET_CNN_TRAININGPLOT_UIFIGURE')) predict(data.BiLSTM.Net,data.XVl,'MiniBatchSize',opt.miniBatchSize);%将建立好的网络结构,输入验证数据,进行预测 valError = mse(predict(data.BiLSTM.Net,data.XVl,'MiniBatchSize',opt.miniBatchSize)-data.YVl); %误差为预测测试集输出数据与实际测试集输出数据的均方根误差 Net = data.BiLSTM.Net; Opts = opt.opts; fieldName = ['ValidationError' strrep(num2str(valError),'.','_')];%每次迭代会将对应的结构和参数进行保存为mat格式,并以误差数值进行命名 if ismember('OptimizedParams',evalin('base','who')) OptimizedParams = evalin('base', 'OptimizedParams'); OptimizedParams.(fieldName).Net = Net; OptimizedParams.(fieldName).Opts = Opts; assignin('base','OptimizedParams',OptimizedParams); else OptimizedParams.(fieldName).Net = Net; OptimizedParams.(fieldName).Opts = Opts; assignin('base','OptimizedParams',OptimizedParams); end fileName = num2str(valError) + ".mat"; if opt.isSaveOptimizedValue save(fileName,'Net','valError','Opts') end cons = []; end
%% --------------- 8.评估结果
[opt,data] = EvaluationData(opt,data);
R2训练集拟合效果
训练集拟合误差
差
训练集拟合误差直方图
训练集线性拟合效果
测试集预测结果
测试集误差
测试集误差直方图
测试集线性拟合效果
总数据拟合效果
总数据拟合误差
总数据误差直方图
总数据线性拟合效果