本博客来源于CSDN机器鱼,未同意任何人转载。
更多内容,欢迎点击本专栏目录,查看更多内容。
目录
0.ROA原理
1.LSTM程序
2.ROA优化LSTM
3.主程序
4.结语
0.ROA原理
具体原理看原文,但是今天咱不用知道具体原理,只需要找到源码,然后改成优化LSTM的即可。下面是我从网上找到的源码。ROA是主要的代码,Cost是适应度函数,这个代码的是找Cost的最小值。
function [Fbest, Rbest,Convergence_curve]= ROA()
sizepop=30; % Number of search agents
maxgen=500; % Maximum number of iterations
lb=-100;
ub=100;
D=30;
%maxgen为最大迭代次数,
%sizepop为种群规模
%记D为维度,lb、 ub分别为搜索上、下限
R=ones(sizepop,D);%预设种群
for i= 1:D
R(:,i)=lb + (ub-lb)*rand(sizepop,1);
end
for k= 1:sizepop
Fitness(k)=Cost(R(k,:));%个体适应度
end
[Fbest,elite]= min(Fitness);%Fbest为最优适应度值
Rbest= R(elite,:);%最优个体位置
H=zeros(1,sizepop);%控制因子
ub=ones(1,D)*ub;
lb=ones(1,D)*lb;
%主循环
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;%作出小幅度移动
%边界吸收
for k=1:D
Flag4ub= R(i,k)>ub(k);
Flag4lb= R(i,k)<lb(k);
R(i,k)=(R(i,k).*(~(Flag4ub + Flag4lb))) + ub(k).*Flag4ub + lb(k).*Flag4lb;
Flag4ub= Ratt(1,k)> ub(k);
Flag4lb= Ratt(1,k)<lb(k);
Ratt(1,k)=(Ratt(1,k).*(~(Flag4ub + Flag4lb)))+ ub(k).*Flag4ub + lb(k).*Flag4lb;
end
Fitness(i)=Cost(R(i,:));
Fitness_Ratt= Cost(Ratt);
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
%边界吸收
for k=1:D
Flag4ub= R(i,k)>ub(k);
Flag4lb= R(i,k)<lb(k);
R(i,k)=(R(i,k).*(~(Flag4ub+ Flag4lb))) + ub(k).*Flag4ub + lb(k).*Flag4lb;
end
end
%更新适应度值、位置
[fbest,elite] = min(Fitness);
%更新最优个体
if fbest< Fbest
Fbest= fbest;
Rbest= R(elite,:);
end
Convergence_curve(iter)= Fbest;
end
end
function o = Cost(x)
o=sum(x.^2);
end
调用这个代码的主程序如下:
clear ;close all;clc;format compact
%鮣鱼优化算法(Remora Optimization Algorithm)
[BestF,BestP,Convergence_curve1]=ROA();
figure
semilogy(Convergence_curve1)
1.LSTM程序
首先建立一个LSTM网络,这次我们是做回归任务,数据是3输入1输出,构建一个含2个lstmlayer的LSTM网络,代码如下:
%% LSTM时间序列预测
clc;clear;close all
%%
load data
XTrain;%3*97
XTest;%3*68
YTrain;%1*97
YTest;%1*68
%% 参数设置
train=0;%为1就重新训练,否则加载训练好的模型进行预测
if train==1
rng(0)
numFeatures = size(XTrain,1);%输入节点数
numResponses = size(YTrain,1);%输出节点数
miniBatchSize = 16; %batchsize
numHiddenUnits1 = 20;
numHiddenUnits2 = 20;
maxEpochs=100;
learning_rate=0.005;
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits1)
lstmLayer(numHiddenUnits2)
fullyConnectedLayer(numResponses)
regressionLayer];
options = trainingOptions('adam', ...
'ExecutionEnvironment', 'cpu',...
'MaxEpochs',maxEpochs, ...
'MiniBatchSize',miniBatchSize, ...
'InitialLearnRate',learning_rate, ...
'GradientThreshold',1, ...
'Shuffle','every-epoch', ...
'Verbose',true,...
'Plots','training-progress');
net = trainNetwork(XTrain,YTrain,layers,options);
save model/lstm net
else
load model/lstm
end
YPred = predict(net,XTest,'ExecutionEnvironment', 'cpu');YPred=double(YPred);
从构建网络那里,我们发现,构建一个超级简单的LSTM,依旧有miniBatchSize ,numHiddenUnits1 ,numHiddenUnits2 ,maxEpochs,learning_rate共5个超参数需要设置,而网络越复杂,那需要优化的超参数也就更多,手动选择就算了,一般是选不出来,为此这篇博客采用ROA进行优化。
2.ROA优化LSTM
任意一个优化网路超参数的步骤都是通用的,步骤如下:
步骤1:知道要优化的参数的优化范围。显然就是上面提到的5个参数。代码如下,首先改写lb与ub,然后初始化的时候注意除了学习率,其他的都是整数。并将原来里面的边界判断,改成了Bounds函数,方便在计算适应度函数前转化成整数与小数。
function [Rbest,Convergence_curve,process]= ROAforlstm(X1,y1,Xt,yt)
D=5;
sizepop=5;%种群数量
maxgen=10;%寻优代数
%范围
lb=[1 1 1 1 0.001];%分别对batchsize、两个lstm隐含层节点 训练次数与学习率寻优
ub=[64 100 100 50 0.01];%这个分别代表5个参数的上下界,比如第一个参数的范围就是1-64
%
%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
步骤2:知道优化的目标。优化的目标是提高的网络的准确率,而ROA代码我们这个代码是最小值优化的,所以我们的目标可以是最小化LSTM的预测误差。预测误差具体是,测试集(或验证集)的预测值与真实值之间的均方差。
步骤3:构建适应度函数。通过步骤2我们已经知道目标,即采用ROA去找到5个值,用这5个值构建的网络,误差最小化。观察下面的代码,首先我们将ROA的值传进来,然后转成需要的5个值,然后构建网络,训练集训练、测试集预测,计算预测值与真实值的mse,将mse作为结果传出去作为适应度值。
function y=fitness(x,p,t,pt,tt)
rng(0)
numFeatures = size(p,1);%输入节点数
numResponses = size(t,1);%输出节点数
miniBatchSize = x(1); %batchsize
numHiddenUnits1 = x(2);
numHiddenUnits2 = x(3);
maxEpochs=x(4);
learning_rate=x(5);
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits1)
lstmLayer(numHiddenUnits2)
fullyConnectedLayer(numResponses)
regressionLayer];
options = trainingOptions('adam', ...
'ExecutionEnvironment', 'cpu',...
'MaxEpochs',maxEpochs, ...
'MiniBatchSize',miniBatchSize, ...
'InitialLearnRate',learning_rate, ...
'GradientThreshold',1, ...
'Shuffle','every-epoch', ...
'Verbose',false);
net = trainNetwork(p,t,layers,options);
YPred = predict(net,pt,'ExecutionEnvironment', 'cpu');YPred=double(YPred);
[m,n]=size(YPred);
YPred=reshape(YPred,[1,m*n]);
tt=reshape(tt,[1,m*n]);
y =mse(YPred-tt);
% 以mse为适应度函数,优化算法目的就是找到一组超参数 使网络的mse最低
rng((100*sum(clock)))
3.主程序
%% ROA优化LSTM时间序列预测
clc;clear;close all;format compact
%%
load data
%% 采用ROA优化
optimization=1;%是否重新优化
if optimization==1
[x ,fit_gen,process]=ROAforlstm(XTrain,YTrain,XTest,YTest);%分别对batchsize 隐含层节点 训练次数与学习率寻优
save result/ROA_para_result x fit_gen process
else
load result/ROA_para_result
end
%% 利用优化得到的参数重新训练,得到预测值
train=1;%是否重新训练
if train==1
rng(0)
numFeatures = size(XTrain,1);%输入节点数
numResponses = size(YTrain,1);%输出节点数
miniBatchSize = x(1); %batchsize
numHiddenUnits1 = x(2);
numHiddenUnits2 = x(3);
maxEpochs=x(4);
learning_rate=x(5);
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits1)
lstmLayer(numHiddenUnits2)
fullyConnectedLayer(numResponses)
regressionLayer];
options = trainingOptions('adam', ...
'ExecutionEnvironment', 'cpu',...
'MaxEpochs',maxEpochs, ...
'MiniBatchSize',miniBatchSize, ...
'InitialLearnRate',learning_rate, ...
'GradientThreshold',1, ...
'Shuffle','every-epoch', ...
'Verbose',true,...
'Plots','training-progress');
net = trainNetwork(XTrain,YTrain,layers,options);
save model/ROAlstm net
else
load model/ROAlstm
end
% 预测
YPred = predict(net,XTest,'ExecutionEnvironment', 'cpu');
YPred=double(YPred);
4.结语
优化网络超参数的格式都是这样的!只要会改一种,那么随便拿一份能跑通的优化算法,在不管原理的情况下,都能用来优化网络的超参数。晚一点我们再来写一个简单的CNN,并用这个算法来优化。更多内容【点击专栏】目录。