基于 MATLAB 的遗传算法优化神经网络

面对较复杂的非线性系统问题时,由于 BP 网络设置的初始权值依赖设计者的经验和样本空间的反复试验,容易产生收敛速度慢、网络不稳定以及陷入局部最优等一系列问题.将 BP 神经网络算法与遗传算法结合,理论上可以对任意非线性系统进行映射,并且得到全局最优的效果,从而形成一种更加有效的非线性反演方法。本场 Chat 中遗传算法对 BP 神经网络进行如下优化,话题将从遗传算法,BP 神经网络两部分分别开始,主要进行 BP 神经网络应用的快速实用入门,学完之后能够学会调用 GA_BP 算法处理数据。

本场 Chat 主要内容:

  • BP 神经网络的原理;
  • 遗传算法引入;
  • GA_BP 示范代码解读。

第一步 认识 BP 神经网络

我们主干是需要了解神经网络,因为遗传算法的的加入是对神经网络的改进,除了遗传算法还可以用小波算法,蚁群算法。遗传算法可以得到最优个体的初始权值和阈值。先从神经网络算法开始入门。

1.1神经网络的分类

人工神经网络分类为以下两种:

1.1.1 依学习策略(Algorithm)分类主要有:

监督式学习网络(Supervised Learning Network)为主。
无监督式学习网络(Unsupervised Learning Network)。
混合式学习网络(Hybrid Learning Network)。
联想式学习网络(Associate Learning Network)。
最适化学习网络(Optimization Application Network)。

1.1.2 依网络架构(Connectionism)分类主要有:

前向式架构(Feed Forward Network)。
回馈式架构(Recurrent Network)。
强化式架构(Reinforcement Network)。

1.2 学习算法

(1) Hebb 学习规则。
(2) Delta 学习规则。
(3) 梯度下降学习规则。
(4) Kohonen 学习规则(就是SOM)。
(5)向后传播学系规则(BP)。
(6) 概率式学习规则(GA)。
(7)竞争式学习规则(SOM,ART,CPN)。

1.3 BP 神经网络

BP 神经网络训练算法:

(1) 初始化网络设置。
(2) 向前传播输入。
(3) 反向误差传播。
(4) 网络权重与神经元偏置调整。
(5) 判断结束。

详细:BP 神经网络是怎样的一种定义?看这句话:一种按 “ 误差逆传播算法训练 ” 的多层前馈网络。

BP 的思想就是:利用输出后的误差来估计输出层前一层的误差,再用这层误差来估计更前一层误差,如此获取所有各层误差估计。这里的误差估计可以理解为某种偏导数,我们就是根据这种偏导数来调整各层的连接权值,再用调整后的连接权值重新计算输出误差。

直到输出的误差达到符合的要求或者迭代次数溢出设定值。

说来说去,“ 误差 ” 这个词说的很多嘛,说明这个算法是不是跟误差有很大的关系?

没错,BP 的传播对象就是 “ 误差 ”,传播目的就是得到所有层的估计误差。

它的学习规则是:使用最速下降法,通过反向传播(就是一层一层往前传)不断调整网络的权值和阈值,最后使全局误差系数最小。

它的学习本质就是:对各连接权值的动态调整。

BP 网络由输入层、隐层和输出层组成,隐层可以有一层或多层:输入层(input),隐藏层(hide layer),输出层(output)BP 网络的优势就是能学习和储存大量的输入输出的关系,而不用事先指出这种数学关系。那么它是如何学习的?

BP 利用处处可导的激活函数来描述该层输入与该层输出的关系,常用 S 型函数 δ 来当作激活函数。

是 m × k × n 的三层 BP 网络模型,网络选用 S 型传递函数,通过反传误差函数 ( (Ti 为期望输出、Oi 为网络的计算输出),不断调节网络权值和 阈值使误差函数 E 达到极小。

其中,n 为输入层神经元个数,m 为输出层神经元个数,a 为 [ 1, 10] 之间的常数。

我们现在开始有监督的 BP 神经网络学习算法:

1、正向传播得到输出层误差 e;=>输入层输入样本=>各隐藏层=>输出层。
2、判断是否反向传播;=>若输出层误差与期望不符=>反向传播。
3、误差反向传播;=>误差在各层显示=>修正各层单元的权值,直到误差减少到可接受程度。

算法阐述起来比较简单,接下来通过数学公式来认识 BP 的真实面目。

假设我们的网络结构是一个含有 N 个神经元的输入层,含有 P 个神经元的隐层,含有 Q 个神经元的输出层。

认识好以上变量后,开始计算:

一、 用(-1,1)内的随机数初始化误差函数,并设定精度 ε,最多迭代次数 M。

二、随机选取第 k 个输入样本及对应的期望输出。

重复以下步骤至误差达到要求:

三、计算隐含层各神经元的输入和输出。

四、计算误差函数 e 对输出层各神经元的偏导数,根据输出层期望输出和实际输出以及输出层输入等参数计算。

五、计算误差函数对隐藏层各神经元的偏导数,根据后一层(这里即输出层)的灵敏度(稍后介绍灵敏度) δo(k),后一层连接权值 w,以及该层的输入值等参数计算

六、利用第四步中的偏导数来修正输出层连接权值

七、利用第五步中的偏导数来修正隐藏层连接权值

八、计算全局误差(m 个样本,q 个类别)

第二步 加入遗传算法

1.1 遗传算法

目的:神经网络里面有很多参数,但是你并不知道哪些参数训练出来的效率最高,识别率最高。这时候就可以以这个识别率为目标函数,用遗传算法来优化神经网络的参数。

遗传神经网络算法和神经网络算法最本质的区别可以说是学习方法不同,或者说模型的优化方法不同。

前者应该是基于遗传算法进行网络权值的学习,而后者大都是采用反向传播(BP)算法进行权值学习,而这两种算法差异很大。可以分别了解:

1)遗传算法:

遗传算法属于进化算法,模拟大自然生物进化的过程:优胜略汰。个体不断进化,只有高质量的个体(目标函数最小(大))才能进入下一代的繁殖。如此往复,最终找到全局最优值。遗传算法能够很好的解决常规优化算法无法解决的高度非线性优化问题,广泛应用在各行各业中。差分进化,蚁群算法,粒子群算法等都属于进化算法,只是模拟的生物群体对象不一样而已。

2)反向传播算法

详细介绍遗传算法:遗传算法 GA —模拟自然界遗传机制和生物进化论而成的一种并行随机搜索最优化方法。(具有 “ 生存 + 检测 ” 的迭代过程的搜索算法)基于自然界 “ 优胜劣汰,适者生存 ” 的生物进化原理引入优化参数形成的编码串联群体中,按照所选择的适应度函数并通过遗传中的选择、交叉和变异对个体进行筛选,使适应度值好的个体被保留,适应度差的个体被淘汰,新的群体既继承了上一代的信息,又优于上一代。反复循环,直至满足条件。

种群中的每个个体是问题的一个解,称为 “ 染色体 ”,染色体是一串符号,如二进制字符串。利用 “ 适值 ”(适应性函数)测量染色体的好坏。 遗传算法基本操作分为:

  1. 选择操作:以一定概率选择旧群体个体到新群体中,个体被选中的概率跟适应度值有关个体适应度越好被选中改了吧越大。
  2. 交叉操作 – 信息交换思想选两个个体交换组合产生新的优秀个体,染色体位置互换。
  3. 变异操作 — 以一定的低概率发生,染色体位置产生变异(通常取值 0.001 - 0.01 之间)。 遗传算法是具有高效启发式搜索、并行计算等特点,应用于函数优化、组合优化及生产调度等方面。

算法基本要素:

1、染色体编码方法 。
2、适应度函数。
3、遗传操作(选择、交叉、变异) 。
4、运行参数 —(参数:群体大小 M、遗传代数 G、交叉概率 Pc 和变异概率 Pm) 。

1、种群初始化

个体编码方法为实数编码,每隔个体均为一个实数串,由输入层和隐含层连接权值、隐含层阈值、隐含层与输出层连接权值以及输出层阈值 4 个部分组成。个体包含了神经网络全部的权值和阈值,在网路结构一直的情况下,就可以构成一个结构、权值、阈值确定的神经网络。

2、适应度函数

根据个体得到 BP 神经网络的初始权值和阈值,用训练数据训练 BP 神经网络后预测系统输出,把预测输出个期望的输出之间的误差绝对值和 E 作为个体适应度值 F。

3、选择操作

遗传算法选择操作有轮盘赌法、锦标赛法等多种方法。选择轮盘赌法时,即基于适应度比例的选择策略,每个个体 i 的选择概率 pi。

4、交叉操作

由于个体采用实数编码,所以交叉操作方法采用实数交叉法。

5、变异操作

选取第 i 个个体的第 j 个基因 aij 进行变异变异操作。

1.2 神经网络加入遗传算法

1.2.1 遗传算法在神经网络中的应用

神经网络的设计要用到遗传算法,遗传算法在神经网络中的应用主要反映在 3 个方面: 网络的学习,网络的结构设计,网络的分析。

1.2.1.1 遗传算法在网络学习中的应用

在神经网络中,遗传算法可用于网络的学习。这时,它在两个方面起作用。学习规则的 优化用遗传算法对神经网络学习规则实现自动优化,从而提高学习速率。网络权系数的优化 用遗传算法的全局优化及隐含并行性的特点提高权系数优化速度。

1.2.1.2 遗传算法在网络设计中的应用

用遗传算法设计一个优秀的神经网络结构,首先是要解决网络结构的编码问题;然后才 能以选择、交叉、变异操作得出最优结构。

编码方法主要有下列 3 种:

直接编码法:这是把神经网络结构直接用二进制串表示,在遗传算法中,“ 染色体 ” 实质 上和神经网络是一种映射关系。通过对 “ 染色体 ” 的优化就实现了对网络的优化。

参数化编码法:参数化编码采用的编码较为抽象,编码包括网络层数、每层神经元数、 各层互连方式等信息。一般对进化后的优化“染色体”进行分析,然后产生网络的结构。

繁衍生长法:这种方法不是在 “ 染色体 ” 中直接编码神经网络的结构,而是把一些简单 的生长语法规则编码入 “ 染色体 ” 中;然后,由遗传算法对这些生长语法规则不断进行改变, 最后生成适合所解的问题的神经网络。这种方法与自然界生物地生长进化相一致。

1.2.1.3 遗传算法在网络分析中的应用

遗传算法可用于分析神经网络。神经网络由于有分布存储等特点,一般难以从其拓扑结构直接理解其功能。遗传算法可对神经网络进行功能分析,性质分析,状态分析。

遗传算法虽然可以在多种领域都有实际应用,并且也展示了它潜力和宽广前景;但 是,遗传算法还有大量的问题需要研究,目前也还有各种不足。首先,在变量多,取值范围 大或无给定范围时,收敛速度下降;其次,可找到最优解附近,但无法精确确定最扰解位置; 最后,遗传算法的参数选择尚未有定量方法。

对遗传算法,还需要进一步研究其数学基础理 论;还需要在理论上证明它与其它优化技术的优劣及原因;还需研究硬件化的遗传算法;以及遗传算法的通用编程和形式等。

小结:遗传算法和神经网络都是计算智能领域重要的算法,遗传算法借鉴生物界适者生存,优胜劣 汰遗传机制的规律,来寻找一个问题的最优解。

神经网络则是模拟生物神经网络的结构和功 能的数学模型或计算模型。大量细胞构成各种神经网络。通过在遗传算法调整神经网络的结 构,使得神经网络获得动态的结构,从而更加智能。用遗传算法调整权重,获得更快的速度, 同时更大程度的避免出现局部最优情况下收敛。将遗传算法应用于神经网络,大大提高神经网络的性能。

第三步 代码赏析

数据归一化是神经网络预测前对数据常做的一种处理方法,将数据转化为【0,1】之间的数字,取消各维数据间的数量级误差,避免因此造成的网络预测误差较大,一般有两种方法:最大最小函数法和平均数方差法;当使用最大最小归一法时可以使用函数:

mapminmax.[inputn,inputs]=mapminmax(input_train)

分别为 归一化后的数据 归一化后得到的结构体 训练输入测试数据归一化和反归一化的程序如下:

Inputn_test=mapminmax(‘apply’,input_test,inputs);BPoutput=mapminmax(‘reverse’,an,outputs);%反归一

另外归一化的方法有:

<1> premnmx

语法:

[pn,minp,maxp,tn,mint,maxt] = premnmx(p,t)。

参数:

pn: p 矩阵按行归一化后的矩阵 minp。
maxp:p 矩阵每一行的最小值,最大值。
tn:t 矩阵按行归一化后的矩阵 mint。
maxt:t 矩阵每一行的最小值,最大值。

作用:将矩阵 p,t 归一化到 [-1,1] ,主要用于归一化处理训练数据集。

<2> tramnmx

语法:

[pn] = tramnmx(p,minp,maxp)。

参数:minp,maxp:premnmx 函数计算的矩阵的最小,最大值。pn:归一化后的矩阵。作用:主要用于归一化处理待分类的输入数据。

<3> postmnmx

语法:

[p,t] =
postmnmx(pn,minp,maxp,tn,mint,maxt)。

参数:minp,maxp:premnmx 函数计算的 p 矩阵每行的最小值,最大值。mint,maxt:premnmx 函数计算的 t 矩阵每行的最小值,最大值。作用:将矩阵 pn,tn 映射回归一化处理前的范围。

postmnmx 函数主要用于将神经网络的输出结果映射回归一化前的数据范围。

BP 神经网络工具箱

使用 Matlab 建立前馈神经网络主要会使用到下面 3 个函数:

  • newff :前馈网络创建函数。
  • train:训练一个神经网络。
  • sim :使用网络进行仿真。

这三个函数的参数如下:net=newff(P,T,S,TF,BTF,BLF,PF,LPF,OPF,DDF)

  • P:输入数据矩阵一个 n × 2 的矩阵,第 i 行元素为输入信号 xi 的最小值和最大值;
  • T:输出数据矩阵一个 k 维行向量,其元素为网络中各层节点数;
  • S:隐含层节点数一个 k 维字符串行向量,每一分量为对应层神经元的激活函数
  • TF:节点传递函数为学习规则采用的训练算法。
  • BTF:训练函数。
  • BLF:网络学习函数。
  • PF:性能分析函数。
  • IPF:输入处理函数。
  • OPF:输出处理函数。
  • DDF:验证数据划分函数。
  • [net,tr] = train(NET,X,T,Pi,Ai)。
  • NET:待训练网络。
  • X:输入数据矩阵。
  • T:输出数据矩阵。
  • Pi:初始化输入层条件。
  • AI:初始化输出层条件。
  • Net:训练好的网络。
  • Tr:训练过程记录。
  • Y = sim (net,x)。
  • Y:网络预测数据。
  • x:输入数据。
  • net:训练好的网络。

MORE:

常用的激活函数

常用的激活函数有:a) 线性函数 (Linear transfer function)f(x) = x,该函数的字符串为 purelin

b) 对数 S 形转移函数( Logarithmic sigmoid transfer function ) 该函数的字符串为 logsig

c) 双曲正切 S 形函数 (Hyperbolic tangent sigmoid transfer function )

也就是上面所提到的双极 S 形函数。该函数的字符串为 tansig

Matlab 的安装目录下的 toolbox\nnet\nnet\nntransfer 子目录中有所有激活函数的定义说明。

常见的训练函数

常见的训练函数有:

  • traingd :梯度下降 BP 训练函数(Gradient descent backpropagation)。
  • traingdx :梯度下降自适应学习率训练函数。
网络配置参数

一些重要的网络配置参数如下:

  • net.trainparam.goal:神经网络训练的目标误差。
  • net.trainparam.show : 显示中间结果的周期。
  • net.trainparam.epochs :最大迭代次数。
  • net.trainParam.lr:学习率。
train 函数

网络训练学习函数。

语法:[ net, tr, Y1, E ] = train( net, X, Y )

参数:

  • X:网络实际输入。
  • Y:网络应有输出。
  • tr:训练跟踪信息。
  • Y1:网络实际输出。
  • E:误差矩阵。
    sim 函数:
  • 语法:Y=sim(net,X)。
参数:

net:网络

  • X:输入给网络的K× N 矩阵,其中 K 为网络输入个数,N 为数据样本数。
  • Y:输出矩阵 Q × N,其中 Q 为网络输出个数。

<1>隐含层节点个数 隐含层节点的个数对于识别率的影响并不大,但是节点个数过多会增加运算量,使得训练较慢。

<2>激活函数的选择 激活函数无论对于识别率或收敛速度都有显著的影响。在逼近高次曲线时,S 形函数精度比线性函数要高得多,但计算量也要大得多。

适应度函数:

 function error=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn)    %该函数用来计算适应度值%x          input     个体%inputnum   input     输入层节点数%outputnum  input     隐含层节点数%net        input     网络%inputn     input     训练输入数据%outputn    input     训练输出数据%error      output    个体适应度值w1=x(1:inputnum*hiddennum);    B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);    w2=x(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);B2=x(inputnum*hiddennum+hiddennum+hiddennum*outputnum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum);net=newff(inputn,outputn,hiddennum);%网络进化参数    net.trainParam.epochs=20;    net.trainParam.lr=0.1;     net.trainParam.goal=0.00001;    net.trainParam.show=100;    net.trainParam.showWindow=0;    %网络权值赋值    net.iw{1,1}=reshape(w1,hiddennum,inputnum);    net.lw{2,1}=reshape(w2,outputnum,hiddennum);    net.b{1}=reshape(B1,hiddennum,1);30.    net.b{2}=B2;    %网络训练    net=train(net,inputn,outputn);    an=sim(net,inputn);    error=sum(abs(an-outputn));

选择操作函数

1.    function ret=select(individuals,sizepop)2.    % 该函数用于进行选择操作3.    % individuals input    种群信息4.    % sizepop     input    种群规模5.    % ret         output   选择后的新种群6.     7.    %求适应度值倒数   8.    fitness1=10./individuals.fitness; %individuals.fitness为个体适应度值9.     10.    %个体选择概率11.    sumfitness=sum(fitness1);12.    sumf=fitness1./sumfitness;13.     14.    %采用轮盘赌法选择新个体15.    index=[]; 16.    for i=1:sizepop   %sizepop为种群数17.        pick=rand;18.        while pick==0    19.            pick=rand;        20.        end21.        for i=1:sizepop    22.            pick=pick-sumf(i);        23.            if pick<0        24.                index=[index i];            25.                break;  26.            end27.        end28.    end29.     30.    %新种群31.    individuals.chrom=individuals.chrom(index,:);   %individuals.chrom为种群中个体32.    individuals.fitness=individuals.fitness(index);33.    ret=individuals;

交叉操作:

1.    function ret=Cross(pcross,lenchrom,chrom,sizepop,bound)2.    %本函数完成交叉操作3.    % pcorss                input  : 交叉概率4.    % lenchrom              input  : 染色体的长度5.    % chrom     input  : 染色体群6.    % sizepop               input  : 种群规模7.    % ret                   output : 交叉后的染色体8.     for i=1:sizepop  %每一轮for循环中,可能会进行一次交叉操作,染色体是随机选择的,交叉位置也是随机选择的,%但该轮for循环中是否进行交叉操作则由交叉概率决定(continue控制)9.         % 随机选择两个染色体进行交叉10.         pick=rand(1,2);11.         while prod(pick)==012.             pick=rand(1,2);13.         end14.         index=ceil(pick.*sizepop);15.         % 交叉概率决定是否进行交叉16.         pick=rand;17.         while pick==018.             pick=rand;19.         end20.         if pick>pcross21.             continue;22.         end23.         flag=0;24.         while flag==025.             % 随机选择交叉位26.             pick=rand;27.             while pick==028.                 pick=rand;29.             end30.             pos=ceil(pick.*sum(lenchrom)); %随机选择进行交叉的位置,即选择第几个变量进行交叉,注意:两个染色体交叉的位置相同31.             pick=rand; %交叉开始32.             v1=chrom(index(1),pos);33.             v2=chrom(index(2),pos);34.             chrom(index(1),pos)=pick*v2+(1-pick)*v1;35.             chrom(index(2),pos)=pick*v1+(1-pick)*v2; %交叉结束36.             flag1=test(lenchrom,bound,chrom(index(1),:));  %检验染色体1的可行性37.             flag2=test(lenchrom,bound,chrom(index(2),:));  %检验染色体2的可行性38.             if   flag1*flag2==039.                 flag=0;40.             else flag=1;41.             end    %如果两个染色体不是都可行,则重新交叉42.         end43.     end44.    ret=chrom;

变异操作:

1.    function ret=Mutation(pmutation,lenchrom,chrom,sizepop,num,maxgen,bound)2.    % 本函数完成变异操作3.    % pcorss                input  : 变异概率4.    % lenchrom              input  : 染色体长度5.    % chrom     input  : 染色体群6.    % sizepop               input  : 种群规模7.    % opts                  input  : 变异方法的选择8.    % pop                   input  : 当前种群的进化代数和最大的进化代数信息9.    % bound                 input  : 每个个体的上届和下届10.    % maxgen                input  :最大迭代次数11.    % num                   input  : 当前迭代次数12.    % ret                   output : 变异后的染色体13.     14.    for i=1:sizepop   %每一轮for循环中,可能会进行一次变异操作,染色体是随机选择的,变异位置也是随机选择的,15.        %但该轮for循环中是否进行变异操作则由变异概率决定(continue控制)16.        % 随机选择一个染色体进行变异17.        pick=rand;18.        while pick==019.            pick=rand;20.        end21.        index=ceil(pick*sizepop);22.        % 变异概率决定该轮循环是否进行变异23.        pick=rand;24.        if pick>pmutation25.            continue;26.        end27.        flag=0;28.        while flag==029.            % 变异位置30.            pick=rand;31.            while pick==0      32.                pick=rand;33.            end34.            pos=ceil(pick*sum(lenchrom));  %随机选择了染色体变异的位置,即选择了第pos个变量进行变异35.        36.            pick=rand; %变异开始     37.            fg=(rand*(1-num/maxgen))^2;38.            if pick>0.539.                chrom(i,pos)=chrom(i,pos)+(bound(pos,2)-chrom(i,pos))*fg;40.            else41.                chrom(i,pos)=chrom(i,pos)-(chrom(i,pos)-bound(pos,1))*fg;42.            end   %变异结束43.            flag=test(lenchrom,bound,chrom(i,:));     %检验染色体的可行性44.        end45.    end46.    ret=chrom;

主函数:

步骤:
1、随机初始化种群。
2、计算种群适应度值从中找出最优个体。
3、选择操作。
4、交叉操作。
5、变异操作。
6、判断进化是否结束,否返回步骤 2。

input 为输入数据,output 为输出

1.    % 清空环境变量2.    clc3.    clear4.    % 5.    %% 网络结构建立6.    %读取数据7.    load data input output8.     9.    %节点个数10.    inputnum=2;11.    hiddennum=5;12.    outputnum=1;13.     14.    %训练数据和预测数据15.    input_train=input(1:1900,:)';16.    input_test=input(1901:2000,:)';17.    output_train=output(1:1900)';18.    output_test=output(1901:2000)';19.     20.    %选连样本输入输出数据归一化21.    [inputn,inputps]=mapminmax(input_train);22.    [outputn,outputps]=mapminmax(output_train);23.     24.    %构建网络25.    net=newff(inputn,outputn,hiddennum);26.     27.    %% 遗传算法参数初始化28.    maxgen=10;                         %进化代数,即迭代次数29.    sizepop=10;                        %种群规模30.    pcross=[0.3];                       %交叉概率选择,0和1之间31.    pmutation=[0.1];                    %变异概率选择,0和1之间32.     33.    %节点总数34.    numsum=inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum;35.     36.    lenchrom=ones(1,numsum);        37.    bound=[-3*ones(numsum,1) 3*ones(numsum,1)];    %数据范围38.     39.    %------------------------------------------------------种群初始化--------------------------------------------------------40.    individuals=struct('fitness',zeros(1,sizepop), 'chrom',[]);  %将种群信息定义为一个结构体41.    avgfitness=[];                      %每一代种群的平均适应度42.    bestfitness=[];                     %每一代种群的最佳适应度43.    bestchrom=[];                       %适应度最好的染色体44.    %初始化种群45.    for i=1:sizepop46.        %随机产生一个种群47.        individuals.chrom(i,:)=Code(lenchrom,bound);    %编码(binary和grey的编码结果为一个实数,float的编码结果为一个实数向量)48.        x=individuals.chrom(i,:);49.        %计算适应度50.        individuals.fitness(i)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);   %染色体的适应度51.    end52.     53.    %找最好的染色体54.    [bestfitness bestindex]=min(individuals.fitness);55.    bestchrom=individuals.chrom(bestindex,:);  %最好的染色体56.    avgfitness=sum(individuals.fitness)/sizepop; %染色体的平均适应度57.    % 记录每一代进化中最好的适应度和平均适应度58.    trace=[avgfitness bestfitness]; 59.     60.    %% 迭代求解最佳初始阀值和权值61.    % 进化开始62.    for i=1:maxgen63.        i64.        % 选择65.        individuals=Select(individuals,sizepop); 66.        avgfitness=sum(individuals.fitness)/sizepop;67.        %交叉68.        individuals.chrom=Cross(pcross,lenchrom,individuals.chrom,sizepop,bound);69.        % 变异70.        individuals.chrom=Mutation(pmutation,lenchrom,individuals.chrom,sizepop,i,maxgen,bound);71.        72.        % 计算适应度 73.        for j=1:sizepop74.            x=individuals.chrom(j,:); %解码75.            individuals.fitness(j)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);   76.        end77.        78.      %找到最小和最大适应度的染色体及它们在种群中的位置79.        [newbestfitness,newbestindex]=min(individuals.fitness);80.        [worestfitness,worestindex]=max(individuals.fitness);81.        % 代替上一次进化中最好的染色体82.        if bestfitness>newbestfitness83.            bestfitness=newbestfitness;84.            bestchrom=individuals.chrom(newbestindex,:);85.        end86.        individuals.chrom(worestindex,:)=bestchrom;87.        individuals.fitness(worestindex)=bestfitness;88.        89.        avgfitness=sum(individuals.fitness)/sizepop;90.        91.        trace=[trace;avgfitness bestfitness]; %记录每一代进化中最好的适应度和平均适应度92.     93.    end94.    %% 遗传算法结果分析 95.     figure(1)96.    [r c]=size(trace);97.    plot([1:r]',trace(:,2),'b--');98.    title(['适应度曲线  ' '终止代数=' num2str(maxgen)]);99.    xlabel('进化代数');ylabel('适应度');100.    legend('平均适应度','最佳适应度');101.    disp('适应度                   变量');102.    x=bestchrom;103.    104.    %% 把最优初始阀值权值赋予网络预测105.    % %用遗传算法优化的BP网络进行值预测106.    w1=x(1:inputnum*hiddennum);107.    B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);108.    w2=x(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);109.    B2=x(inputnum*hiddennum+hiddennum+hiddennum*outputnum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum);110.    111.    net.iw{1,1}=reshape(w1,hiddennum,inputnum);112.    net.lw{2,1}=reshape(w2,outputnum,hiddennum);113.    net.b{1}=reshape(B1,hiddennum,1);114.    net.b{2}=B2;115.    116.    %% BP网络训练117.    %网络进化参数118.    net.trainParam.epochs=100;119.    net.trainParam.lr=0.1;120.    %net.trainParam.goal=0.00001;121.    122.    %网络训练123.    [net,per2]=train(net,inputn,outputn);124.    125.    %% BP网络预测126.    %数据归一化127.    inputn_test=mapminmax('apply',input_test,inputps);128.    an=sim(net,inputn_test);129.    test_simu=mapminmax('reverse',an,outputps);130.    error=test_simu-output_test;

使用时将程序视为输入输出的系统,需要根据需要修改使用 save data 生成的 .mat 数据库文件,然后再调用数据,确定传递函数等就可以观察到结果。

神经网络的初始化数据:

load data input output%节点个数inputnum=2;hiddennum=5;outputnum=1;%训练数据和预测数据input_train=input(1:1900,:)’;input_test=input(1901:2000,:)’;output_train=output(1:1900)’;output_test=output(1901:2000)’;遗传算法的初始化数据:maxgen=10; %进化代数,即迭代次数sizepop=10; %种群规模pcross=[0.3]; %交叉概率选择,0和1之间pmutation=[0.1]; %变异概率选择,0和1之间

本文首发于GitChat,未经授权不得转载,转载需与GitChat联系。

阅读全文: http://gitbook.cn/gitchat/activity/5b600a5b5ecd332382c04076

您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

FtooAtPSkEJwnW-9xkCLqSTRpBKX

你可能感兴趣的:(基于 MATLAB 的遗传算法优化神经网络)