本博客來源于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 填充為samereluLayer%relu激活convolution2dLayer(3,8,'Stride',1,'Padding','same')%核3*1 數量8 步長1 填充為samereluLayer%relu激活fullyConnectedLayer(20) % 全連接層1 20個神經元reluLayerfullyConnectedLayer(20) % 全連接層2 20個神經元reluLayerfullyConnectedLayer(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
elseload 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:Dif j==D%除了學習率 其他的都是整數R( i, j ) = (ub(j)-lb(j))*rand+lb(j);elseR( i, j ) = round((ub(j)-lb(j))*rand+lb(j));endend
endfor k= 1:sizepopFitness(k)=fitness(R(k,:),X1,y1,Xt,yt);%個體適應度
end
[Fbest,elite]= min(Fitness);%Fbest為最優適應度值
Rbest= R(elite,:);%最優個體位置
H=zeros(1,sizepop);%控制因子%主循環
for iter= 1:maxgenRpre= R;%記錄上一代的位置V=2*(1-iter/maxgen);B= 2*V*rand-V;a=-(1 + iter/maxgen);alpha=rand*(a-1)+ 1;for i= 1:sizepopif H(i)==0dis = abs(Rbest-R(i,:));R(i,:)= R(i,:)+ dis* exp(alpha)*cos(2*pi* alpha);elseRAND= ceil(rand*sizepop);%隨機選擇一個個體R(i,:)= Rbest -(rand*0.5*(Rbest + R(RAND,:))- R(RAND,:));endRatt= 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)==1H(i)=0;elseH(i)=1;endelse %不改變寄主A= B*(R(i,:)-rand*0.3*Rbest);R(i,:)=R(i,:)+A;endR(i, : ) = Bounds( R(i, : ), lb, ub );%對超過邊界的變量進行去除end%更新適應度值、位置[fbest,elite] = min(Fitness);%更新最優個體if fbest< FbestFbest= fbest;Rbest= R(elite,:);endprocess(iter,:)=Rbest;Convergence_curve(iter)= Fbest;iter,Fbest,Rbest
endendfunction s = Bounds( s, Lb, Ub)
temp = s;
dim=length(Lb);
for i=1:length(s)if i==dim%除了學習率 其他的都是整數temp(:,i) =temp(:,i);elsetemp(:,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);elsetemp(:,i) =round(rand*(Ub(i)-Lb(i))+Lb(i));endend
end
s = temp;
end
function s = Bounds( s, Lb, Ub)
temp = s;
for i=1:length(s)if i==1%除了學習率 其他的都是整數temp(:,i) =temp(:,i);elsetemp(:,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);elsetemp(:,i) =round(rand*(Ub(i)-Lb(i))+Lb(i));endend
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')reluLayerconvolution2dLayer(kernel2_size,kernel2_num,'Stride',1,'Padding','same')reluLayerfullyConnectedLayer(fc1_num) reluLayerfullyConnectedLayer(fc2_num) reluLayerfullyConnectedLayer(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
elseload 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')reluLayerconvolution2dLayer(kernel2_size,kernel2_num,'Stride',1,'Padding','same')reluLayerfullyConnectedLayer(fc1_num)reluLayerfullyConnectedLayer(fc2_num)reluLayerfullyConnectedLayer(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
elseload result/roacnn_net
endfigure;
plot(traininfo.TrainingLoss,'b')
hold on;grid on
ylabel('損失')
xlabel('訓練次數')
title('roa-CNN')%% 結果評價
YPred = predict(net,testD);YPred=double(YPred);
3.結語
優化網絡超參數的格式都是這樣的!只要會改一種,那么隨便拿一份能跑通的優化算法,在不管原理的情況下,都能用來優化網絡的超參數。更多內容【點擊專欄】目錄。