前言
在机器学习模型的构建和优化过程中,选择合适的超参数对模型的性能有着至关重要的影响。BP(反向传播)神经网络是一种经典的神经网络,广泛应用于包括分类和回归在内的多种任务。本文将探讨如何通过网格优化(Grid Search)方法来选择BP神经网络的超参数,并解释Matlab代码中实现这一过程的各个模块功能。
网格优化的概念
网格优化,也称为网格搜索,是一种寻找最优超参数的方法。它系统地遍历多种超参数的组合,通过交叉验证确定最佳的参数设置。这种方法虽然计算量大,但可以保证在给定的参数范围内找到最优组合。
代码解释
核心代码如下,全部代码以及多输出回归预测的实现请见小破站视频讲解:
【【炼丹炼的好,结果差不了】基于网格搜索的BP神经网络多输出预测】 https://www.bilibili.com/video/BV18t421P74N/?share_source=copy_web&vd_source=a9100554431c2d1cd88da0ebf23e97fc
全部代码详见:https://www.bilibili.com/video/BV1fb421B77N/?vd_source=81aa08b7b5e4b4ec6294af25f75ad69a
%% 定义超参数的搜索空间
hiddenLayerSizeGrid = [10, 20, 30, 40]; % 隐藏层神经元个数的候选值
learningRateGrid = [0.001, 0.01, 0.1]; % 学习率的候选值
%% 初始化记录结果的文件
fileID = fopen('tuning_results.txt', 'w');
fprintf(fileID, '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\r\n', ...
'i','HiddenLayerSize', 'LearningRate', 'RMSE_Train', 'RMSE_Test', ...
'R2_Train', 'R2_Test', 'MAE_Train', 'MAE_Test', 'MBE_Train', 'MBE_Test');
%% 超参数搜索
for h = 1:length(hiddenLayerSizeGrid)
for lr = 1:length(learningRateGrid)
%% 创建网络
net = newff(Label_train, target_train, [hiddenLayerSizeGrid(h), hiddenLayerSizeGrid(h)]);
%% 设置训练参数
net.trainParam.epochs = 500; % 迭代次数
net.trainParam.goal = 1e-6; % 误差阈值
net.trainParam.lr = learningRateGrid(lr); % 学习率
net.trainFcn = 'trainlm';
%% 训练网络
net = train(net, Label_train, target_train);
定义超参数的搜索空间
在Matlab代码的开始,我们定义了两个重要的超参数搜索空间:hiddenLayerSizeGrid
和learningRateGrid
。这两个数组分别存储了隐藏层神经元个数和学习率的候选值。
hiddenLayerSizeGrid = [10, 20, 30, 40];
learningRateGrid = [0.001, 0.01, 0.1];
初始化记录结果的文件
接下来,代码初始化了一个文件tuning_results.txt
,用于记录每次训练过程中的详细结果,包括隐藏层大小、学习率和各种性能指标。
fileID = fopen('tuning_results.txt', 'w');
fprintf(fileID, '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\r\n', ...
'i','HiddenLayerSize', 'LearningRate', 'RMSE_Train', 'RMSE_Test', ...
'R2_Train', 'R2_Test', 'MAE_Train', 'MAE_Test', 'MBE_Train', 'MBE_Test');
超参数搜索
代码中的双重循环遍历了隐藏层神经元个数和学习率的所有可能组合。对于每一种组合,都执行以下步骤:
- 创建网络:使用
newff
函数创建一个新的前馈网络。隐藏层的大小由hiddenLayerSizeGrid
数组提供。
net = newff(Label_train, target_train, [hiddenLayerSizeGrid(h), hiddenLayerSizeGrid(h)]);
- 设置训练参数:设置网络的训练参数,包括迭代次数、误差阈值和学习率。
net.trainParam.epochs = 500;
net.trainParam.goal = 1e-6;
net.trainParam.lr = learningRateGrid(lr);
net.trainFcn = 'trainlm';
- 训练网络:使用
train
函数对网络进行训练。
net = train(net, Label_train, target_train);
- 仿真测试:使用训练好的网络对训练集和测试集进行仿真,得到输出结果。
output_train = sim(net, Label_train);
output_test = sim(net, Label_test);
- 数据反归一化:最后的
mapminmax
函数将输出结果反归一化,转换回原始的数据范围。
Res_train = mapminmax('reverse', output_train, para_output);
Res_test = mapminmax('reverse', output_test, para_output);
网格优化的优点
- 全面性:网格优化通过尝试所有可能的参数组合,确保不会遗漏任何潜在的最佳解。
- 简单易行:网格优化方法概念上简单,易于理解和实施。
- 易于并行化:由于每组参数的评估是独立的,网格优化可以很容易地并行处理,从而加快搜索速度。
程序运行结果
图1 真实值和预测值散点图
图2 网格优化模型超参数结果和模型性能指标
总结
网格优化对于BP神经网络的求解来说是一个非常有力的工具,尤其当我们不确定哪些超参数组合能够产生最好的性能时。以上Matlab代码的实现展示了如何在实际任务中应用网格优化来调整BP神经网络的超参数,从而提高模型预测的准确性。