当前位置: 首页 > article >正文

2-2 MATLAB鮣鱼优化算法ROA优化CNN超参数回归预测

本博客来源于CSDN机器鱼,未同意任何人转载。

更多内容,欢迎点击本专栏目录,查看更多内容。

目录

0.引言

1.ROA优化CNN

2.主程序调用

3.结语


0.引言

在博客【ROA优化LSTM超参数回归】中,我们采用ROA对LSTM的学习率、迭代次数、batchsize、两个lstmlayer的节点数进行寻优,在优化过程中我们不必知道ROA的具体优化原理,只需要修改lb、ub、维度D、边界判断、适应度函数即可。今天这边博客,我们依旧采用此前提到的步骤对CNN的超参数进行回归,话不多说,首先我们定义一个超级简单的CNN网络进行回归预测,代码如下:

clc;clear;close all;rng(0)
%% 数据的提取
load data%数据是4输入1输出的简单数据
train_x;%4*98
train_y;%1*98
test_x;%4*42
test_y;%1*98
%转成CNN的输入格式
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);

观察网络构建与训练,我们发现至少有9个参数需要优化,分别是:迭代次数MaxEpochs、MiniBatchSize、第一层卷积层的核大小和数量、第2层卷积层的核大小和数量,以及两个全连接层的神经元数量,还有学习率InitialLearnRate(学习率放最后是因为其他的都是整数,只有这个是小数,要么放最前要么放最后,方便我们写边界判断函数与初始化种群的程序)

1.ROA优化CNN

步骤1:知道要优化的参数与优化范围。显然就是上面提到的9个参数。代码如下,首先改写lb与ub,然后初始化的时候注意除了学习率,其他的都是整数。并将原来里面的边界判断,改成了Bounds函数,方便在计算适应度函数值的时候转化成整数与小数。如果学习率的位置不在最后,而是在其他位置,就需要改随机初始化位置和Bounds函数与fitness函数里对应的地方,具体怎么改就不说了,很简单。

function [Rbest,Convergence_curve,process]= roa_cnn(X1,y1,Xt,yt)
D=9;%一共有9个参数需要优化,分别是迭代次数、batchsize、第一层卷积层的核大小、和数量、第2层卷积层的核大小、和数量,以及两个全连接层的神经元数量,学习率
lb= [10 16  1 1 1 1 1 1 0.001];    % 下边界
ub= [50 256 3 20 3 20 50 50 0.01];    % 上边界
% 迭代次数的范围是10-50 batchsize的范围是16-256 核大小的范围是1-3 核数量的范围是1-20 全连接层的范围是1-50
 % 学习率的范围是0.001-0.01
sizepop=5;
maxgen=10;% maxgen 为最大迭代次数,
% sizepop 为种群规模
%记D为维度,lb、 ub分别为搜索上、下限
R=ones(sizepop,D);%预设种群
for i=1:sizepop%随机初始化位置
    for j=1:D
        if j==D%除了学习率 其他的都是整数
            R( i, j ) = (ub(j)-lb(j))*rand+lb(j);
        else
            R( i, j ) = round((ub(j)-lb(j))*rand+lb(j));
        end
    end
end

for k= 1:sizepop
    Fitness(k)=fitness(R(k,:),X1,y1,Xt,yt);%个体适应度
end
[Fbest,elite]= min(Fitness);%Fbest为最优适应度值
Rbest= R(elite,:);%最优个体位置
H=zeros(1,sizepop);%控制因子


%主循环
for iter= 1:maxgen
    Rpre= R;%记录上一代的位置
    V=2*(1-iter/maxgen);
    B= 2*V*rand-V;
    a=-(1 + iter/maxgen);
    alpha=rand*(a-1)+ 1;
    for i= 1:sizepop
        if H(i)==0
            dis = abs(Rbest-R(i,:));
            R(i,:)= R(i,:)+ dis* exp(alpha)*cos(2*pi* alpha);
        else
            RAND= ceil(rand*sizepop);%随机选择一个个体
            R(i,:)= Rbest -(rand*0.5*(Rbest + R(RAND,:))- R(RAND,:));
        end
        Ratt= R(i,:)+ (R(i,:)- Rpre(i,:))*randn;%作出小幅度移动
        %边界吸收
        R(i, : ) = Bounds( R(i, : ), lb, ub );%对超过边界的变量进行去除
        Ratt = Bounds( Ratt, lb, ub );%对超过边界的变量进行去除
        Fitness(i)=fitness(R(i,:),X1,y1,Xt,yt);
        Fitness_Ratt= fitness(Ratt,X1,y1,Xt,yt);
        if Fitness_Ratt < Fitness(i)%改变寄主
            if H(i)==1
                H(i)=0;
            else
                H(i)=1;
            end
        else %不改变寄主
            A= B*(R(i,:)-rand*0.3*Rbest);
            R(i,:)=R(i,:)+A;
        end
        
        R(i, : ) = Bounds( R(i, : ), lb, ub );%对超过边界的变量进行去除
        
    end
    %更新适应度值、位置
    [fbest,elite] = min(Fitness);
    %更新最优个体
    if fbest< Fbest
        Fbest= fbest;
        Rbest= R(elite,:);
    end
    process(iter,:)=Rbest;
    Convergence_curve(iter)= Fbest;
    iter,Fbest,Rbest
end

end

function s = Bounds( s, Lb, Ub)
temp = s;
dim=length(Lb);
for i=1:length(s)
    if i==dim%除了学习率 其他的都是整数
        temp(:,i) =temp(:,i);
    else
        temp(:,i) =round(temp(:,i));
    end
end

% 判断参数是否超出设定的范围

for i=1:length(s)
    if temp(:,i)>Ub(i) | temp(:,i)<Lb(i) 
        if i==dim%除了学习率 其他的都是整数
            temp(:,i) =rand*(Ub(i)-Lb(i))+Lb(i);
        else
            temp(:,i) =round(rand*(Ub(i)-Lb(i))+Lb(i));
        end
    end
end
s = temp;
end
function s = Bounds( s, Lb, Ub)
temp = s;
for i=1:length(s)
    if i==1%除了学习率 其他的都是整数
        temp(:,i) =temp(:,i);
    else
        temp(:,i) =round(temp(:,i));
    end
end

% 判断参数是否超出设定的范围

for i=1:length(s)
    if temp(:,i)>Ub(i) | temp(:,i)<Lb(i) 
        if i==1%除了学习率 其他的都是整数
            temp(:,i) =rand*(Ub(i)-Lb(i))+Lb(i);
        else
            temp(:,i) =round(rand*(Ub(i)-Lb(i))+Lb(i));
        end
    end
end
s = temp;
end

步骤2:知道优化的目标。优化的目标是提高的网络的准确率,而ROA代码我们这个代码是最小值优化的,所以我们的目标可以是最小化CNN的预测误差。预测误差具体是,测试集(或验证集)的预测值与真实值之间的均方差。

步骤3:构建适应度函数。通过步骤2我们已经知道目标,即采用ROA去找到9个值,用这9个值构建的CNN网络,误差最小化。观察下面的代码,首先我们将ROA的值传进来,然后转成需要的9个值,然后构建网络,训练集训练、测试集预测,计算预测值与真实值的mse,将mse作为结果传出去作为适应度值。

function y=fitness(x,trainD,targetD,testD,targetD_test)
rng(0)
%% 将传进来的值 转换为需要的超参数
iter=x(1);
minibatch=x(2);
kernel1_size=x(3);
kernel1_num=x(4);
kernel2_size=x(5);
kernel2_num=x(6);
fc1_num=x(7);
fc2_num=x(8);
lr=x(9);

feature=size(trainD,1);
%% 利用寻优得到参数重新训练CNN与预测 
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, ...
    'shuffle','every-epoch',...
    'Verbose',false);
net = trainNetwork(trainD,targetD,layers,options);
YPred = predict(net,testD);
%% 适应度值计算
YPred=double(YPred);
%以CNN的预测值与实际值的均方误差最小化作为适应度函数,SSA的目的就是找到一组超参数
%用这组超参数训练得到的CNN的误差能够最小化
[m,n]=size(YPred);
YPred=reshape(YPred,[1,m*n]);
targetD_test=reshape(targetD_test,[1,m*n]);
y=mse(YPred,targetD_test);



rng(sum(100*clock))

2.主程序调用

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

%% 数据的提取
load data
load data%数据是4输入1输出的简单数据
train_x;%4*98
train_y;%1*98
test_x;%4*42
test_y;%1*98
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';


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

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

disp('优化后的各超参数')

iter=x(1)%迭代次数
minibatch=x(2)%batchsize 
kernel1_size=x(3)
kernel1_num=x(4)%第一层卷积层的核大小与核数量
kernel2_size=x(5)
kernel2_num=x(6)%第2层卷积层的核大小与核数量
fc1_num=x(7)
fc2_num=x(8)%两个全连接层的神经元数量
lr=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就是调用训练好的网络 
if train_again==1
    [net,traininfo] = trainNetwork(trainD,targetD,layers,options);
    save result/roacnn_net net traininfo
else
    load result/roacnn_net
end

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


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


3.结语

优化网络超参数的格式都是这样的!只要会改一种,那么随便拿一份能跑通的优化算法,在不管原理的情况下,都能用来优化网络的超参数。更多内容【点击专栏】目录。


http://www.kler.cn/a/610309.html

相关文章:

  • QLoRA和LoRA 微调
  • 01-系统编程
  • 从零开始的大模型强化学习框架verl解析
  • AWE 2025:当AI科技遇见智能家居
  • 基于javaweb的SpringBoot线上网络文件管理系统设计与实现(源码+文档+部署讲解)
  • 【Linux网络】——Socket网络编程
  • 6. 理解中间件与认证中间件
  • 失踪人口回归之Java开发工程师面试记录第二篇
  • AI小白的第七天:必要的数学知识(概率)
  • 前端面试:如何去衡量用户操作过程中否卡顿?
  • LLM实践(二)——基于llama-factory的模型微调
  • 蓝桥杯高频考点——二分(含C++源码)
  • Go 1.24 新特性解析:泛型类型别名、弱指针与终结器改进
  • 论文阅读笔记——Diffuser,Diffusion Policy
  • java使用小知识合集(持续更新中)
  • 栈-常见考察面试算法题
  • 生活电子常识——cmd不能使用anaconda的python环境,导致输入python打开应用商店
  • Driver具体负责什么工作
  • 大疆上云api直播功能如何实现
  • odata 搜索帮助