1-4 麻雀优化深度核极限学习机超参数

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

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

目录

0.引言

1.原理

2.具体实现

3.结语


0.引言


在博客【深度核极限学习机】里我们讲述了深度核极限学习机原理,今天我们对其继续进行改进:观察下列DKELM的调用代码可以发现,超参数有隐含层节点数、ELM-AE的L2正则化系数,核函数的惩罚系数与核参数等,这些参数都直接影响分类或回归的准确率,做过SVM的都知道,光惩罚系数与核参数的选择都很困难,一般也不是自己手动选择,都是用各种优化智能优化算法进行手动选择,因此我们继续利用优化算法进行优化选择。

%elm-ae的参数
h=[100 ,50];%各隐含层节点数,里面有几个数就是几个隐含层,即有几个ELM-AE参与无监督预训练,数字代表隐含层节点数
% 比如 h=[100,50],假如输入是200,输出是5类,则DKELM网络结构为200-100-50-5。
% 比如 h=[100,50,20],假如输入是200,输出是5类,则DKELM网络结构为200-100-50-20-5。
TF='sig';%ELM-AE激活函数
lambda=1000;%ELM-AEL2正则化系数
%顶层核极限学习的惩罚系数与核参数
kernel='RBF_kernel';%核函数类型  RBF_kernel lin_kernel poly_kernel wav_kernel
% kernelpara中第一个参数是惩罚系数
if strcmp(kernel,'RBF_kernel')
    kernelpara=[1 1]; %rbf有一个核参数
elseif strcmp(kernel,'lin_kernel')
    kernelpara=[1]; %线性没有核参数
elseif strcmp(kernel,'poly_kernel')
    kernelpara=[1,1,1]; %多项式有2个核参数
elseif strcmp(kernel,'wav_kernel')
     kernelpara=[1,1,1,1]; %小波核有3个核参数
end
%%
delm=dkelmtrain(P_train,T_train,h,lambda,TF,kernelpara,kernel);
T1=dkelmpredict(delm,kernelpara,kernel,P_train,P_train);

1.原理

麻雀优化算法的原理到处都是,就不详细说明了。我们只需要知道一点,任何一个优化算法,都是在他的寻优空间内,基于特定公式进行寻优,具体什么公式我们可以不用管,只要网上能找到可以跑得通的原始代码,我们拿过来改一下就能用,我要调整的就是寻优参数的维度,每个参数的寻优范围,以及适应度函数。

具体实现如下:

2.具体实现

步骤1:确定寻优参数与寻优的范围。如下代码所示,我们要优化的是各隐含层节点数,ELM-AE的正则化系数,顶层kelm的惩罚系数与核参数,隐含层数量与核函数类型是预先设定好的,一般设置成3层与RBF核函数即可。由于每个参数的代码的含义不一样,因此我们需要针对每个参数设定寻优范围lb与ub,详细的看下列代码。

function [bestX,Convergence_curve,result]=ssafordkelm(P_train,P_test,T_train,T_test,layers,TF,kernel)
% 优化DKELM超参数,包括各隐含层节点数,正则化系数,顶层kelm的惩罚系数与核参数
% 定义寻优边界,由于隐含层层数与核函数类型会影响寻优维度,所以下面我们分段进行寻优范围设置
lb=[];ub=[];
% 首先是各层节点数,范围是1-100,整数
lb=[lb ones(1,layers)];
ub=[ub 100*ones(1,layers)];
% 然后是ELM-AE的正则化系数与 kelm的惩罚系数
lb=[lb 1e-3 1e-3];
ub=[ub 1e3  1e3];
% 最后是kelm的核参数
% 核参数设置  详情看kernel_matrix
if strcmp(kernel,'RBF_kernel')
    lb=[lb 1e-3];ub=[ub 1e3 ]; %rbf有一个核参数
elseif strcmp(kernel,'lin_kernel')
    lb=[lb];ub=[ub]; %线性没有核参数
elseif strcmp(kernel,'poly_kernel')
    lb=[lb 1e-3 1];ub=[ub 1e3 10];  %多项式有2个核参数,第二个是多项式幂指数,我们把范围就定到1-10
elseif strcmp(kernel,'wav_kernel')
    lb=[lb 1e-3 1e-3 1e-3];ub=[ub 1e3 1e3 1e3]; %小波核有3个核参数
end
dim=length(lb);

pop=10; % 种群数
M=10; % Maximum numbef of iterations

P_percent = 0.2;    % The population size of producers accounts for "P_percent" percent of the total population size
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pNum = round( pop *  P_percent );    % The population size of the producers

%Initialization
for i=1:pop%随机初始化位置
    for j=1:dim
        if j>layers% % 隐含层节点是整数 其他的都是浮点数
            x(i,j)=(ub(j)-lb(j))*rand+lb(j);
        else
            x(i,j)=round((ub(j)-lb(j))*rand+lb(j));  %
        end
    end
	fit(i)=fitness(x(i,:),P_train,T_train,P_test,T_test,layers,TF,kernel);
end

pFit = fit;
pX = x; 
fMin=fit(1);
bestX = x( i, : );
result=[];
for t = 1 : M
    t
    [ ans, sortIndex ] = sort( pFit );% Sort.从小到大
    [fmax,B]=max( pFit );
    worse= x(B,:);
    r2=rand(1);
    %%%%%%%%%%%%%5%%%%%%这一部位为发现者(探索者)的位置更新%%%%%%%%%%%%%%%%%%%%%%%%%
    if(r2<0.8)%预警值较小,说明没有捕食者出现
        for i = 1 : pNum  %r2小于0.8的发现者的改变(1-20)                                                 % Equation (3)
            r1=rand(1);
            x( sortIndex( i ), : ) = pX( sortIndex( i ), : )*exp(-(i)/(r1*M));%对自变量做一个随机变换
            x( sortIndex( i ), : ) = Bounds( x( sortIndex( i ), : ), lb, ub,layers );%对超过边界的变量进行去除
            
            fit(  sortIndex( i ) )=fitness(x( sortIndex( i ), : ),P_train,T_train,P_test,T_test,layers,TF,kernel);
        end
    else   %预警值较大,说明有捕食者出现威胁到了种群的安全,需要去其它地方觅食
        for i = 1 : pNum   %r2大于0.8的发现者的改变
            x( sortIndex( i ), : ) = pX( sortIndex( i ), : )+randn(1)*ones(1,dim);
            x( sortIndex( i ), : ) = Bounds( x( sortIndex( i ), : ), lb, ub,layers );
            
            fit(  sortIndex( i ) )= fitness(x( sortIndex( i ), : ),P_train,T_train,P_test,T_test,layers,TF,kernel);
           
        end
        
    end
    [ fMMin, bestII ] = min( fit );
    bestXX = x( bestII, : );
    %%%%%%%%%%%%%5%%%%%%这一部位为加入者(追随者)的位置更新%%%%%%%%%%%%%%%%%%%%%%%%%
    for i = ( pNum + 1 ) : pop     %剩下20-100的个体的变换                % Equation (4)
%         i
%         sortIndex( i )
        A=floor(rand(1,dim)*2)*2-1;
        if( i>(pop/2))%这个代表这部分麻雀处于十分饥饿的状态(因为它们的能量很低,也是是适应度值很差),需要到其它地方觅食
            x( sortIndex(i ), : )=randn(1,dim).*exp((worse-pX( sortIndex( i ), : ))/(i)^2);
        else%这一部分追随者是围绕最好的发现者周围进行觅食,其间也有可能发生食物的争夺,使其自己变成生产者
            x( sortIndex( i ), : )=bestXX+(abs(( pX( sortIndex( i ), : )-bestXX)))*(A'*(A*A')^(-1))*ones(1,dim);
        end
        x( sortIndex( i ), : ) = Bounds( x( sortIndex( i ), : ), lb, ub,layers );%判断边界是否超出
        fit(  sortIndex( i ) )=fitness(x( sortIndex( i ), : ),P_train,T_train,P_test,T_test,layers,TF,kernel);
         
    end
    %%%%%%%%%%%%%5%%%%%%这一部位为意识到危险(注意这里只是意识到了危险,不代表出现了真正的捕食者)的麻雀的位置更新%%%%%%%%%%%%%%%%%%%%%%%%%
    c=randperm(numel(sortIndex));%%%%%%%%%这个的作用是在种群中随机产生其位置(也就是这部分的麻雀位置一开始是随机的,意识到危险了要进行位置移动,
    %处于种群外围的麻雀向安全区域靠拢,处在种群中心的麻雀则随机行走以靠近别的麻雀)
    b=sortIndex(c(1:3));
    for j =  1  : length(b)      % Equation (5)
        if( pFit( sortIndex( b(j) ) )>(fMin) ) %处于种群外围的麻雀的位置改变
            x( sortIndex( b(j) ), : )=bestX+(randn(1,dim)).*(abs(( pX( sortIndex( b(j) ), : ) -bestX)));
        else   
            %处于种群中心的麻雀的位置改变
            x( sortIndex( b(j) ), : ) =pX( sortIndex( b(j) ), : )+(2*rand(1)-1)*(abs(pX( sortIndex( b(j) ), : )-worse))/ ( pFit( sortIndex( b(j) ) )-fmax+1e-50);
        end
        x( sortIndex(b(j) ), : ) = Bounds( x( sortIndex(b(j) ), : ), lb, ub,layers );
        fit(  sortIndex( b(j)  ) )=fitness(x( sortIndex( b(j) ), : ),P_train,T_train,P_test,T_test,layers,TF,kernel);
        
    end
    for i = 1 : pop
        if ( fit( i ) < pFit( i ) )
            pFit( i ) = fit( i );
            pX( i, : ) = x( i, : );
        end
        if( pFit( i ) < fMin )
            fMin= pFit( i );
            bestX = pX( i, : );
        end
    end
    Convergence_curve(t)=fMin;
    result(t,:)=bestX;
end

步骤2:确定适应度函数。观察ssafordkelm函数中更新fmin与bestX可知,这个优化算法是找适应度函数最小时对应的x值,是一个最小化问题,因此我们的适应度函数也要写成最小化误差的方式。代码如下,首先将麻雀的x传进来,进行解码,得到各隐含层节点数、L2正则化系数、顶层kelm的惩罚系数与核参数,然后用这些参数训练、预测DELM,得到预测值,分类任务就计算分类错误率,回归任务就计算均方差。

function accuracy=fitness(xx,P_train,T_train,P_test,T_test,layers,activatation,kernel)
rng('default')

hidden=xx(1:layers); %各隐含层节点数
lambda=xx(layers+1); %L2正则化系数
para=xx(layers+2:end); %顶层kelm惩罚系数与核参数

delm=dkelmtrain(P_train,T_train,hidden,lambda,activatation,para,kernel);
T2=dkelmpredict(delm,para,kernel,P_test,P_train);
% 如果是分类任务
[~ ,J2]=max(T2,[],2);
[~ ,J3]=max(T_test,[],2);
accuracy=1-sum(J2==J3)/length(J2); %以最小化分类错误率作为适应度值,优化算法的目的就是找到一组最优超参数,用这组超参数训练 的网络,可以使得使得网络的错误率最低

% 如果是回归任务
%[m,m]=size(T2);
%T2=reshape(T2,[1,m*n]);
%T_test=reshape(T_test,[1,m*n]);

%accuracy=mse(T2,T_test); %以最小化预测值与实际值的均方差作为适应度值,优化算法的目的就是找到一组最优超参数,用这组超参数训练 的网络,可以使得使得网络的预测误差最低

rng(sum(100*clock))

步骤3:在ssa将x传进适应度函数之前,我们还需要做一下参数范围的限制,目的1是怕x中的值不在lb、ub中,目的2是部分参数是整数,部分是小数,我们需要将x的值转成对应的类型。

function x = Bounds( x,  xmin, xmax,layers)
D=length(x);
for j=1:D
    if j <=layers
        x(j)=round(x(j));%隐含层节点数是整数
    end
    
    if x(j)>xmax(j) | x(j)<xmin(j)
        if j>layers
            x(j)=(xmax(j)-xmin(j))*rand+xmin(j);  %
        else
            x(j)=round((xmax(j)-xmin(j))*rand+xmin(j));  %
        end
    end
end

步骤4:主程序调用

%% 优化DKELM超参数,包括各隐含层节点数,正则化系数,顶层kelm的惩罚系数与核参数,
close all;clear;format compact;format short;clc;warning off
%% 
load data
P_train = double(train_x) ;%30*1000
P_test  = double(test_x);%30*100
T_train = double(train_Y);%5*1000
T_test  = double(test_Y);%5*100
%% 预先设定几个常用参数,这些设置的参数不参与寻优
layers=3;%layers个隐含层
TF='sig';%ELM-AE激活函数
%顶层核极限学习机参数
kernel='RBF_kernel';%核函数类型  RBF_kernel lin_kernel poly_kernel wav_kernel

%%
[x,trace,result]=ssafordkelm(P_train,P_test,T_train,T_test,layers,TF,kernel); %优化DKELM超参数,包括各隐含层节点数,正则化系数,顶层kelm的惩罚系数与核参数

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

%% 将优化得到的参数解码出来
hidden=x(1:layers) %各隐含层节点数
lambda=x(layers+1) %L2正则化系数
kernelpara=x(layers+2:end) %顶层kelm惩罚系数与核参数

%% 重新训练DKELM,看结果
rng('default')
delm=dkelmtrain(P_train,T_train,hidden,lambda,TF,kernelpara,kernel);
T1=dkelmpredict(delm,kernelpara,kernel,P_train,P_train);%训练集预测结果
T2=dkelmpredict(delm,kernelpara,kernel,P_test,P_train);%测试集预测结果
%如果是分类就计算分类正确率,如果是回归就计算预测的误差

其中用到的dkelmtrain dkelmpredict等函数,看我上一篇博客。

3.结语

本章我们将DKELM与麻雀优化算法结合起来。用麻雀优化算法来对dklem的参数进行寻优,下一篇我们继续对DKELM进行改进,更多内容请点击专栏获取。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

机器鱼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值