• 使用遗传算法优化BP神经网络实现非线性函数拟合


            大家好,我是带我去滑雪

            非线性函数拟合是一种用于找到与给定数据点集合最好匹配的非线性函数的过程。非线性函数拟合通常用于以下情况:

    • 数据趋势不是线性的:当数据点之间的关系不能用线性方程来表示时,需要使用非线性函数来更好地拟合数据。
    • 复杂的数据模式:当数据包含复杂的非线性模式或曲线时,非线性函数拟合可以提供更准确的拟合结果。
    • 物理、生物、经济或其他领域的实验数据:许多自然现象和实验数据无法用简单的线性模型来解释,因此需要使用非线性模型。

            下面使用遗传算法优化的BP神经网络实现非线性函数拟合: 

    目录

    一、预备知识 

    (1)什么是遗传算法

    (2)拟合函数

    二、模型建立

    (1)遗传算法优化BP神经网络算法流程

    (2)适应度函数

    (3)选择操作

     (4)交叉

    (5) 变异

    (6) 遗传算法主函数

    (7) 将遗传算法的到的最优个体赋值进BP神经网络

     (8)结果分析


    一、预备知识 

    (1)什么是遗传算法

            遗传算法(Genetic Algorithm, GA)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。其主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;具有内在的隐并行性和更好的全局寻优能力;采用概率化的寻优方法,不需要确定的规则就能自动获取和指导优化的搜索空间,自适应地调整搜索方向。遗传算法以一种群体中的所有个体为对象,并利用随机化技术指导对一个被编码的参数空间进行高效搜索。其中,选择、交叉和变异构成了遗传算法的遗传操作;参数编码、初始群体的设定、适应度函数的设计、遗传操作设计、控制参数设定五个要素组成了遗传算法的核心内容。

    • 选择操作:从旧群体中以一定的概率选择个体到新群体中,个体被选中的概率跟适应度值有关,个体适应度值越好,被选择的概率越大。 
    • 交叉操作:从个体中选择两个个体,通过染色体的交换组合,来产生新的优秀个体。交叉过程为从群体中任选两个染色体,随机选择一点或多点染色体位置进行交换。
    • 变异操作:从群体中选择一个个体,选择染色体中的一点进行变异以产生更优秀的个体。

           运行参数主要包括群体大小、遗传代数、交叉概率、变异概率 。

    (2)拟合函数

          本次需要拟合的非线性函数为:

    y=x_{1}^{2}+x_{2}^{2}

    1. clc,clear,close all
    2. x=-6:0.1:6;
    3. [X,Y]=meshgrid(x);
    4. Z=X.^2+Y.^2;
    5. mesh(X,Y,Z)

       绘制函数图像为:

    二、模型建立

    (1)遗传算法优化BP神经网络算法流程

             流程分为:BP神经网络结构确定、遗传算法优化、BP神经网络预测。由于拟合函数中有两个输入参数,1个输出参数,所以设置BP神经网络结构为2-5-1,即输入层节点为2,隐含层节点为5,输出层节点为1,总共有2x5+5x1=15个权重,5+1=6个阈值,使用遗传算法个体的编码长度为15+6=21个。从非线性函数中随机得到2000组输入输出数据,随机选择其中1900组作为训练数据,100组作为测试数据。将训练数据预测误差绝对值和作为个体适应度值,个体适应度值越小,该个体越优。

           遗传算法参数设置为:种群规模为10,进化次数为50次,交叉概率为0.4,变异概率为0.2。

    (2)适应度函数

            将训练数据预测误差作为个体适应度值。 

    1. function error = fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn)
    2. w1=x(1:inputnum*hiddennum);
    3. B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);
    4. w2=x(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);
    5. B2=x(inputnum*hiddennum+hiddennum+hiddennum*outputnum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum);
    6. net.trainParam.epochs=20;
    7. net.trainParam.lr=0.1;
    8. net.trainParam.goal=0.00001;
    9. net.trainParam.show=100;
    10. net.trainParam.showWindow=0;
    11. net.iw{1,1}=reshape(w1,hiddennum,inputnum);
    12. net.lw{2,1}=reshape(w2,outputnum,hiddennum);
    13. net.b{1}=reshape(B1,hiddennum,1);
    14. net.b{2}=B2;
    15. net=train(net,inputn,outputn);
    16. an=sim(net,inputn);
    17. error=sum(abs(an-outputn));

    (3)选择操作

           选择操作采用轮盘赌法从种群中选择适应度好的个体组成新种群。

    1. function ret=select(individuals,sizepop)
    2. fitness1=10./individuals.fitness;
    3. sumfitness=sum(fitness1);
    4. sumf=fitness1./sumfitness;
    5. index=[];
    6. for i=1:sizepop %转sizepop次轮盘
    7. pick=rand;
    8. while pick==0
    9. pick=rand;
    10. end
    11. for j=1:sizepop
    12. pick=pick-sumf(i);
    13. if pick<0
    14. index=[index j];
    15. break;
    16. end
    17. end
    18. end
    19. individuals.chrom=individuals.chrom(index,:);
    20. individuals.fitness=individuals.fitness(index);
    21. ret=individuals;

     (4)交叉

    1. function ret=Cross(pcross,lenchrom,chrom,sizepop,bound)
    2. for i=1:sizepop
    3. pick=rand(1,2);
    4. while prod(pick)==0
    5. pick=rand(1,2);
    6. end
    7. index=ceil(pick.*sizepop);
    8. pick=rand;
    9. while pick==0
    10. pick=rand;
    11. end
    12. if pick>pcross
    13. continue;
    14. end
    15. flag=0;
    16. while flag==0
    17. pick=rand;
    18. while pick==0
    19. pick=rand;
    20. end
    21. pos=ceil(pick.*sum(lenchrom));
    22. pick=rand;
    23. v1=chrom(index(1),pos);
    24. v2=chrom(index(2),pos);
    25. chrom(index(1),pos)=pick*v2+(1-pick)*v1;
    26. chrom(index(2),pos)=pick*v1+(1-pick)*v2;
    27. flag1=test(lenchrom,bound,chrom(index(1),:));
    28. flag2=test(lenchrom,bound,chrom(index(2),:));
    29. if flag1*flag2==0
    30. flag=0;
    31. else flag=1;
    32. end
    33. end
    34. end
    35. ret=chrom;

    (5) 变异

    1. function ret=Mutation(pmutation,lenchrom,chrom,sizepop,num,maxgen,bound)
    2. for i=1:sizepop
    3. pick=rand;
    4. while pick==0
    5. pick=rand;
    6. end
    7. index=ceil(pick*sizepop);
    8. pick=rand;
    9. if pick>pmutation
    10. continue;
    11. end
    12. flag=0;
    13. while flag==0
    14. pick=rand;
    15. while pick==0
    16. pick=rand;
    17. end
    18. pos=ceil(pick*sum(lenchrom));
    19. pick=rand;
    20. fg=(rand*(1-num/maxgen))^2;
    21. if pick>0.5
    22. chrom(i,pos)=chrom(i,pos)+(bound(pos,2)-chrom(i,pos))*fg;
    23. else
    24. chrom(i,pos)=chrom(i,pos)-(chrom(i,pos)-bound(pos,1))*fg;
    25. end
    26. flag=test(lenchrom,bound,chrom(i,:));
    27. end
    28. end
    29. ret=chrom;

    (6) 遗传算法主函数

    1. clc
    2. clear
    3. load data input output
    4. inputnum=2;
    5. hiddennum=5;
    6. outputnum=1;
    7. input_train=input(1:1900,:)';
    8. input_test=input(1901:2000,:)';
    9. output_train=output(1:1900)';
    10. output_test=output(1901:2000)';
    11. [inputn,inputps]=mapminmax(input_train);
    12. [outputn,outputps]=mapminmax(output_train);
    13. net=newff(inputn,outputn,hiddennum);
    14. maxgen=20;
    15. pcross=[0.2];
    16. pmutation=[0.1];
    17. numsum=inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum;
    18. lenchrom=ones(1,numsum);
    19. bound=[-3*ones(numsum,1) 3*ones(numsum,1)];
    20. individuals=struct('fitness',zeros(1,sizepop), 'chrom',[]);
    21. avgfitness=[];
    22. bestfitness=[];
    23. bestchrom=[];
    24. for i=1:sizepop
    25. individuals.chrom(i,:)=Code(lenchrom,bound);
    26. x=individuals.chrom(i,:);
    27. individuals.fitness(i)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);
    28. end
    29. FitRecord=[];
    30. [bestfitness bestindex]=min(individuals.fitness);
    31. bestchrom=individuals.chrom(bestindex,:);
    32. avgfitness=sum(individuals.fitness)/sizepop;
    33. trace=[avgfitness bestfitness];
    34. for i=1:maxgen
    35. i
    36. individuals=Select(individuals,sizepop);
    37. avgfitness=sum(individuals.fitness)/sizepop;
    38. individuals.chrom=Cross(pcross,lenchrom,individuals.chrom,sizepop,bound);
    39. individuals.chrom=Mutation(pmutation,lenchrom,individuals.chrom,sizepop,i,maxgen,bound);
    40. for j=1:sizepop
    41. x=individuals.chrom(j,:);
    42. individuals.fitness(j)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);
    43. end
    44. [newbestfitness,newbestindex]=min(individuals.fitness);
    45. [worestfitness,worestindex]=max(individuals.fitness);
    46. if bestfitness>newbestfitness
    47. bestfitness=newbestfitness;
    48. bestchrom=individuals.chrom(newbestindex,:);
    49. end
    50. individuals.chrom(worestindex,:)=bestchrom;
    51. individuals.fitness(worestindex)=bestfitness;
    52. avgfitness=sum(individuals.fitness)/sizepop;
    53. trace=[trace;avgfitness bestfitness];
    54. FitRecord=[FitRecord;individuals.fitness];
    55. end

    (7) 将遗传算法的到的最优个体赋值进BP神经网络

    1. w1=x(1:inputnum*hiddennum);
    2. B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);
    3. w2=x(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);
    4. B2=x(inputnum*hiddennum+hiddennum+hiddennum*outputnum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum);
    5. net.iw{1,1}=reshape(w1,hiddennum,inputnum);
    6. net.lw{2,1}=reshape(w2,outputnum,hiddennum);
    7. net.b{1}=reshape(B1,hiddennum,1);
    8. net.b{2}=B2;
    9. net.trainParam.epochs=100;
    10. net.trainParam.lr=0.1;
    11. [net,per2]=train(net,inputn,outputn);
    12. inputn_test=mapminmax('apply',input_test,inputps);
    13. an=sim(net,inputn_test);
    14. test_simu=mapminmax('reverse',an,outputps);
    15. error=test_simu-output_test;

     (8)结果分析

          绘制遗传算法优化过程中最优个体适应度值变化图:

    1. figure(1)
    2. [r c]=size(trace);
    3. plot([1:r]',trace(:,2),'b--');
    4. title(['适应度曲线 ' '终止代数=' num2str(maxgen)]);
    5. xlabel('进化代数');ylabel('适应度');
    6. legend('平均适应度','最佳适应度');

    输出结果:

          模型的均方误差为2.2628x10的负7次方,什么模型的效果还可以。


    更多优质内容持续发布中,请移步主页查看。

    若有问题可邮箱联系:1736732074@qq.com 

    博主的WeChat:TCB1736732074

       点赞+关注,下次不迷路!

  • 相关阅读:
    halcon脚本-边缘及骨架的识别【附源码】
    定位消耗系统资源多的查询
    vue学习之属性绑定
    Vue Router
    Vue+element-ui实现表格数据渲染+分页
    C# out参数out多个参数
    魔兽世界安装插件后进游戏闪退的一个原因。
    Apache Hive源码阅读环境搭建
    使用 Kotlin DSL 编写网络爬虫
    C++多态与虚拟:运算符重载(Operator Overloading)
  • 原文地址:https://blog.csdn.net/qq_45856698/article/details/134292075