MATLAB麻雀优化CNN超参数分类

        在CNN分类器模型的构建中,涉及到特别多的超参数,比如:学习率、训练次数、batchsize、各个卷积层的卷积核大小与卷积核数量(feature map数),全连接层的节点数等。直接选择的话,很难选到一组满意的参数,因此可以用优化算法进行超参数优化,虽然过程比较慢,但是总比自己无脑试的效果好。

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

1,麻雀优化算法原理

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

2、麻雀优化CNN的原理

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

3、代码实现:

        数据是10分类,每个样本的特征维度是864,。共1000个样本,按照7:2:1划分训练集,验证集与测试集,标签是类比即可,不用转换为onehot编码。

        3.1 CNN分类模型

clc;clear;close all
%% read data
load('result/data_process.mat');
method=@mapstd;
% method=@mapminmax;
[xs,mapping]=method(train_X');train_X=xs';
xs=method('apply',test_X',mapping);test_X=xs';
xs=method('apply',valid_X',mapping);valid_X=xs';
N_train=size(train_X,1);
N_feature=size(train_X,2);
for i=1:N_train
    trainD(:,:,:,i)=reshape(train_X(i,:),[N_feature 1 1]);
end
N_valid=size(valid_X,1);
for i=1:N_valid
    XValidation(:,:,:,i)=reshape(valid_X(i,:),[N_feature 1 1]);
end
N_test=size(test_X,1);
for i=1:N_test
    testD(:,:,:,i)=reshape(test_X(i,:),[N_feature 1 1]);
end
targetD=categorical(train_Y);

YValidation=categorical(valid_Y);

target_testD=categorical(test_Y);
%% define network
layers = [
    imageInputLayer([size(trainD,1) ,size(trainD,2), size(trainD,3)]) %
    convolution2dLayer(5,8,'Padding','same') % 5x5 filtr ,8 kernel padding=‘same’,stride=1(default)
    %     batchNormalizationLayer% batch Normalization
    reluLayer % relu activation function
    maxPooling2dLayer(2,'Stride',2,'Padding','same')% 2x2 kernel stride=2,padding=1
    
    convolution2dLayer(5,16,'Padding','same') % 5x5 filtr ,16 kernel padding=‘same’,stride=1(default)
    %     batchNormalizationLayer
    reluLayer % relu activation function
    maxPooling2dLayer(2,'Stride',2,'Padding','same')% 2x2 kernel stride=2
    
    fullyConnectedLayer(128) %fc 128
    reluLayer
    fullyConnectedLayer(10) % classes
    softmaxLayer
    classificationLayer];

options = trainingOptions('adam',...
    'ExecutionEnvironment','cpu', ...
    'MaxEpochs',10, ...
    'InitialLearnRate',1e-3, ...
    'MiniBatchSize',16, ...
    'shuffle','every-epoch',...
    'Verbose',false);
% analyzeNetwork(layers)
%% train
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;
yyaxis left; % 激活左边的轴
plot(traininfo.TrainingLoss);
title('CNN');
xlabel('训练次数');
ylabel('损失值'); % 给左y轴添加轴标签
yyaxis right; % 激活右边的轴
plot(traininfo.TrainingAccuracy);
ylabel('正确率'); % 给右y轴添加轴标签
%% test
predictedLabels = classify(net,testD);
save result/cnn_result target_testD predictedLabels

disp('测试集分类正确率为:')
acc=sum(target_testD==predictedLabels)/length(target_testD)


图1 CNN结果

         上面是CNN的损失曲线与正确率曲线,下面是测试集输入训练好的网络得到的正确率,为85%。 

        3.2 SSA优化CNN分类模型

clc;clear;close all;format compact;rng(0)
%% 数据处理
load('result/data_process.mat');
method=@mapstd;
% method=@mapminmax;
[xs,mapping]=method(train_X');train_X=xs';
xs=method('apply',test_X',mapping);test_X=xs';
xs=method('apply',valid_X',mapping);valid_X=xs';
N_train=size(train_X,1);
N_feature=size(train_X,2);
for i=1:N_train
    trainD(:,:,:,i)=reshape(train_X(i,:),[N_feature 1 1]);
end
N_valid=size(valid_X,1);
for i=1:N_valid
    XValidation(:,:,:,i)=reshape(valid_X(i,:),[N_feature 1 1]);
end
N_test=size(test_X,1);
for i=1:N_test
    testD(:,:,:,i)=reshape(test_X(i,:),[N_feature 1 1]);
end

targetD=categorical(train_Y);

YValidation=categorical(valid_Y);

target_testD=categorical(test_Y);

%% SSA优化CNN的超参数
%一共有9个参数需要优化,分别是学习率、迭代次数、batchsize、第一层卷积层的核大小、和数量、第2层卷积层的核大小、和数量,以及两个全连接层的神经元数量
optimize=1;%optimize为1就优化 不然就调用之前优化得到的参数直接训练测试
if optimize==1
    [x,trace]=ssa_cnn(trainD,targetD,XValidation,YValidation);
    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')
    %     batchNormalizationLayer
    reluLayer
    maxPooling2dLayer(2,'Stride',2,'Padding','same')% 2x2 kernel stride=2,padding=1
    
    convolution2dLayer(kernel2_size,kernel2_num,'Stride',1,'Padding','same')
    %     batchNormalizationLayer
    reluLayer
    maxPooling2dLayer(2,'Stride',2,'Padding','same')% 2x2 kernel stride=2,padding=1
    
    fullyConnectedLayer(fc1_num)
    reluLayer
    fullyConnectedLayer(fc2_num)
    reluLayer
    fullyConnectedLayer(10)
    softmaxLayer
    classificationLayer];
options = trainingOptions('adam', ...
    'ExecutionEnvironment','cpu', ...
    'MaxEpochs',iter, ...
    'MiniBatchSize',minibatch, ...
    'InitialLearnRate',lr, ...
    '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/ssacnn_net net traininfo
else
    
    load result/ssacnn_net
end

figure;
yyaxis left; % 激活左边的轴
plot(traininfo.TrainingLoss);
title('SSA-CNN');
xlabel('训练次数');
ylabel('损失值'); % 给左y轴添加轴标签
yyaxis right; % 激活右边的轴
plot(traininfo.TrainingAccuracy);
ylabel('正确率'); % 给右y轴添加轴标签
%%
predictedLabels = classify(net,testD);
save result/ssa_cnn_result target_testD predictedLabels

disp('测试集分类正确率为:')
acc=sum(target_testD==predictedLabels)/length(target_testD)

        以最小化验证集分类错误率为适应度函数,目的就是找到一组超参数,使得网络错误率最低。所以适应度曲线是一条下降的曲线

利用上述最优参数,训练CNN,结果如下:

可以看到测试集正确率为94%,具有明显提升。 

4.代码

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

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

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

  • 19
    点赞
  • 154
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 24
    评论
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值