Matlab遗传算法神经网络泰坦尼克号

介绍

数据处理见上篇博文,这里用遗传算法优化神经网络的参数,使其得到更好的训练效果。

实验步骤

流程图

在这里插入图片描述

初始化参数

%样本数据就是前面问题描述中列出的数据
[x,y]=date_inscet();
randIndex=randperm(size(x,1));%打乱顺序
x=x(randIndex,:);y=y(randIndex,:);
x1=x(1:1000,:);y1=y(1:1000,:);x2=x(1001:end,:);y2=y(1001:end,:);
% 初始隐层神经元个数
hiddennum1=15;hiddennum2=5;
% 输入向量的最大值和最小值
threshold=[0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1];
inputnum=size(x,2);       % 输入层神经元个数
outputnum=size(y,2);      % 输出层神经元个数
w1num=inputnum*hiddennum1; % 输入层到隐层1的权值个数
w2num=hiddennum2*hiddennum1;% 隐层1到隐层2的权值个数
w3num=outputnum*hiddennum2;% 隐层2到输出层的权值个数
N=w1num+hiddennum1+w2num+hiddennum2+w3num+outputnum; %待优化的变量的个数

%% 定义遗传算法参数
NIND=40;        %个体数目
MAXGEN=50;      %最大遗传代数
PRECI=10;       %变量的二进制位数
%GGAP=0.95;      %代沟
px=0.7;         %交叉概率
pm=0.01;        %变异概率
trace=zeros(N+1,MAXGEN);                        %寻优结果的初始值

初始化种群

二进制编码,通过自变量的范围与精度来确定染色体编码长度。

bounds=repmat([-1;1],1,N);%所有变量范围都为【-1,1】
precision=ones([1,N])*0.01;%由求解精度确定二进制编码长度
bits=ceil(log2((bounds(2,:)-bounds(1,:)) ./ precision));%由设定精度划分区间,ceil取上整
[Pop]=InitPopGray(NIND,bits);%初始化种群
bestpop=zeros([1,size(Pop,2)]);bestac=0;
%初始化种群
function [initpop]=InitPopGray(popsize,bits)
len=sum(bits);
initpop=zeros(popsize,len);%The whole zero encoding individual
for i=1:popsize
     pop=round(rand(1,len));
     initpop(i,:)=pop(:);
end

计算适应度函数

神经网络的测试集准确率作为适应度函数。

function  [value] = fitness_funNew(Pop,bounds,precision,bits,x1,y1,x2,y2,hiddennum1,hiddennum2)
[m,n]=size(Pop);
value=zeros([m,2]);
for j=1:m
    aa=b2f(Pop(j,:),bounds,precision,bits);%二进制->十进制
    [err,ac]=Bpfun(aa,x1',y1',hiddennum1,hiddennum2,x2',y2');
    value(j,:)=[err,ac];
end

用matlab自带的神经网络函数搭建

function [err,ac]=Bpfun(x,P,T,hiddennum1,hiddennum2,P_test,T_test)
%% 训练&测试BP网络
%% 输入
% x:一个个体的初始权值和阈值
% P:训练样本输入
% T:训练样本输出
% hiddennum:隐含层神经元数
% P_test:测试样本输入
% T_test:测试样本期望输出
%% 输出
% err:预测样本的预测误差的范数

inputnum=size(P,1);       % 输入层神经元个数
outputnum=size(T,1);      % 输出层神经元个数
%% 新建BP网络
net=newff(minmax(P),[hiddennum1,hiddennum2,outputnum],{'tansig','satlins','logsig'},'trainlm');
%% 设置网络参数:训练次数为1000,训练目标为0.01,学习速率为0.1
net.trainParam.epochs=10;
net.trainParam.goal=0.01;
LP.lr=0.1;
net.trainParam.show=NaN;
%net.trainParam.showwindow=false;  %高版MATLAB
%% BP神经网络初始权值和阈值
w1num=inputnum*hiddennum1; % 输入层到隐层1的权值个数
w2num=hiddennum1*hiddennum2;% 隐层1到隐层2的权值个数
w3num=outputnum*hiddennum2;% 隐层2到输出层的权值个数
w1=x(1:w1num);   %初始输入层到隐层的权值
B1=x(w1num+1:w1num+hiddennum1);  %初始隐层阈值
w2=x(w1num+hiddennum1+1:w1num+hiddennum1+w2num); %初始隐层到输出层的阈值
B2=x(w1num+hiddennum1+w2num+1:w1num+hiddennum1+w2num+hiddennum2); %输出层阈值
w3=x(w1num+hiddennum1+w2num+hiddennum2+1:w1num+hiddennum1+w2num+hiddennum2+w3num); %初始隐层到输出层的阈值
B3=x(w1num+hiddennum1+w2num+hiddennum2+w3num+1:w1num+hiddennum1+w2num+hiddennum2+w3num+outputnum); %输出层阈值
net.iw{1,1}=reshape(w1,hiddennum1,inputnum);
net.lw{2,1}=reshape(w2,hiddennum2,hiddennum1);
net.lw{3,2}=reshape(w3,outputnum,hiddennum2);
net.b{1}=reshape(B1,hiddennum1,1);
net.b{2}=reshape(B2,hiddennum2,1);
net.b{3}=reshape(B3,outputnum,1);
%% 训练网络以
net=train(net,P,T);
%% 测试网络
Y=sim(net,P_test);
err=norm(Y-T_test);
for i=1:length(Y)
    if Y(i)<0.5
        Y(i)=0;
    else
        Y(i)=1;
    end
end
ac=1-sum(abs(Y-T_test))/length(Y);

选择

历代最优留下+最好的前20%-1直接留下+轮盘赌选择法

function [selectpop]=NonlinearRankSelect(fit,pop,bestpop)
[m,n]=size(pop);
selectpop=zeros(m,n);
%fit=max(fit)-fit;
selectprob1=fit/sum(fit);%计算各个体相对适应度(0,1)
newfit=cumsum(selectprob1);%计算各选择概率之和,轮盘图

mm=round(m*0.2);
rNums=sort(rand(m-mm,1));
%把最好的前20%直接留下
[a,b]=sort(fit);
for i=1:mm-1
    selectpop(i,:)=pop(b(m-i+1),:);
end
selectpop(mm,:)=bestpop;
%随机选
fitIn=1;newIn=mm+1;
while newIn<=m%选择,不用改
    if rNums(newIn-mm)<=newfit(fitIn)
        selectpop(newIn,:)=pop(fitIn,:);
        newIn=newIn+1;
    else
        fitIn=fitIn+1;
    end
end

交叉

全交叉

%交叉操作
function [NewPop]=CrossOver(OldPop,pCross)
%OldPop为父代种群,pcross为交叉概率
[m,n]=size(OldPop);
NewPop=zeros([m,n]);
r=rand(1,m);
y1=find(r<pCross);
y2=find(r>=pCross);
len=length(y1);
if len>2 && mod(len,2)==1%如果用来进行交叉的染色体的条数为奇数,将其调整为偶数
	y2(length(y2)+1)=y1(len);
    y1(len)=[];
end
if length(y1)>=2
    for i=0:2:length(y1)-2
        [NewPop(y1(i+1),:),NewPop(y1(i+2),:)]=EqualCrossOver(OldPop(y1(i+1),:),OldPop(y1(i+2),:));
    end
end
NewPop(y2,:)=OldPop(y2,:);
end

function [children1,children2]=EqualCrossOver(parent1,parent2)%采用均匀交叉
n=length(parent1);
hidecode=round(rand(1,n));%随机生成掩码
crossposition=find(hidecode==1);
holdposition=find(hidecode==0);
children1(crossposition)=parent1(crossposition);%掩码为1,父1为子1提供基因
children1(holdposition)=parent2(holdposition);%掩码为0,父2为子1提供基因
children2(crossposition)=parent2(crossposition);%掩码为1,父2为子2提供基因
children2(holdposition)=parent1(holdposition);%掩码为0,父1为子2提供基因
end

变异

五点变异

function [NewPop]=Mutation(OldPop,pMutation,VarNum)%变异操作,VarNum变异点个数
[m,n]=size(OldPop);
r=rand(1,m);%m是种群个数
position=find(r<=pMutation);
len=length(position);
if len>=1
    for i=1:len
        k=unidrnd(n,1,VarNum); %设置变异点数,一般设置1for j=1:length(k)
            if OldPop(position(i),k(j))==1
                OldPop(position(i),k(j))=0;
            else
            OldPop(position(i),k(j))=1;
            end
        end
    end
end
NewPop=OldPop;

实验结果

进化曲线:
在这里插入图片描述
最优初始权值和阈值:
X=-0.4 -0.77 1.04 0.11 1 0.68 -0.44 1.15 -0.3 1.02 0.91 1.11 -0.74 -0.28 0.3 -0.33 0.42 0.63 0.61 -0.22 1.27 -0.92 1.32 0.36 0.74 1.07 -0.94 -0.35 -0.57 0.32 0.87 0 -0.33 -0.07 0.93 0.79 1.33 0.83 0.01 1.06 -0.29 -0.14 0.5 1.41 1.15 1.01 -0.62 -0.03 -0.69 0.02 -0.47 0.16 1.41 -0.06 -0.42 0.55 0.22 -0.68 -0.8 1.21 0.66 1.4 -0.51 -0.32 -0.97 1.28 -0.29 -0.62 -0.32 0.44 0.22 0.09 -0.84 0.14 1.48 0.19 0.89 -0.3 0.77 0.94 -0.22 0.1 -0.02 -0.31 -0.91 -0.56 0.17 0.16 -0.2 0.92 -0.69 0.24 0.71 1.01 -0.21 1.54 -0.49 -0.81 0.1 1.44 -0.24 0.7 1.52 -0.52 0.54 -0.43 0.47 -0.03 -0.03 0.17 1.43 0.13 -0.91 1.52 -0.56 -0.66 -0.57 0.06 -0.65 0.98 0.79 0.62 1.38 1.46 0.12 -0.79 -0.46 1.41 0.23 -0.24 -0.15 -0.83 0.89 -0.7 0.84 0.88 -0.32 -0.75 1.41 1.17 1.37 1.08 0.27 -0.14 1.55 -0.87 -0.72 -0.95 -0.44 1.37 1.55 0.36 1.36 -0.5 -0.16 -0.79 -0.53 0.81 0.74 0.18 1.21 -0.75 1.34 0.05 0.63 0.34 0.28 0.86 0.28 -0.49 0.67 -0.62 -0.62 0.48 0.68 0.06 -0.27 -0.31 0.56 -0.3 0.08 -0.06 0.56 -0.26 -0.02 0.94 -0.51 0.25 -0.26 -0.64 1.16 -0.99 0.92 0.5 1.2 -0.5 0.44 -0.38 0.75 0.89 0.76 0.01 -0.89 -0.97 1.44 -0.65
最大准确率ac=0.83819

总代码

clc
clear all
close all
%% 加载神经网络的训练样本 测试样本每列一个样本 输入P 输出T
%样本数据就是前面问题描述中列出的数据
[x,y]=date_inscet();
randIndex=randperm(size(x,1));%打乱顺序
x=x(randIndex,:);y=y(randIndex,:);
x1=x(1:1000,:);y1=y(1:1000,:);x2=x(1001:end,:);y2=y(1001:end,:);
% 初始隐层神经元个数
hiddennum1=15;hiddennum2=5;
% 输入向量的最大值和最小值
threshold=[0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1];
inputnum=size(x,2);       % 输入层神经元个数
outputnum=size(y,2);      % 输出层神经元个数
w1num=inputnum*hiddennum1; % 输入层到隐层1的权值个数
w2num=hiddennum2*hiddennum1;% 隐层1到隐层2的权值个数
w3num=outputnum*hiddennum2;% 隐层2到输出层的权值个数
N=w1num+hiddennum1+w2num+hiddennum2+w3num+outputnum; %待优化的变量的个数

%% 定义遗传算法参数
NIND=40;        %个体数目
MAXGEN=50;      %最大遗传代数
PRECI=10;       %变量的二进制位数
GGAP=0.95;      %代沟
px=0.7;         %交叉概率
pm=0.01;        %变异概率
trace=zeros(N+1,MAXGEN);                        %寻优结果的初始值

%FieldD=[repmat(PRECI,1,N);repmat([-0.5;0.5],1,N);repmat([1;0;1;1],1,N)];                      %区域描述器
%Chrom=crtbp(NIND,PRECI*N);                      %初始种群
bounds=repmat([-1;1],1,N);%所有变量范围都为【-1,1】
precision=ones([1,N])*0.01;%由求解精度确定二进制编码长度
bits=ceil(log2((bounds(2,:)-bounds(1,:)) ./ precision));%由设定精度划分区间,ceil取上整
[Pop]=InitPopGray(NIND,bits);%初始化种群
bestpop=zeros([1,size(Pop,2)]);bestac=0;
%% 优化
gen=0;                                 %代计数器
[value] = fitness_funNew(Pop,bounds,precision,bits,x1,y1,x2,y2,hiddennum1,hiddennum2);%计算适应度
while gen<MAXGEN
   fprintf('%d\n',gen)
   [selectpop]=NonlinearRankSelect(value(:,2),Pop,bestpop);%排名选择
   [CrossOverPop]=CrossOver(selectpop,px);%采用多点交叉和均匀交叉,且逐步增大均匀交叉的概率
   [MutationPop]=Mutation(CrossOverPop,pm,5);%变异
   [value] = fitness_funNew(MutationPop,bounds,precision,bits,x1,y1,x2,y2,hiddennum1,hiddennum2);%计算适应度

   gen=gen+1;                                             %代计数器增加
   %获取每代的最优解及其序号,Y为最优解,I为个体的序号
   [Y,I]=max(value(:,2));
   trace(1:N,gen)=b2f(MutationPop(I,:),bounds,precision,bits);                       %记下每代的最优值
   trace(end,gen)=Y;                               %记下每代的最优值
   if Y>bestac
       bestac=Y;
       bestpop=MutationPop(I,:);
   end
   Pop=MutationPop;
end
%% 画进化图
figure(1);
plot(1:MAXGEN,trace(end,:));
grid on
xlabel('遗传代数')
ylabel('准确率的变化')
title('进化过程')
[a,b]=max(trace(end,:));
bestX=trace(1:end-1,b);
bestErr=trace(end,b);
fprintf(['最优初始权值和阈值:\nX=',num2str(bestX'),'\n最大准确率ac=',num2str(bestErr),'\n'])
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值