在CNN模型的构建中,涉及到特别多的超参数,比如:学习率、训练次数、batchsize、各个卷积层的卷积核大小与卷积核数量(feature map数),全连接层的节点数等。直接选择的话,很难选到一组满意的参数,因此采用优化算法进行超参数优化,相比于多次尝试,优化算法会遵循自己的一套策略进行优化选择。

        基于此思想,本文采用麻雀优化算法,对CNN上述9个超参数进行优化。

1,麻雀优化算法原理

       麻雀优化是2020年提出来得,具体原理:原理点这里

2、麻雀优化CNN的原理

        一般情况下进行参数的优化的时候,就是给CNN网络设一组超参数,然后训练并验证,取验证集精度最高的那个模型(这个模型就可以认为具有最优超参数)。其实优化算法也是这样,它们都是不断地产生新的超参数组合,然后用这组超参数建立CNN网络,训练并验证。只不过,优化算法是有自己的学习规律。我们对CNN超参数进行优化,也就是让SSA一直有去找能够让验证集满足精度最大化的那一组超参数。

3、代码实现:

        数据采用多输入单输出,在我的excel表中,最后一列是输出,前几列都是输入,当然你也可以换成多输出格式,这样把自己的input和output写对即可。

        3.1 CNN模型


clc;clear;close all;rng(0)
%% 数据的提取
data=xlsread('data.xlsx');
input=data(:,1:end-1);%x
output=data(:,end);%y

%% 数据处理
n=randperm(size(input,1));
m=round(size(input,1)*0.7);%随机70%作为训练集 其余30%作为测试集
train_x=input(n(1:m),:);
train_y=output(n(1:m),:);
test_x=input(n(m+1:end),:);
test_y=output(n(m+1:end),:);

% 归一化或者标准化
method=@mapminmax;
% method=@mapstd;
[train_x,train_ps]=method(train_x');
test_x=method('apply',test_x',train_ps);
[train_y,output_ps]=method(train_y');
test_y=method('apply',test_y',output_ps);

feature=size(train_x,1);
num_train=size(train_x,2);
num_test=size(test_x,2);
trainD=reshape(train_x,[feature,1,1,num_train]);
testD=reshape(test_x,[feature,1,1,num_test]);
targetD = train_y';
targetD_test  = test_y';

%% 
layers = [
    imageInputLayer([size(trainD,1) size(trainD,2) size(trainD,3)]) % 输入
    convolution2dLayer(3,4,'Stride',1,'Padding','same')%核3*1 数量4 步长1 填充为same
    reluLayer%relu激活
    convolution2dLayer(3,8,'Stride',1,'Padding','same')%核3*1 数量8 步长1 填充为same
    reluLayer%relu激活
    fullyConnectedLayer(20) % 全连接层1 20个神经元
    reluLayer
    fullyConnectedLayer(20) % 全连接层2 20个神经元
    reluLayer
    fullyConnectedLayer(size(targetD,2)) %输出层
    regressionLayer];
options = trainingOptions('adam', ...
    'ExecutionEnvironment','cpu', ...
    'MaxEpochs',30, ...
    'MiniBatchSize',16, ...
    'InitialLearnRate',0.01, ...
    'GradientThreshold',1, ...
    'shuffle','every-epoch',...
    'Verbose',false);
train_again=1;% 为1就代码重新训练模型,为0就是调用训练好的网络
if train_again==1
    [net,traininfo] = trainNetwork(trainD,targetD,layers,options);
    save result/cnn_net net traininfo
else
    load result/cnn_net
end
figure;
plot(traininfo.TrainingLoss,'b')
hold on;grid on
ylabel('损失')
xlabel('训练次数')
title('CNN')


%% 结果评价
YPred = predict(net,testD);YPred=double(YPred);

% 反归一化
predict_value=method('reverse',YPred',output_ps);predict_value=double(predict_value);
true_value=method('reverse',targetD_test',output_ps);true_value=double(true_value);

save result/cnn_result predict_value true_value
%%
figure
plot(true_value,'-*','linewidth',3)
hold on
plot(predict_value,'-s','linewidth',3)
legend('实际值','预测值')
title('CNN')
grid on

result(true_value,predict_value)


损失曲线与测试集结果如图所示:

cnn模型性能优化 cnn参数优化_cnn

cnn模型性能优化 cnn参数优化_matlab_02

 结果如下: 

R-square决定系数(R2):0.79945
平均相对误差(MPE):0.20031
平均绝对百分误差(MAPE):20.0306%
平均绝对误差(MAE):0.32544
根均方差(RMSE):0.47113

        3.2 SSA优化CNN

clc;clear;close all;format compact;rng(0)

%% 数据的提取
data=xlsread('data.xlsx');
input=data(:,1:end-1);%x
output=data(:,end);%y
%% 数据处理
n=randperm(size(input,1));
m=round(size(input,1)*0.7);%随机70%作为训练集 其余30%作为测试集
train_x=input(n(1:m),:);
train_y=output(n(1:m),:);
test_x=input(n(m+1:end),:);
test_y=output(n(m+1:end),:);

% 归一化或者标准化
method=@mapminmax;
% method=@mapstd;
[train_x,train_ps]=method(train_x');
test_x=method('apply',test_x',train_ps);
[train_y,output_ps]=method(train_y');
test_y=method('apply',test_y',output_ps);

feature=size(train_x,1);
num_train=size(train_x,2);
num_test=size(test_x,2);
trainD=reshape(train_x,[feature,1,1,num_train]);
testD=reshape(test_x,[feature,1,1,num_test]);
targetD = train_y';
targetD_test  = test_y';


%% SSA优化CNN的超参数
%一共有9个参数需要优化,分别是学习率、迭代次数、batchsize、第一层卷积层的核大小、和数量、第2层卷积层的核大小、和数量,以及两个全连接层的神经元数量
optimaztion=1;  
if optimaztion==1
    [x,trace]=ssa_cnn(trainD,targetD,testD,targetD_test);
    save result/ssa_result x trace
else
    load result/ssa_result
end
%%

figure
plot(trace)
title('适应度曲线')
xlabel('优化次数')
ylabel('适应度值')

disp('优化后的各超参数')
lr=x(1)%学习率
iter=x(2)%迭代次数
minibatch=x(3)%batchsize 
kernel1_size=x(4)
kernel1_num=x(5)%第一层卷积层的核大小
kernel2_size=x(6)
kernel2_num=x(7)%第2层卷积层的核大小
fc1_num=x(8)
fc2_num=x(9)%两个全连接层的神经元数量

%% 利用寻优得到参数重新训练CNN与预测
rng(0)
layers = [
    imageInputLayer([size(trainD,1) size(trainD,2) size(trainD,3)])
    convolution2dLayer(kernel1_size,kernel1_num,'Stride',1,'Padding','same')
    reluLayer
    convolution2dLayer(kernel2_size,kernel2_num,'Stride',1,'Padding','same')
    reluLayer
    fullyConnectedLayer(fc1_num)
    reluLayer
    fullyConnectedLayer(fc2_num)
    reluLayer
    fullyConnectedLayer(size(targetD,2))
    regressionLayer];
options = trainingOptions('adam', ...
    'ExecutionEnvironment','cpu', ...
    'MaxEpochs',iter, ...
    'MiniBatchSize',minibatch, ...
    'InitialLearnRate',lr, ...
    'GradientThreshold',1, ...
    'Verbose',false);

train_again=1;% 为1就重新训练模型,为0就是调用训练好的网络  load options_data1600.mat  ,changed!must retrain   train_again=0;% 为1就重新训练模型,为0就是调用训练好的网络
if train_again==1
    [net,traininfo] = trainNetwork(trainD,targetD,layers,options);
    save result/ssacnn_net net traininfo
else
    load result/ssacnn_net
end

figure;
plot(traininfo.TrainingLoss,'b')
hold on;grid on
ylabel('损失')
xlabel('训练次数')
title('SSA-CNN')


%% 结果评价
YPred = predict(net,testD);YPred=double(YPred);

% 反归一化
predict_value=method('reverse',YPred',output_ps);predict_value=double(predict_value);
true_value=method('reverse',targetD_test',output_ps);true_value=double(true_value);

save result/ssa_cnn_result predict_value true_value
%%
figure
plot(true_value,'-*','linewidth',3)
hold on
plot(predict_value,'-s','linewidth',3)
legend('实际值','预测值')
title('SSA-CNN')
grid on

result(true_value,predict_value)

        以最小化测试集真实值与预测值的均方差为适应度函数,目的就是找到一组超参数,使得网络均方误差最低。所以适应度曲线是一条下降的曲线

cnn模型性能优化 cnn参数优化_回归_03

 

cnn模型性能优化 cnn参数优化_优化算法_04

cnn模型性能优化 cnn参数优化_cnn_05

结果如下:

R-square决定系数(R2):0.86547
平均相对误差(MPE):0.114
平均绝对百分误差(MAPE):11.3997%
平均绝对误差(MAE):0.17238
根均方差(RMSE):0.26745

可以看到测试集指标具有明显提升。 

4.代码

代码见评论区,还有更多哦

1.MATLAB麻雀优化CNN超参数回归

2.MATLAB灰狼优化CNN超参数回归

3.MATLAB鲸鱼优化CNN超参数回归

4.MATLAB麻雀优化CNN超参数分类