1 算法介绍

1.1 BP神经网络

1、 反向传播算法应用领域

   反向传播算法应用较为广泛,从字面意思理解,与前向传播相互对应。在简单的神经网络中,反向传播算法,可以理解为最优化损失函数过程,求解每个参与运算的参数的梯度的方法。在前馈神经网络中,反向传播从求解损失函数偏导过程中,步步向前求解每一层的参数梯度。在卷积神经网络中,反向传播可以求解全连接层的参数梯度。在循环神经网络中,反向传播算法可以求解每一个时刻t或者状态t的参数梯度(在RNN\LSTM\GRU中,反向传播更多是BPTT)。笔者如今对于BP的理解,认为是在优化损失函数或者目标函数过程中,求解参与运算的参数的梯度方法,是一种比较普遍的说法。

2、准备知识--反向传播(BP)算法应用于神经网络

     反向传播(BP)算法在深度学习中,应用广泛。这里仅以前馈神经网络中的BP算法作为介绍。神经网络是一个由输入层、隐藏层、输出层三部分组成的网络,如图(1):数据从输入层,经过权重值和偏置项的线性变换处理,再通过激活层,得到隐藏层的输出,也即下一层的输入;隐藏层到输出层之间是,经过权重值和偏置项的线性变换,之后通过激活层,得到输出层。

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_02

      图2表示一个网络层为2的前馈神经网络:一个隐藏层,一个输出层;隐藏单元为5,记输入层到隐藏层的权重值为W,偏置项为b1,激活函数为g1,隐藏层到输出层的权重值为V,偏置项为b2,激活函数为g2,则图2的模型即为:

                                                               基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_03

图2是一个比较简单的神经网络,通常,我们见到的神经网络,是具有多个隐藏层的网络,如图3:这是一个隐藏层个数为N个,每层隐藏单元数为5的神经网络。(PS:隐藏层设计,可以考虑层数设计和隐藏单元设计,可根据自己的需要自行设计。)


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_04

    从输入层到隐藏层再到输出层,这一向前传递的过程,我们称之为前向传播。前向传播过程,往往是我们设定模型的过程,也可以理解为设定数学表达式或者列方程的过程。

3、BP算法原理及其实施步骤

     BP算法的核心思想:使用梯度下降来搜索可能的权向量的假设空间,以找到最佳的拟合样例的权向量。具体而言,即利用损失函数,每次向损失函数负梯度方向移动,直到损失函数取得最小值。

     或者说,反向传播算法,是根据损失函数,求出损失函数关于每一层的权值及偏置项的偏导数,也称为梯度,用该值更新初始的权值和偏置项,一直更新到损失函数取得最小值或是设置的迭代次数完成为止。以此来计算神经网络中的最佳的参数。

    由此,正式介绍BP算法前,我们需要知道前向传播过程,确定网络的设计。为此先设定一个只有一层的神经网络,作为讲解,如图4.


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_05

      设定:从输入层数据为X,输入层到隐藏层参数为w,b1,隐藏层到输出层参数为v,b2,激活函数用为g1,g2。于是模型设定为:

输入层到隐藏层:

                                                                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_06                                            (3-1)

隐藏层到输出层:

                                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_07                                               (3-2)

模型:

                                                    (3-3)

损失函数:

                                                                        基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_08                                                   (3-4)

其中:

                            

                                      

                                                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_09        

以上述的模型设定为例,下面介绍BP算法步骤,通过BP算法的步骤,了解反向传播,是如何实现模型的参数更新。

实施步骤:

    1)初始化网络中的权值和偏置项,分别记为

                                                                                                                            (3-5)

    2)激活前向传播,得到各层输出和损失函数的期望值

                                                                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_10                                                   (3-6)

      其中,基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_11表示参数集合,基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_12表示真实值基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_13表示预测值,基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_14表示对总的误差值取平均,所以一般情况下,输出单元多少维,误差值求平均就除以多少;本模型设定中,输出值为2维列数据,故用误差值除以2。一般情况下,损失函数的期望值表示为:

                                                                                                                (3-6-1)

       这是一组n维数据的输出,若是有m组这样的数据,损失函数的期望值为:

                                                             基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_15                                     (3-6-2)

       若真实值与输出值表示为基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_16,上式可表示为:

                                                                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_17                                        (3-6-3)

       一般情况下,输出数据为1维或是2维,输出的数据有多组。

    3)根据损失函数,计算输出单元的误差项和隐藏单元的误差项

       输出单元的误差项,即计算损失函数关于输出单元的梯度值或偏导数,根据链式法则有:

                                                                 

                                                          基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_18                                      (3-7)

      隐藏单元的误差项,即计算损失函数关于隐藏单元的梯度值或偏导数,根据链式法则有:

                                                                            

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_19                       (3-8)

     PS: 对于复合函数中的向量或矩阵求偏导,复合函数内部函数的偏导总是左乘;对于复合函数中的标量求偏导,复合函数内部函数的偏导左乘或者右乘都可以。

   4) 更新神经网路中的权值和偏置项

       输出单元参数更新:             基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_20                         (3-9)

       隐藏单元参数更新:                                    (3-10)     

       其中,基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_21表示学习率k=1,2,...,n表示更新次数或迭代次数,k=1表示第一次更新,以此类推。此处可能和别处博客不太一样,但实质是一样的,此处的'+'或者'-'主要取决于损失函数.

   如何定义损失函数或者定义参数更新均可,但参数的更新一定是向参数的负梯度方向。

   5) 重复步骤2-4,直到损失函数小于事先给定的阈值或迭代次数用完为止,输出此时的参数即为目前最佳参数。

这便是BP算法的一个具体步骤,下面我们详细介绍BP算法步骤中的每一步

    步骤1)初始化参数值(输出单元权值、偏置项和隐藏单元权值、偏置项均为模型的参数),是为激活前向传播,得到每一层元素的输出值,进而得到损失函数的值。参数初始化,可以自己设定,也可以选择随机生成;一般情况下,自己写代码或者调用tensorflow或keras时,都是随机生成参数。因为初始参数对最终的参数影响不大,只会影响迭代的次数。

    步骤2)在步骤1的基础上,激活前向传播,得到基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_22的值,进而得到的值;其中的计算,根据前面模型设定中的公式计算。计算这些值是为计算步骤3中的误差项。

    步骤3)计算各项误差,即计算参数关于损失函数的梯度或偏导数,之所以称之为误差,是因为损失函数本身为真实值与预测值之间的差异。计算参数的偏导数,根据的是微积分中的链式法则。具体推导如下:

     输出单元的误差项:输出单元v与损失函数E,不是直接相关,而是通过复合函数的形式关联,以设定的模型为例:

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_23      

                                                                  基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_24          (3-11)

其中基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_25表示损失函数化为与参数v,b2相关的表达式。

根据链式法则,输出单元v与损失函数E的误差项为:                              

                                                           

                                                           基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_26                                         (3-12)

求出上式中每一个偏导:

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_27

                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_28                                                          (3-13)

                                                                                                                           (3-14)

                                                               基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_29                                                (3-15)

                                                           基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_30                                              (3-16)

其中,​关于激活函数基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_31求偏导,需要根据具体的激活函数而定,每一层的激活函数可以选择不同的函数,一般情况下,为简单化模型设计和求导方便,会设定为同一个函数。此处假设选择激活函数为sigmoid函数,那么有:  

                 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_32

                                 (3-17)

PS:因为sigmoid(z)中z是标量,对z求偏导,有:

                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_33

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_34      

本文定义了z为向量,对于向量就有了式(3-17)的逐元素相乘的式子。

于是,为简化后面的计算,记

                                                    基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_35                               (3-18)

其中,基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_36​表示第k次求损失函数关于基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_37​的偏导;基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_38表示逐元素相乘,即两个向量或两个矩阵对应的元素相乘,例如:     

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_39

于是,输出单元的误差项为:

                                                                    基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_40                                            (3-19)

                                                               基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_41                               (3-20)

此处说明:若遇式(3-15)的偏导(对权值求偏导),链式法则处理方式均如式(3-19);若遇式(3-16)的偏导(对偏置项求偏导),链式法则处理方式均如式(3-20)。

隐藏单元的误差项:隐藏单元w与损失函数E,通过复合函数的形式关联,以设定的模型整理为:

         基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_42

                         基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_43 (3-21)

根据链式法则,隐藏单元w与损失函数E的误差项为:

                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_44

                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_45                        (3-22)

同样的求导法则,得到隐藏单元的误差项为:

                                                                  (3-23)

                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_46(3-24)

     其中:

                                                                    基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_47                                 (3-25)

                                                         基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_48                    (3-26)

                                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_49                                      (3-27)

                                                                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_50                              (3-28)

       说明:若遇式(3-25)(对隐藏单元求偏导),链式法则处理如式(3-23);式(3-15)和(3-26)同,故有相同的处理方式;式(3-16)和(3-27)同,故有相同的处理方式。

       补充:若有多个隐藏层时,逐步计算隐藏层的权值和偏置项误差,推导的规则同上。例如:一个隐藏层为2,隐藏单元为5的神经网络:


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_51

输出层到隐藏层2的误差项同式(3-19)

隐藏层2到隐藏层1的误差项为:

                                                                        (3-29)

记:                           

                                                                                                      (3-30)

隐藏层1到输入层的误差项为:

                                                                       (3-31)

从上述中,容易看出,无论多少层隐藏层,其误差项都是同样的结构。

     步骤4) 更新神经网路中的权值和偏置项。学习率自己设定,学习率太大,容易跳过最佳的参数;学习率太小,容易陷入局部极小值。

     步骤5) 设定阈值e或者设定迭代次数,当损失函数值小于阈值e时,或当迭代次数用完时,输出最终参数。

4、实例运用

     为能更好理解BP算法和知道如何运用BP算法,下面以一个实际的例子来说明运用BP算法的具体操作。

有一组数据基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_52,目的是训练这两组数据,找到输入X计算得到Y的预测值尽可能接近于真实值的参数。设定模型:设计一个隐藏层为1,隐藏单元数为2,激活函数为sigmod函数的模型,运用反向传播算法,得到参数。网络如图5:


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_53

于是有:

                                                  基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_54

                                                          基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_55

                                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_56

                                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_57                                       (4-1)

式(4-1)中,x表示net1后的h。

根据BP算法步骤:

  1)初始化网络中的所有参数并给出学习率基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_58

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_59

   2)激活前向传播,将参数带入式(4-1),并计算损失函数:

        输入层-->隐藏层:

                                                 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_60                       (4-2)

                                                                            (4-3)

        隐藏层-->输出层:

                                            基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_61               (4-4)

                                           (上式中x表示4-3中的h)

                                                 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_62                    (4-5)

        损失函数:

                                                    基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_63                            (4-6)

  3)计算输出单元的误差项和隐藏单元的误差项

      输出单元的误差项:根据公式(3-19),将基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_64带入其中,得到需更新的梯度误差:

                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_65           

                                            基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_66                         

                                     

      如果对v中每一个元素求偏导,有:

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_67

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_68

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_69

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_70

                                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_71

    用公式(3-19)和对v中每一个元素求偏导,得到的结果一致。

    隐藏单元的误差项:根据公式(3-23),将基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_72带入其中,得到需更新的梯度误差

                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_73

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_74

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_75

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_76

       若对w中每一个元素求偏导,有:

                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_77

                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_78

                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_79

                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_80

                                          基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_81

       用公式(3-23)和对v中每一个元素求偏导,得到的结果一致。

  注意:一般情况下,不会对偏置项更新

  4)更新神经网络中的权值

                          

                                 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_82

                        

                                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_83 

      于是,得到第一次更新的参数值w,v。

  5)重复步骤2-4,直到损失值达到了预先设定的阈值或迭代次数用完,得到最终的权值。

       以上即为BP算法的更新权值的过程,下面将上述实例的推导过程用代码实现:

1.2 帝企鹅算法

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_84

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_85

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_86

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_87

2 部分代码



%% 2021.9.2  AFO 算法优化神经网络
% 2021.9.2 AFO algorithm optimizes neural network weights and thresholds
%% 这是使用原始算法的直接求解结果,添加专用于本问题的更新方式可以进一步提高精度
% This is the direct result of using the original algorithm,
% adding some specific update methods to this problem can further improve the accuracy
clc;
clear;
close all;
warning off
%% 固定随机数种子
noRNG=1;
rng('default')
rng(noRNG)
%% 载入数据
%% 数据预处理
load input
load output
%%
data.x=[input'];
data.y=[output];
num_Train=120; %训练集数量
data.len_train=num_Train;
num_Test=48; %测试集数量
index=randperm(num_Train+num_Test); %随机乱序
data.train_x=data.x(:,index(1:num_Train))';
data.train_y=data.y(:,index(1:num_Train))';
data.test_x=data.x(:,index(num_Train+1:end))';
data.test_y=data.y(:,index(num_Train+1:end))';
% 归一化
[data.train_x0,option.ps_x]=mapminmax(data.train_x');
data.train_x0=data.train_x0';
[data.train_y0,option.ps_y]=mapminmax(data.train_y');
data.train_y0=data.train_y0';
data.test_x0 = mapminmax('apply',data.test_x',option.ps_x);
data.test_x0=data.test_x0';
data.test_y0 = mapminmax('apply',data.test_y',option.ps_y);
data.test_y0=data.test_y0';
%%
data.weight=1;
data=data;
data.hiddenumber= [5];%隐含神经元数

%% 未优化神经网络
clear result
[x(1,:),result(1)]=creat_x_1(option,data);
%draw(result(1),'未优化')
data.m=result(1).m;
data.n=result(1).n;
data.m_lw=result(1).m_lw;
data.n_lw=result(1).n_lw;
data.m_iw=result(1).m_iw;
data.n_iw=result(1).n_iw;
data.m_b=result(1).m_b;
data.n_b=result(1).n_b;
data.len=result(1).len;
[y(1),result(1)]=aimFcn_1(x(1,:),option,data,result(1).net);
%% 参数设置
lb=-5;
ub=5;
option.lb=lb;
option.ub=ub;
dim=length(x(1,:));
%%
option.dim=dim; %八个决策变量
lb=0;
ub=1;
option.lb=lb;
option.ub=ub;
if length(option.lb)==1
option.lb=ones(1,option.dim)*option.lb;
option.ub=ones(1,option.dim)*option.ub;
end
option.fobj=@aimFcn_1;
%option.fobj0=option.fobj;
option.showIter=0;
%% 算法参数设置 Parameters
% 基本参数
option.numAgent=10; %种群个体数 size of population
option.maxIteration=100; %最大迭代次数 maximum number of interation
% 帝企鹅算法
option.v_lb=-(option.ub-option.lb)/4;
option.v_ub=(option.ub-option.lb)/4;
option.w2=0.5; %weight of Moving strategy III
option.w4=1;%weight of Moving strategy III
option.w5=1;%weight of Moving strategy III
option.pe=0.01; % rate to judge Premature convergence
option.gap0=ceil(sqrt(option.maxIteration*2))+1;
option.gapMin=5; % min gap
option.dec=2; % dec of gap
option.L=10; % Catastrophe
str_legend=[{'AFO1'},{'AFO2'}];
%% Initialize population individuals (common to control experiment algorithm)
%% 初始种群生成
x=ones(option.numAgent,option.dim);
y=ones(option.numAgent,1);
for i=1:option.numAgent
[x(i,:),result(i,1)]=creat_x_1(option,data);
[y(i,1),result(i,1)]=aimFcn_1(x(i,:),option,data,result(i).net);
end
%% 使用算法求解
% Based on the same population, solve the selected functions by using different algorithms
bestX=x;
rng(noRNG)
tic
[bestY(1,:),bestX(1,:),best_result1,recording(1)]=AFO1(x,y,result,option,data);
tt(1,1)=toc;
%%
figure
hold on
for i=1:length(recording)
plot((recording(i).bestFit),'LineWidth',2)
end
legend(str_legend)
title('fitness curve')
%% 未优化神经网络
rng(7)
[x(1,:),result(1)]=creat_x_1(option,data);
[y(1),result(1)]=aimFcn_1(x(1,:),option,data,result(1).net);

%%
figure
hold on
plot(result(1).ygabptest(i,:));
plot(best_result1.ygabptest(i,:));
plot(data.test_y(:,i));
legend(['未优化神经网络(mse=',num2str(result(1).mse(i)),')'],['AFO优化神经网络(mse=',num2str(best_result1.mse(i)),')'],['真实数据'])

3 仿真结果

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_88

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_89

4 参考文献

[1]李旭飞,王贞.求解约束优化问题的改进帝企鹅优化算法[J].计算机工程与设计,2021,42(03):703-710.

5 代码下载


1 算法介绍

1.1 BP神经网络

1、 反向传播算法应用领域

   反向传播算法应用较为广泛,从字面意思理解,与前向传播相互对应。在简单的神经网络中,反向传播算法,可以理解为最优化损失函数过程,求解每个参与运算的参数的梯度的方法。在前馈神经网络中,反向传播从求解损失函数偏导过程中,步步向前求解每一层的参数梯度。在卷积神经网络中,反向传播可以求解全连接层的参数梯度。在循环神经网络中,反向传播算法可以求解每一个时刻t或者状态t的参数梯度(在RNN\LSTM\GRU中,反向传播更多是BPTT)。笔者如今对于BP的理解,认为是在优化损失函数或者目标函数过程中,求解参与运算的参数的梯度方法,是一种比较普遍的说法。

2、准备知识--反向传播(BP)算法应用于神经网络

     反向传播(BP)算法在深度学习中,应用广泛。这里仅以前馈神经网络中的BP算法作为介绍。神经网络是一个由输入层、隐藏层、输出层三部分组成的网络,如图(1):数据从输入层,经过权重值和偏置项的线性变换处理,再通过激活层,得到隐藏层的输出,也即下一层的输入;隐藏层到输出层之间是,经过权重值和偏置项的线性变换,之后通过激活层,得到输出层。

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_02

      图2表示一个网络层为2的前馈神经网络:一个隐藏层,一个输出层;隐藏单元为5,记输入层到隐藏层的权重值为W,偏置项为b1,激活函数为g1,隐藏层到输出层的权重值为V,偏置项为b2,激活函数为g2,则图2的模型即为:

                                                               基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_92

图2是一个比较简单的神经网络,通常,我们见到的神经网络,是具有多个隐藏层的网络,如图3:这是一个隐藏层个数为N个,每层隐藏单元数为5的神经网络。(PS:隐藏层设计,可以考虑层数设计和隐藏单元设计,可根据自己的需要自行设计。)


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_04

    从输入层到隐藏层再到输出层,这一向前传递的过程,我们称之为前向传播。前向传播过程,往往是我们设定模型的过程,也可以理解为设定数学表达式或者列方程的过程。

3、BP算法原理及其实施步骤

     BP算法的核心思想:使用梯度下降来搜索可能的权向量的假设空间,以找到最佳的拟合样例的权向量。具体而言,即利用损失函数,每次向损失函数负梯度方向移动,直到损失函数取得最小值。

     或者说,反向传播算法,是根据损失函数,求出损失函数关于每一层的权值及偏置项的偏导数,也称为梯度,用该值更新初始的权值和偏置项,一直更新到损失函数取得最小值或是设置的迭代次数完成为止。以此来计算神经网络中的最佳的参数。

    由此,正式介绍BP算法前,我们需要知道前向传播过程,确定网络的设计。为此先设定一个只有一层的神经网络,作为讲解,如图4.


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_05

      设定:从输入层数据为X,输入层到隐藏层参数为w,b1,隐藏层到输出层参数为v,b2,激活函数用为g1,g2。于是模型设定为:

输入层到隐藏层:

                                                                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_95                                            (3-1)

隐藏层到输出层:

                                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_96                                               (3-2)

模型:

                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_97                 (3-3)

损失函数:

                                                                        基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_98                                                   (3-4)

其中:

                            基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_99

                                      

                                                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_100        

以上述的模型设定为例,下面介绍BP算法步骤,通过BP算法的步骤,了解反向传播,是如何实现模型的参数更新。

实施步骤:

    1)初始化网络中的权值和偏置项,分别记为

                                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_101                                                         (3-5)

    2)激活前向传播,得到各层输出和损失函数的期望值

                                                                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_102                                                   (3-6)

      其中,基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_103表示参数集合,基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_104表示真实值表示预测值,基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_105表示对总的误差值取平均,所以一般情况下,输出单元多少维,误差值求平均就除以多少;本模型设定中,输出值为2维列数据,故用误差值除以2。一般情况下,损失函数的期望值表示为:

                                                                 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_106                                               (3-6-1)

       这是一组n维数据的输出,若是有m组这样的数据,损失函数的期望值为:

                                                             基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_107                                     (3-6-2)

       若真实值与输出值表示为基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_108,上式可表示为:

                                                                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_109                                        (3-6-3)

       一般情况下,输出数据为1维或是2维,输出的数据有多组。

    3)根据损失函数,计算输出单元的误差项和隐藏单元的误差项

       输出单元的误差项,即计算损失函数关于输出单元的梯度值或偏导数,根据链式法则有:

                                                          基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_110       

                                                                                                (3-7)

      隐藏单元的误差项,即计算损失函数关于隐藏单元的梯度值或偏导数,根据链式法则有:

                                                    基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_111                        

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_112                       (3-8)

     PS: 对于复合函数中的向量或矩阵求偏导,复合函数内部函数的偏导总是左乘;对于复合函数中的标量求偏导,复合函数内部函数的偏导左乘或者右乘都可以。

   4) 更新神经网路中的权值和偏置项

       输出单元参数更新:             基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_113                         (3-9)

       隐藏单元参数更新:            基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_114                        (3-10)     

       其中,基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_115表示学习率k=1,2,...,n表示更新次数或迭代次数,k=1表示第一次更新,以此类推。此处可能和别处博客不太一样,但实质是一样的,此处的'+'或者'-'主要取决于损失函数.

   如何定义损失函数或者定义参数更新均可,但参数的更新一定是向参数的负梯度方向。

   5) 重复步骤2-4,直到损失函数小于事先给定的阈值或迭代次数用完为止,输出此时的参数即为目前最佳参数。

这便是BP算法的一个具体步骤,下面我们详细介绍BP算法步骤中的每一步

    步骤1)初始化参数值(输出单元权值、偏置项和隐藏单元权值、偏置项均为模型的参数),是为激活前向传播,得到每一层元素的输出值,进而得到损失函数的值。参数初始化,可以自己设定,也可以选择随机生成;一般情况下,自己写代码或者调用tensorflow或keras时,都是随机生成参数。因为初始参数对最终的参数影响不大,只会影响迭代的次数。

    步骤2)在步骤1的基础上,激活前向传播,得到基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_116的值,进而得到的值;其中的计算,根据前面模型设定中的公式计算。计算这些值是为计算步骤3中的误差项。

    步骤3)计算各项误差,即计算参数关于损失函数的梯度或偏导数,之所以称之为误差,是因为损失函数本身为真实值与预测值之间的差异。计算参数的偏导数,根据的是微积分中的链式法则。具体推导如下:

     输出单元的误差项:输出单元v与损失函数E,不是直接相关,而是通过复合函数的形式关联,以设定的模型为例:

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_117      

                                                                  基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_118          (3-11)

其中基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_119表示损失函数化为与参数v,b2相关的表达式。

根据链式法则,输出单元v与损失函数E的误差项为:                              

                                                           基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_120

                                                           基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_121                                         (3-12)

求出上式中每一个偏导:

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_122

                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_123                                                          (3-13)

                                                                      基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_124                                                     (3-14)

                                                                                                               (3-15)

                                                                                                         (3-16)

其中,基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_125​关于激活函数基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_126求偏导,需要根据具体的激活函数而定,每一层的激活函数可以选择不同的函数,一般情况下,为简单化模型设计和求导方便,会设定为同一个函数。此处假设选择激活函数为sigmoid函数,那么有:  

                 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_127

                            基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_128     (3-17)

PS:因为sigmoid(z)中z是标量,对z求偏导,有:

                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_129

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_130      

本文定义了z为向量,对于向量就有了式(3-17)的逐元素相乘的式子。

于是,为简化后面的计算,记

                                                    基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_131                               (3-18)

其中,​表示第k次求损失函数关于基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_132​的偏导;基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_133表示逐元素相乘,即两个向量或两个矩阵对应的元素相乘,例如:     

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_134

于是,输出单元的误差项为:

                                                                    基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_135                                            (3-19)

                                                               基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_136                               (3-20)

此处说明:若遇式(3-15)的偏导(对权值求偏导),链式法则处理方式均如式(3-19);若遇式(3-16)的偏导(对偏置项求偏导),链式法则处理方式均如式(3-20)。

隐藏单元的误差项:隐藏单元w与损失函数E,通过复合函数的形式关联,以设定的模型整理为:

         基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_137

                         基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_138 (3-21)

根据链式法则,隐藏单元w与损失函数E的误差项为:

                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_139

                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_140                        (3-22)

同样的求导法则,得到隐藏单元的误差项为:

                                            基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_141                      (3-23)

                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_142(3-24)

     其中:

                                                                                                     (3-25)

                                                         基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_143                    (3-26)

                                                                                                         (3-27)

                                                                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_144                              (3-28)

       说明:若遇式(3-25)(对隐藏单元求偏导),链式法则处理如式(3-23);式(3-15)和(3-26)同,故有相同的处理方式;式(3-16)和(3-27)同,故有相同的处理方式。

       补充:若有多个隐藏层时,逐步计算隐藏层的权值和偏置项误差,推导的规则同上。例如:一个隐藏层为2,隐藏单元为5的神经网络:


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_51

输出层到隐藏层2的误差项同式(3-19)

隐藏层2到隐藏层1的误差项为:

                                                                        (3-29)

记:                           

                                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_146                                        (3-30)

隐藏层1到输入层的误差项为:

                                               基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_147                        (3-31)

从上述中,容易看出,无论多少层隐藏层,其误差项都是同样的结构。

     步骤4) 更新神经网路中的权值和偏置项。学习率自己设定,学习率太大,容易跳过最佳的参数;学习率太小,容易陷入局部极小值。

     步骤5) 设定阈值e或者设定迭代次数,当损失函数值小于阈值e时,或当迭代次数用完时,输出最终参数。

4、实例运用

     为能更好理解BP算法和知道如何运用BP算法,下面以一个实际的例子来说明运用BP算法的具体操作。

有一组数据基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_148,目的是训练这两组数据,找到输入X计算得到Y的预测值尽可能接近于真实值的参数。设定模型:设计一个隐藏层为1,隐藏单元数为2,激活函数为sigmod函数的模型,运用反向传播算法,得到参数。网络如图5:


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_53

于是有:

                                                  

                                                          基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_150

                                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_151

                                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_152                                       (4-1)

式(4-1)中,x表示net1后的h。

根据BP算法步骤:

  1)初始化网络中的所有参数并给出学习率:

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_153

   2)激活前向传播,将参数带入式(4-1),并计算损失函数:

        输入层-->隐藏层:

                                                 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_154                       (4-2)

                                                                            (4-3)

        隐藏层-->输出层:

                                            基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_155               (4-4)

                                           (上式中x表示4-3中的h)

                                                 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_156                    (4-5)

        损失函数:

                                                                                (4-6)

  3)计算输出单元的误差项和隐藏单元的误差项

      输出单元的误差项:根据公式(3-19),将基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_157带入其中,得到需更新的梯度误差:

                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_158           

                                            基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_159                         

                                     

      如果对v中每一个元素求偏导,有:

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_160

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_161

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_162

                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_163

                                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_164

    用公式(3-19)和对v中每一个元素求偏导,得到的结果一致。

    隐藏单元的误差项:根据公式(3-23),将基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_165带入其中,得到需更新的梯度误差

                              

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_166

                                       基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_167

                                       

       若对w中每一个元素求偏导,有:

                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_168

                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_169

                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_170

                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_171

                                          基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_172

       用公式(3-23)和对v中每一个元素求偏导,得到的结果一致。

  注意:一般情况下,不会对偏置项更新

  4)更新神经网络中的权值

                          基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_173

                                 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_174

                        基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_175

                                基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_176 

      于是

1 算法介绍

1.1 BP神经网络

1、 反向传播算法应用领域

   反向传播算法应用较为广泛,从字面意思理解,与前向传播相互对应。在简单的神经网络中,反向传播算法,可以理解为最优化损失函数过程,求解每个参与运算的参数的梯度的方法。在前馈神经网络中,反向传播从求解损失函数偏导过程中,步步向前求解每一层的参数梯度。在卷积神经网络中,反向传播可以求解全连接层的参数梯度。在循环神经网络中,反向传播算法可以求解每一个时刻t或者状态t的参数梯度(在RNN\LSTM\GRU中,反向传播更多是BPTT)。笔者如今对于BP的理解,认为是在优化损失函数或者目标函数过程中,求解参与运算的参数的梯度方法,是一种比较普遍的说法。

2、准备知识--反向传播(BP)算法应用于神经网络

     反向传播(BP)算法在深度学习中,应用广泛。这里仅以前馈神经网络中的BP算法作为介绍。神经网络是一个由输入层、隐藏层、输出层三部分组成的网络,如图(1):数据从输入层,经过权重值和偏置项的线性变换处理,再通过激活层,得到隐藏层的输出,也即下一层的输入;隐藏层到输出层之间是,经过权重值和偏置项的线性变换,之后通过激活层,得到输出层。

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_02

      图2表示一个网络层为2的前馈神经网络:一个隐藏层,一个输出层;隐藏单元为5,记输入层到隐藏层的权重值为W,偏置项为b1,激活函数为g1,隐藏层到输出层的权重值为V,偏置项为b2,激活函数为g2,则图2的模型即为:

                                                               基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_179

图2是一个比较简单的神经网络,通常,我们见到的神经网络,是具有多个隐藏层的网络,如图3:这是一个隐藏层个数为N个,每层隐藏单元数为5的神经网络。(PS:隐藏层设计,可以考虑层数设计和隐藏单元设计,可根据自己的需要自行设计。)


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_04

    从输入层到隐藏层再到输出层,这一向前传递的过程,我们称之为前向传播。前向传播过程,往往是我们设定模型的过程,也可以理解为设定数学表达式或者列方程的过程。

3、BP算法原理及其实施步骤

     BP算法的核心思想:使用梯度下降来搜索可能的权向量的假设空间,以找到最佳的拟合样例的权向量。具体而言,即利用损失函数,每次向损失函数负梯度方向移动,直到损失函数取得最小值。

     或者说,反向传播算法,是根据损失函数,求出损失函数关于每一层的权值及偏置项的偏导数,也称为梯度,用该值更新初始的权值和偏置项,一直更新到损失函数取得最小值或是设置的迭代次数完成为止。以此来计算神经网络中的最佳的参数。

    由此,正式介绍BP算法前,我们需要知道前向传播过程,确定网络的设计。为此先设定一个只有一层的神经网络,作为讲解,如图4.


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_05

      设定:从输入层数据为X,输入层到隐藏层参数为w,b1,隐藏层到输出层参数为v,b2,激活函数用为g1,g2。于是模型设定为:

输入层到隐藏层:

                                                                                                            (3-1)

隐藏层到输出层:

                                                              基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_182                                               (3-2)

模型:

                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_183                 (3-3)

损失函数:

                                                                        基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_184                                                   (3-4)

其中:

                            基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_185


                                                                     基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_186        

以上述的模型设定为例,下面介绍BP算法步骤,通过BP算法的步骤,了解反向传播,是如何实现模型的参数更新。

实施步骤:

    1)初始化网络中的权值和偏置项,分别记为

                                                                   基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_187                                                         (3-5)

    2)激活前向传播,得到各层输出和损失函数的期望值

                                                                                                                   (3-6)

      其中,表示参数集合,表示真实值表示预测值,表示对总的误差值取平均,所以一般情况下,输出单元多少维,误差值求平均就除以多少;本模型设定中,输出值为2维列数据,故用误差值除以2。一般情况下,损失函数的期望值表示为:

                                                                                                                (3-6-1)

       这是一组n维数据的输出,若是有m组这样的数据,损失函数的期望值为:

                                                                                                  (3-6-2)

       若真实值与输出值表示为,上式可表示为:

                                                                                                        (3-6-3)

       一般情况下,输出数据为1维或是2维,输出的数据有多组。

    3)根据损失函数,计算输出单元的误差项和隐藏单元的误差项

       输出单元的误差项,即计算损失函数关于输出单元的梯度值或偏导数,根据链式法则有:

                                                                 

                                                                                                (3-7)

      隐藏单元的误差项,即计算损失函数关于隐藏单元的梯度值或偏导数,根据链式法则有:

                                                                            

                                                                          (3-8)

     PS: 对于复合函数中的向量或矩阵求偏导,复合函数内部函数的偏导总是左乘;对于复合函数中的标量求偏导,复合函数内部函数的偏导左乘或者右乘都可以。

   4) 更新神经网路中的权值和偏置项

       输出单元参数更新:                                      (3-9)

       隐藏单元参数更新:                                    (3-10)     

       其中,表示学习率k=1,2,...,n表示更新次数或迭代次数,k=1表示第一次更新,以此类推。此处可能和别处博客不太一样,但实质是一样的,此处的'+'或者'-'主要取决于损失函数.

   如何定义损失函数或者定义参数更新均可,但参数的更新一定是向参数的负梯度方向。

   5) 重复步骤2-4,直到损失函数小于事先给定的阈值或迭代次数用完为止,输出此时的参数即为目前最佳参数。

这便是BP算法的一个具体步骤,下面我们详细介绍BP算法步骤中的每一步

    步骤1)初始化参数值(输出单元权值、偏置项和隐藏单元权值、偏置项均为模型的参数),是为激活前向传播,得到每一层元素的输出值,进而得到损失函数的值。参数初始化,可以自己设定,也可以选择随机生成;一般情况下,自己写代码或者调用tensorflow或keras时,都是随机生成参数。因为初始参数对最终的参数影响不大,只会影响迭代的次数。

    步骤2)在步骤1的基础上,激活前向传播,得到的值,进而得到的值;其中的计算,根据前面模型设定中的公式计算。计算这些值是为计算步骤3中的误差项。

    步骤3)计算各项误差,即计算参数关于损失函数的梯度或偏导数,之所以称之为误差,是因为损失函数本身为真实值与预测值之间的差异。计算参数的偏导数,根据的是微积分中的链式法则。具体推导如下:

     输出单元的误差项:输出单元v与损失函数E,不是直接相关,而是通过复合函数的形式关联,以设定的模型为例:


                                                                            (3-11)

其中表示损失函数化为与参数v,b2相关的表达式。

根据链式法则,输出单元v与损失函数E的误差项为:                              

                                                           

                                                                                                    (3-12)

求出上式中每一个偏导:


                                                                                                        (3-13)

                                                                                                                           (3-14)

                                                                                                               (3-15)

                                                                                                         (3-16)

其中,关于激活函数求偏导,需要根据具体的激活函数而定,每一层的激活函数可以选择不同的函数,一般情况下,为简单化模型设计和求导方便,会设定为同一个函数。此处假设选择激活函数为sigmoid函数,那么有:  


                                 (3-17)

PS:因为sigmoid(z)中z是标量,对z求偏导,有:



本文定义了z为向量,对于向量就有了式(3-17)的逐元素相乘的式子。

于是,为简化后面的计算,记

                                                                                   (3-18)

其中,表示第k次求损失函数关于的偏导;表示逐元素相乘,即两个向量或两个矩阵对应的元素相乘,例如:     


于是,输出单元的误差项为:

                                                                                                                (3-19)

                                                                                              (3-20)

此处说明:若遇式(3-15)的偏导(对权值求偏导),链式法则处理方式均如式(3-19);若遇式(3-16)的偏导(对偏置项求偏导),链式法则处理方式均如式(3-20)。

隐藏单元的误差项:隐藏单元w与损失函数E,通过复合函数的形式关联,以设定的模型整理为:

         

                          (3-21)

根据链式法则,隐藏单元w与损失函数E的误差项为:

                                              

                                                                      (3-22)

同样的求导法则,得到隐藏单元的误差项为:

                                                                  (3-23)

                   (3-24)

     其中:

                                                                                                     (3-25)

                                                                             (3-26)

                                                                                                         (3-27)

                                                                                              (3-28)

       说明:若遇式(3-25)(对隐藏单元求偏导),链式法则处理如式(3-23);式(3-15)和(3-26)同,故有相同的处理方式;式(3-16)和(3-27)同,故有相同的处理方式。

       补充:若有多个隐藏层时,逐步计算隐藏层的权值和偏置项误差,推导的规则同上。例如:一个隐藏层为2,隐藏单元为5的神经网络:


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_51

输出层到隐藏层2的误差项同式(3-19)

隐藏层2到隐藏层1的误差项为:

                                                                        (3-29)

记:                           

                                                                                                      (3-30)

隐藏层1到输入层的误差项为:

                                                                       (3-31)

从上述中,容易看出,无论多少层隐藏层,其误差项都是同样的结构。

     步骤4) 更新神经网路中的权值和偏置项。学习率自己设定,学习率太大,容易跳过最佳的参数;学习率太小,容易陷入局部极小值。

     步骤5) 设定阈值e或者设定迭代次数,当损失函数值小于阈值e时,或当迭代次数用完时,输出最终参数。

4、实例运用

     为能更好理解BP算法和知道如何运用BP算法,下面以一个实际的例子来说明运用BP算法的具体操作。

有一组数据,目的是训练这两组数据,找到输入X计算得到Y的预测值尽可能接近于真实值的参数。设定模型:设计一个隐藏层为1,隐藏单元数为2,激活函数为sigmod函数的模型,运用反向传播算法,得到参数。网络如图5:


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_53

于是有:




                                                                                              (4-1)

式(4-1)中,x表示net1后的h。

根据BP算法步骤:

  1)初始化网络中的所有参数并给出学习率:


   2)激活前向传播,将参数带入式(4-1),并计算损失函数:

        输入层-->隐藏层:

                                                                        (4-2)

                                                                            (4-3)

        隐藏层-->输出层:

                                                           (4-4)

                                           (上式中x表示4-3中的h)

                                                                     (4-5)

        损失函数:

                                                                                (4-6)

  3)计算输出单元的误差项和隐藏单元的误差项

      输出单元的误差项:根据公式(3-19),将带入其中,得到需更新的梯度误差:




      如果对v中每一个元素求偏导,有:






    用公式(3-19)和对v中每一个元素求偏导,得到的结果一致。

    隐藏单元的误差项:根据公式(3-23),将带入其中,得到需更新的梯度误差





       若对w中每一个元素求偏导,有:






       用公式(3-23)和对v中每一个元素求偏导,得到的结果一致。

  注意:一般情况下,不会对偏置项更新

  4)更新神经网络中的权值





      于是,得到第一次更新的参数值w,v。

  5)重复步骤2-4,直到损失值达到了预先设定的阈值或迭代次数用完,得到最终的权值。

       以上即为BP算法的更新权值的过程,下面将上述实例的推导过程用代码实现:

1.2 帝企鹅算法

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_84

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_85

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_86

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_87

2 部分代码



%% 2021.9.2  AFO 算法优化神经网络
% 2021.9.2 AFO algorithm optimizes neural network weights and thresholds
%% 这是使用原始算法的直接求解结果,添加专用于本问题的更新方式可以进一步提高精度
% This is the direct result of using the original algorithm,
% adding some specific update methods to this problem can further improve the accuracy
clc;
clear;
close all;
warning off
%% 固定随机数种子
noRNG=1;
rng('default')
rng(noRNG)
%% 载入数据
%% 数据预处理
load input
load output
%%
data.x=[input'];
data.y=[output];
num_Train=120; %训练集数量
data.len_train=num_Train;
num_Test=48; %测试集数量
index=randperm(num_Train+num_Test); %随机乱序
data.train_x=data.x(:,index(1:num_Train))';
data.train_y=data.y(:,index(1:num_Train))';
data.test_x=data.x(:,index(num_Train+1:end))';
data.test_y=data.y(:,index(num_Train+1:end))';
% 归一化
[data.train_x0,option.ps_x]=mapminmax(data.train_x');
data.train_x0=data.train_x0';
[data.train_y0,option.ps_y]=mapminmax(data.train_y');
data.train_y0=data.train_y0';
data.test_x0 = mapminmax('apply',data.test_x',option.ps_x);
data.test_x0=data.test_x0';
data.test_y0 = mapminmax('apply',data.test_y',option.ps_y);
data.test_y0=data.test_y0';
%%
data.weight=1;
data=data;
data.hiddenumber= [5];%隐含神经元数

%% 未优化神经网络
clear result
[x(1,:),result(1)]=creat_x_1(option,data);
%draw(result(1),'未优化')
data.m=result(1).m;
data.n=result(1).n;
data.m_lw=result(1).m_lw;
data.n_lw=result(1).n_lw;
data.m_iw=result(1).m_iw;
data.n_iw=result(1).n_iw;
data.m_b=result(1).m_b;
data.n_b=result(1).n_b;
data.len=result(1).len;
[y(1),result(1)]=aimFcn_1(x(1,:),option,data,result(1).net);
%% 参数设置
lb=-5;
ub=5;
option.lb=lb;
option.ub=ub;
dim=length(x(1,:));
%%
option.dim=dim; %八个决策变量
lb=0;
ub=1;
option.lb=lb;
option.ub=ub;
if length(option.lb)==1
option.lb=ones(1,option.dim)*option.lb;
option.ub=ones(1,option.dim)*option.ub;
end
option.fobj=@aimFcn_1;
%option.fobj0=option.fobj;
option.showIter=0;
%% 算法参数设置 Parameters
% 基本参数
option.numAgent=10; %种群个体数 size of population
option.maxIteration=100; %最大迭代次数 maximum number of interation
% 帝企鹅算法
option.v_lb=-(option.ub-option.lb)/4;
option.v_ub=(option.ub-option.lb)/4;
option.w2=0.5; %weight of Moving strategy III
option.w4=1;%weight of Moving strategy III
option.w5=1;%weight of Moving strategy III
option.pe=0.01; % rate to judge Premature convergence
option.gap0=ceil(sqrt(option.maxIteration*2))+1;
option.gapMin=5; % min gap
option.dec=2; % dec of gap
option.L=10; % Catastrophe
str_legend=[{'AFO1'},{'AFO2'}];
%% Initialize population individuals (common to control experiment algorithm)
%% 初始种群生成
x=ones(option.numAgent,option.dim);
y=ones(option.numAgent,1);
for i=1:option.numAgent
[x(i,:),result(i,1)]=creat_x_1(option,data);
[y(i,1),result(i,1)]=aimFcn_1(x(i,:),option,data,result(i).net);
end
%% 使用算法求解
% Based on the same population, solve the selected functions by using different algorithms
bestX=x;
rng(noRNG)
tic
[bestY(1,:),bestX(1,:),best_result1,recording(1)]=AFO1(x,y,result,option,data);
tt(1,1)=toc;
%%
figure
hold on
for i=1:length(recording)
plot((recording(i).bestFit),'LineWidth',2)
end
legend(str_legend)
title('fitness curve')
%% 未优化神经网络
rng(7)
[x(1,:),result(1)]=creat_x_1(option,data);
[y(1),result(1)]=aimFcn_1(x(1,:),option,data,result(1).net);

%%
figure
hold on
plot(result(1).ygabptest(i,:));
plot(best_result1.ygabptest(i,:));
plot(data.test_y(:,i));
legend(['未优化神经网络(mse=',num2str(result(1).mse(i)),')'],['AFO优化神经网络(mse=',num2str(best_result1.mse(i)),')'],['真实数据'])

3 仿真结果

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_88

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_89

4 参考文献

[1]李旭飞,王贞.求解约

1 算法介绍

1.1 BP神经网络

1、 反向传播算法应用领域

   反向传播算法应用较为广泛,从字面意思理解,与前向传播相互对应。在简单的神经网络中,反向传播算法,可以理解为最优化损失函数过程,求解每个参与运算的参数的梯度的方法。在前馈神经网络中,反向传播从求解损失函数偏导过程中,步步向前求解每一层的参数梯度。在卷积神经网络中,反向传播可以求解全连接层的参数梯度。在循环神经网络中,反向传播算法可以求解每一个时刻t或者状态t的参数梯度(在RNN\LSTM\GRU中,反向传播更多是BPTT)。笔者如今对于BP的理解,认为是在优化损失函数或者目标函数过程中,求解参与运算的参数的梯度方法,是一种比较普遍的说法。

2、准备知识--反向传播(BP)算法应用于神经网络

     反向传播(BP)算法在深度学习中,应用广泛。这里仅以前馈神经网络中的BP算法作为介绍。神经网络是一个由输入层、隐藏层、输出层三部分组成的网络,如图(1):数据从输入层,经过权重值和偏置项的线性变换处理,再通过激活层,得到隐藏层的输出,也即下一层的输入;隐藏层到输出层之间是,经过权重值和偏置项的线性变换,之后通过激活层,得到输出层。

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_02

      图2表示一个网络层为2的前馈神经网络:一个隐藏层,一个输出层;隐藏单元为5,记输入层到隐藏层的权重值为W,偏置项为b1,激活函数为g1,隐藏层到输出层的权重值为V,偏置项为b2,激活函数为g2,则图2的模型即为:


图2是一个比较简单的神经网络,通常,我们见到的神经网络,是具有多个隐藏层的网络,如图3:这是一个隐藏层个数为N个,每层隐藏单元数为5的神经网络。(PS:隐藏层设计,可以考虑层数设计和隐藏单元设计,可根据自己的需要自行设计。)


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_04

    从输入层到隐藏层再到输出层,这一向前传递的过程,我们称之为前向传播。前向传播过程,往往是我们设定模型的过程,也可以理解为设定数学表达式或者列方程的过程。

3、BP算法原理及其实施步骤

     BP算法的核心思想:使用梯度下降来搜索可能的权向量的假设空间,以找到最佳的拟合样例的权向量。具体而言,即利用损失函数,每次向损失函数负梯度方向移动,直到损失函数取得最小值。

     或者说,反向传播算法,是根据损失函数,求出损失函数关于每一层的权值及偏置项的偏导数,也称为梯度,用该值更新初始的权值和偏置项,一直更新到损失函数取得最小值或是设置的迭代次数完成为止。以此来计算神经网络中的最佳的参数。

    由此,正式介绍BP算法前,我们需要知道前向传播过程,确定网络的设计。为此先设定一个只有一层的神经网络,作为讲解,如图4.


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_05

      设定:从输入层数据为X,输入层到隐藏层参数为w,b1,隐藏层到输出层参数为v,b2,激活函数用为g1,g2。于是模型设定为:

输入层到隐藏层:

                                                                                                            (3-1)

隐藏层到输出层:

                                                                                                             (3-2)

模型:

                                                    (3-3)

损失函数:

                                                                                                                           (3-4)

其中:




以上述的模型设定为例,下面介绍BP算法步骤,通过BP算法的步骤,了解反向传播,是如何实现模型的参数更新。

实施步骤:

    1)初始化网络中的权值和偏置项,分别记为

                                                                                                                            (3-5)

    2)激活前向传播,得到各层输出和损失函数的期望值

                                                                                                                   (3-6)

      其中,表示参数集合,表示真实值表示预测值,表示对总的误差值取平均,所以一般情况下,输出单元多少维,误差值求平均就除以多少;本模型设定中,输出值为2维列数据,故用误差值除以2。一般情况下,损失函数的期望值表示为:

                                                                                                                (3-6-1)

       这是一组n维数据的输出,若是有m组这样的数据,损失函数的期望值为:

                                                                                                  (3-6-2)

       若真实值与输出值表示为,上式可表示为:

                                                                                                        (3-6-3)

       一般情况下,输出数据为1维或是2维,输出的数据有多组。

    3)根据损失函数,计算输出单元的误差项和隐藏单元的误差项

       输出单元的误差项,即计算损失函数关于输出单元的梯度值或偏导数,根据链式法则有:

                                                                 

                                                                                                (3-7)

      隐藏单元的误差项,即计算损失函数关于隐藏单元的梯度值或偏导数,根据链式法则有:

                                                                            

                                                                          (3-8)

     PS: 对于复合函数中的向量或矩阵求偏导,复合函数内部函数的偏导总是左乘;对于复合函数中的标量求偏导,复合函数内部函数的偏导左乘或者右乘都可以。

   4) 更新神经网路中的权值和偏置项

       输出单元参数更新:                                      (3-9)

       隐藏单元参数更新:                                    (3-10)     

       其中,表示学习率k=1,2,...,n表示更新次数或迭代次数,k=1表示第一次更新,以此类推。此处可能和别处博客不太一样,但实质是一样的,此处的'+'或者'-'主要取决于损失函数.

   如何定义损失函数或者定义参数更新均可,但参数的更新一定是向参数的负梯度方向。

   5) 重复步骤2-4,直到损失函数小于事先给定的阈值或迭代次数用完为止,输出此时的参数即为目前最佳参数。

这便是BP算法的一个具体步骤,下面我们详细介绍BP算法步骤中的每一步

    步骤1)初始化参数值(输出单元权值、偏置项和隐藏单元权值、偏置项均为模型的参数),是为激活前向传播,得到每一层元素的输出值,进而得到损失函数的值。参数初始化,可以自己设定,也可以选择随机生成;一般情况下,自己写代码或者调用tensorflow或keras时,都是随机生成参数。因为初始参数对最终的参数影响不大,只会影响迭代的次数。

    步骤2)在步骤1的基础上,激活前向传播,得到的值,进而得到的值;其中的计算,根据前面模型设定中的公式计算。计算这些值是为计算步骤3中的误差项。

    步骤3)计算各项误差,即计算参数关于损失函数的梯度或偏导数,之所以称之为误差,是因为损失函数本身为真实值与预测值之间的差异。计算参数的偏导数,根据的是微积分中的链式法则。具体推导如下:

     输出单元的误差项:输出单元v与损失函数E,不是直接相关,而是通过复合函数的形式关联,以设定的模型为例:


                                                                            (3-11)

其中表示损失函数化为与参数v,b2相关的表达式。

根据链式法则,输出单元v与损失函数E的误差项为:                              

                                                           

                                                                                                    (3-12)

求出上式中每一个偏导:


                                                                                                        (3-13)

                                                                                                                           (3-14)

                                                                                                               (3-15)

                                                                                                         (3-16)

其中,关于激活函数求偏导,需要根据具体的激活函数而定,每一层的激活函数可以选择不同的函数,一般情况下,为简单化模型设计和求导方便,会设定为同一个函数。此处假设选择激活函数为sigmoid函数,那么有:  


                                 (3-17)

PS:因为sigmoid(z)中z是标量,对z求偏导,有:



本文定义了z为向量,对于向量就有了式(3-17)的逐元素相乘的式子。

于是,为简化后面的计算,记

                                                                                   (3-18)

其中,表示第k次求损失函数关于的偏导;表示逐元素相乘,即两个向量或两个矩阵对应的元素相乘,例如:     


于是,输出单元的误差项为:

                                                                                                                (3-19)

                                                                                              (3-20)

此处说明:若遇式(3-15)的偏导(对权值求偏导),链式法则处理方式均如式(3-19);若遇式(3-16)的偏导(对偏置项求偏导),链式法则处理方式均如式(3-20)。

隐藏单元的误差项:隐藏单元w与损失函数E,通过复合函数的形式关联,以设定的模型整理为:

         

                          (3-21)

根据链式法则,隐藏单元w与损失函数E的误差项为:

                                              

                                                                      (3-22)

同样的求导法则,得到隐藏单元的误差项为:

                                                                  (3-23)

                   (3-24)

     其中:

                                                                                                     (3-25)

                                                                             (3-26)

                                                                                                         (3-27)

                                                                                              (3-28)

       说明:若遇式(3-25)(对隐藏单元求偏导),链式法则处理如式(3-23);式(3-15)和(3-26)同,故有相同的处理方式;式(3-16)和(3-27)同,故有相同的处理方式。

       补充:若有多个隐藏层时,逐步计算隐藏层的权值和偏置项误差,推导的规则同上。例如:一个隐藏层为2,隐藏单元为5的神经网络:


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_51

输出层到隐藏层2的误差项同式(3-19)

隐藏层2到隐藏层1的误差项为:

                                                                        (3-29)

记:                           

                                                                                                      (3-30)

隐藏层1到输入层的误差项为:

                                                                       (3-31)

从上述中,容易看出,无论多少层隐藏层,其误差项都是同样的结构。

     步骤4) 更新神经网路中的权值和偏置项。学习率自己设定,学习率太大,容易跳过最佳的参数;学习率太小,容易陷入局部极小值。

     步骤5) 设定阈值e或者设定迭代次数,当损失函数值小于阈值e时,或当迭代次数用完时,输出最终参数。

4、实例运用

     为能更好理解BP算法和知道如何运用BP算法,下面以一个实际的例子来说明运用BP算法的具体操作。

有一组数据,目的是训练这两组数据,找到输入X计算得到Y的预测值尽可能接近于真实值的参数。设定模型:设计一个隐藏层为1,隐藏单元数为2,激活函数为sigmod函数的模型,运用反向传播算法,得到参数。网络如图5:


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_53

于是有:




                                                                                              (4-1)

式(4-1)中,x表示net1后的h。

根据BP算法步骤:

  1)初始化网络中的所有参数并给出学习率:


   2)激活前向传播,将参数带入式(4-1),并计算损失函数:

        输入层-->隐藏层:

                                                                        (4-2)

                                                                            (4-3)

        隐藏层-->输出层:

                                                           (4-4)

                                           (上式中x表示4-3中的h)

                                                                     (4-5)

        损失函数:

                                                                                (4-6)

  3)计算输出单元的误差项和隐藏单元的误差项

      输出单元的误差项:根据公式(3-19),将带入其中,得到需更新的梯度误差:




      如果对v中每一个元素求偏导,有:






    用公式(3-19)和对v中每一个元素求偏导,得到的结果一致。

    隐藏单元的误差项:根据公式(3-23),将带入其中,得到需更新的梯度误差





       若对w中每一个元素求偏导,有:






       用公式(3-23)和对v中每一个元素求偏导,得到的结果一致。

  注意:一般情况下,不会对偏置项更新

  4)更新神经网络中的权值





      于是,得到第一次更新的参数值w,v。

  5)重复步骤2-4,直到损失值达到了预先设定的阈值或迭代次数用完,得到最终的权值。

       以上即为BP算法的更新权值的过程,下面将上述实例的推导过程用代码实现:

1.2 帝企鹅算法

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_84

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_85

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_86

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_87

2 部分代码



%% 2021.9.2  AFO 算法优化神经网络
% 2021.9.2 AFO algorithm optimizes neural network weights and thresholds
%% 这是使用原始算法的直接求解结果,添加专用于本问题的更新方式可以进一步提高精度
% This is the direct result of using the original algorithm,
% adding some specific update methods to this problem can further improve the accuracy
clc;
clear;
close all;
warning off
%% 固定随机数种子
noRNG=1;
rng('default')
rng(noRNG)
%% 载入数据
%% 数据预处理
load input
load output
%%
data.x=[input'];
data.y=[output];
num_Train=120; %训练集数量
data.len_train=num_Train;
num_Test=48; %测试集数量
index=randperm(num_Train+num_Test); %随机乱序
data.train_x=data.x(:,index(1:num_Train))';
data.train_y=data.y(:,index(1:num_Train))';
data.test_x=data.x(:,index(num_Train+1:end))';
data.test_y=data.y(:,index(num_Train+1:end))';
% 归一化
[data.train_x0,option.ps_x]=mapminmax(data.train_x');
data.train_x0=data.train_x0';
[data.train_y0,option.ps_y]=mapminmax(data.train_y');
data.train_y0=data.train_y0';
data.test_x0 = mapminmax('apply',data.test_x',option.ps_x);
data.test_x0=data.test_x0';
data.test_y0 = mapminmax('apply',data.test_y',option.ps_y);
data.test_y0=data.test_y0';
%%
data.weight=1;
data=data;
data.hiddenumber= [5];%隐含神经元数

%% 未优化神经网络
clear result
[x(1,:),result(1)]=creat_x_1(option,data);
%draw(result(1),'未优化')
data.m=result(1).m;
data.n=result(1).n;
data.m_lw=result(1).m_lw;
data.n_lw=result(1).n_lw;
data.m_iw=result(1).m_iw;
data.n_iw=result(1).n_iw;
data.m_b=result(1).m_b;
data.n_b=result(1).n_b;
data.len=result(1).len;
[y(1),result(1)]=aimFcn_1(x(1,:),option,data,result(1).net);
%% 参数设置
lb=-5;
ub=5;
option.lb=lb;
option.ub=ub;
dim=length(x(1,:));
%%
option.dim=dim; %八个决策变量
lb=0;
ub=1;
option.lb=lb;
option.ub=ub;
if length(option.lb)==1
option.lb=ones(1,option.dim)*option.lb;
option.ub=ones(1,option.dim)*option.ub;
end
option.fobj=@aimFcn_1;
%option.fobj0=option.fobj;
option.showIter=0;
%% 算法参数设置 Parameters
% 基本参数
option.numAgent=10; %种群个体数 size of population
option.maxIteration=100; %最大迭代次数 maximum number of interation
% 帝企鹅算法
option.v_lb=-(option.ub-option.lb)/4;
option.v_ub=(option.ub-option.lb)/4;
option.w2=0.5; %weight of Moving strategy III
option.w4=1;%weight of Moving strategy III
option.w5=1;%weight of Moving strategy III
option.pe=0.01; % rate to judge Premature convergence
option.gap0=ceil(sqrt(option.maxIteration*2))+1;
option.gapMin=5; % min gap
option.dec=2; % dec of gap
option.L=10; % Catastrophe
str_legend=[{'AFO1'},{'AFO2'}];
%% Initialize population individuals (common to control experiment algorithm)
%% 初始种群生成
x=ones(option.numAgent,option.dim);
y=ones(option.numAgent,1);
for i=1:option.numAgent
[x(i,:),result(i,1)]=creat_x_1(option,data);
[y(i,1),result(i,1)]=aimFcn_1(x(i,:),option,data,result(i).net);
end
%% 使用算法求解
% Based on the same population, solve the selected functions by using different algorithms
bestX=x;
rng(noRNG)
tic
[bestY(1,:),bestX(1,:),best_result1,recording(1)]=AFO1(x,y,result,option,data);
tt(1,1)=toc;
%%
figure
hold on
for i=1:length(recording)
plot((recording(i).bestFit),'LineWidth',2)
end
legend(str_legend)
title('fitness curve')
%% 未优化神经网络
rng(7)
[x(1,:),result(1)]=creat_x_1(option,data);
[y(1),result(1)]=aimFcn_1(x(1,:),option,data,result(1).net);

%%
figure
hold on
plot(result(1).ygabptest(i,:));
plot(best_result1.ygabptest(i,:));
plot(data.test_y(:,i));
legend(['未优化神经网络(mse=',num2str(result(1).mse(i)),')'],['AFO优化神经网络(mse=',num2str(best_result1.mse(i)),')'],['真实数据'])

3 仿真结果

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_88

1 算法介绍

1.1 BP神经网络

1、 反向传播算法应用领域

   反向传播算法应用较为广泛,从字面意思理解,与前向传播相互对应。在简单的神经网络中,反向传播算法,可以理解为最优化损失函数过程,求解每个参与运算的参数的梯度的方法。在前馈神经网络中,反向传播从求解损失函数偏导过程中,步步向前求解每一层的参数梯度。在卷积神经网络中,反向传播可以求解全连接层的参数梯度。在循环神经网络中,反向传播算法可以求解每一个时刻t或者状态t的参数梯度(在RNN\LSTM\GRU中,反向传播更多是BPTT)。笔者如今对于BP的理解,认为是在优化损失函数或者目标函数过程中,求解参与运算的参数的梯度方法,是一种比较普遍的说法。

2、准备知识--反向传播(BP)算法应用于神经网络

     反向传播(BP)算法在深度学习中,应用广泛。这里仅以前馈神经网络中的BP算法作为介绍。神经网络是一个由输入层、隐藏层、输出层三部分组成的网络,如图(1):数据从输入层,经过权重值和偏置项的线性变换处理,再通过激活层,得到隐藏层的输出,也即下一层的输入;隐藏层到输出层之间是,经过权重值和偏置项的线性变换,之后通过激活层,得到输出层。




      图2表示一个网络层为2的前馈神经网络:一个隐藏层,一个输出层;隐藏单元为5,记输入层到隐藏层的权重值为W,偏置项为b1,激活函数为g1,隐藏层到输出层的权重值为V,偏置项为b2,激活函数为g2,则图2的模型即为:


图2是一个比较简单的神经网络,通常,我们见到的神经网络,是具有多个隐藏层的网络,如图3:这是一个隐藏层个数为N个,每层隐藏单元数为5的神经网络。(PS:隐藏层设计,可以考虑层数设计和隐藏单元设计,可根据自己的需要自行设计。)



    从输入层到隐藏层再到输出层,这一向前传递的过程,我们称之为前向传播。前向传播过程,往往是我们设定模型的过程,也可以理解为设定数学表达式或者列方程的过程。

3、BP算法原理及其实施步骤

     BP算法的核心思想:使用梯度下降来搜索可能的权向量的假设空间,以找到最佳的拟合样例的权向量。具体而言,即利用损失函数,每次向损失函数负梯度方向移动,直到损失函数取得最小值。

     或者说,反向传播算法,是根据损失函数,求出损失函数关于每一层的权值及偏置项的偏导数,也称为梯度,用该值更新初始的权值和偏置项,一直更新到损失函数取得最小值或是设置的迭代次数完成为止。以此来计算神经网络中的最佳的参数。

    由此,正式介绍BP算法前,我们需要知道前向传播过程,确定网络的设计。为此先设定一个只有一层的神经网络,作为讲解,如图4.



      设定:从输入层数据为X,输入层到隐藏层参数为w,b1,隐藏层到输出层参数为v,b2,激活函数用为g1,g2。于是模型设定为:

输入层到隐藏层:

                                                                                                            (3-1)

隐藏层到输出层:

                                                                                                             (3-2)

模型:

                                                    (3-3)

损失函数:

                                                                                                                           (3-4)

其中:




以上述的模型设定为例,下面介绍BP算法步骤,通过BP算法的步骤,了解反向传播,是如何实现模型的参数更新。

实施步骤:

    1)初始化网络中的权值和偏置项,分别记为

                                                                                                                            (3-5)

    2)激活前向传播,得到各层输出和损失函数的期望值

                                                                                                                   (3-6)

      其中,表示参数集合,表示真实值表示预测值,表示对总的误差值取平均,所以一般情况下,输出单元多少维,误差值求平均就除以多少;本模型设定中,输出值为2维列数据,故用误差值除以2。一般情况下,损失函数的期望值表示为:

                                                                                                                (3-6-1)

       这是一组n维数据的输出,若是有m组这样的数据,损失函数的期望值为:

                                                                                                  (3-6-2)

       若真实值与输出值表示为,上式可表示为:

                                                                                                        (3-6-3)

       一般情况下,输出数据为1维或是2维,输出的数据有多组。

    3)根据损失函数,计算输出单元的误差项和隐藏单元的误差项

       输出单元的误差项,即计算损失函数关于输出单元的梯度值或偏导数,根据链式法则有:

                                                                 

                                                                                                (3-7)

      隐藏单元的误差项,即计算损失函数关于隐藏单元的梯度值或偏导数,根据链式法则有:

                                                                            

                                                                          (3-8)

     PS: 对于复合函数中的向量或矩阵求偏导,复合函数内部函数的偏导总是左乘;对于复合函数中的标量求偏导,复合函数内部函数的偏导左乘或者右乘都可以。

   4) 更新神经网路中的权值和偏置项

       输出单元参数更新:                                      (3-9)

       隐藏单元参数更新:                                    (3-10)     

       其中,表示学习率k=1,2,...,n表示更新次数或迭代次数,k=1表示第一次更新,以此类推。此处可能和别处博客不太一样,但实质是一样的,此处的'+'或者'-'主要取决于损失函数.

   如何定义损失函数或者定义参数更新均可,但参数的更新一定是向参数的负梯度方向。

   5) 重复步骤2-4,直到损失函数小于事先给定的阈值或迭代次数用完为止,输出此时的参数即为目前最佳参数。

这便是BP算法的一个具体步骤,下面我们详细介绍BP算法步骤中的每一步

    步骤1)初始化参数值(输出单元权值、偏置项和隐藏单元权值、偏置项均为模型的参数),是为激活前向传播,得到每一层元素的输出值,进而得到损失函数的值。参数初始化,可以自己设定,也可以选择随机生成;一般情况下,自己写代码或者调用tensorflow或keras时,都是随机生成参数。因为初始参数对最终的参数影响不大,只会影响迭代的次数。

    步骤2)在步骤1的基础上,激活前向传播,得到的值,进而得到的值;其中的计算,根据前面模型设定中的公式计算。计算这些值是为计算步骤3中的误差项。

    步骤3)计算各项误差,即计算参数关于损失函数的梯度或偏导数,之所以称之为误差,是因为损失函数本身为真实值与预测值之间的差异。计算参数的偏导数,根据的是微积分中的链式法则。具体推导如下:

     输出单元的误差项:输出单元v与损失函数E,不是直接相关,而是通过复合函数的形式关联,以设定的模型为例:


                                                                            (3-11)

其中表示损失函数化为与参数v,b2相关的表达式。

根据链式法则,输出单元v与损失函数E的误差项为:                              

                                                           

                                                                                                    (3-12)

求出上式中每一个偏导:


                                                                                                        (3-13)

                                                                                                                           (3-14)

                                                                                                               (3-15)

                                                                                                         (3-16)

其中,关于激活函数求偏导,需要根据具体的激活函数而定,每一层的激活函数可以选择不同的函数,一般情况下,为简单化模型设计和求导方便,会设定为同一个函数。此处假设选择激活函数为sigmoid函数,那么有:  


                                 (3-17)

PS:因为sigmoid(z)中z是标量,对z求偏导,有:



本文定义了z为向量,对于向量就有了式(3-17)的逐元素相乘的式子。

于是,为简化后面的计算,记

                                                                                   (3-18)

其中,表示第k次求损失函数关于的偏导;表示逐元素相乘,即两个向量或两个矩阵对应的元素相乘,例如:     


于是,输出单元的误差项为:

                                                                                                                (3-19)

                                                                                              (3-20)

此处说明:若遇式(3-15)的偏导(对权值求偏导),链式法则处理方式均如式(3-19);若遇式(3-16)的偏导(对偏置项求偏导),链式法则处理方式均如式(3-20)。

隐藏单元的误差项:隐藏单元w与损失函数E,通过复合函数的形式关联,以设定的模型整理为:

         

                          (3-21)

根据链式法则,隐藏单元w与损失函数E的误差项为:

                                              

                                                                      (3-22)

同样的求导法则,得到隐藏单元的误差项为:

                                                                  (3-23)

                   (3-24)

     其中:

                                                                                                     (3-25)

                                                                             (3-26)

                                                                                                         (3-27)

                                                                                              (3-28)

       说明:若遇式(3-25)(对隐藏单元求偏导),链式法则处理如式(3-23);式(3-15)和(3-26)同,故有相同的处理方式;式(3-16)和(3-27)同,故有相同的处理方式。

       补充:若有多个隐藏层时,逐步计算隐藏层的权值和偏置项误差,推导的规则同上。例如:一个隐藏层为2,隐藏单元为5的神经网络:


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_51

输出层到隐藏层2的误差项同式(3-19)

隐藏层2到隐藏层1的误差项为:

                                                                        (3-29)

记:                           

                                                                                                      (3-30)

隐藏层1到输入层的误差项为:

                                                                       (3-31)

从上述中,容易看出,无论多少层隐藏层,其误差项都是同样的结构。

     步骤4) 更新神经网路中的权值和偏置项。学习率自己设定,学习率太大,容易跳过最佳的参数;学习率太小,容易陷入局部极小值。

     步骤5) 设定阈值e或者设定迭代次数,当损失函数值小于阈值e时,或当迭代次数用完时,输出最终参数。

4、实例运用

     为能更好理解BP算法和知道如何运用BP算法,下面以一个实际的例子来说明运用BP算法的具体操作。

有一组数据,目的是训练这两组数据,找到输入X计算得到Y的预测值尽可能接近于真实值的参数。设定模型:设计一个隐藏层为1,隐藏单元数为2,激活函数为sigmod函数的模型,运用反向传播算法,得到参数。网络如图5:


基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_53

于是有:




                                                                                              (4-1)

式(4-1)中,x表示net1后的h。

根据BP算法步骤:

  1)初始化网络中的所有参数并给出学习率:


   2)激活前向传播,将参数带入式(4-1),并计算损失函数:

        输入层-->隐藏层:

                                                                        (4-2)

                                                                            (4-3)

        隐藏层-->输出层:

                                                           (4-4)

                                           (上式中x表示4-3中的h)

                                                                     (4-5)

        损失函数:

                                                                                (4-6)

  3)计算输出单元的误差项和隐藏单元的误差项

      输出单元的误差项:根据公式(3-19),将带入其中,得到需更新的梯度误差:




      如果对v中每一个元素求偏导,有:






    用公式(3-19)和对v中每一个元素求偏导,得到的结果一致。

    隐藏单元的误差项:根据公式(3-23),将带入其中,得到需更新的梯度误差





       若对w中每一个元素求偏导,有:






       用公式(3-23)和对v中每一个元素求偏导,得到的结果一致。

  注意:一般情况下,不会对偏置项更新

  4)更新神经网络中的权值





      于是,得到第一次更新的参数值w,v。

  5)重复步骤2-4,直到损失值达到了预先设定的阈值或迭代次数用完,得到最终的权值。

       以上即为BP算法的更新权值的过程,下面将上述实例的推导过程用代码实现:

1.2 帝企鹅算法


 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_85



2 部分代码



%% 2021.9.2  AFO 算法优化神经网络
% 2021.9.2 AFO algorithm optimizes neural network weights and thresholds
%% 这是使用原始算法的直接求解结果,添加专用于本问题的更新方式可以进一步提高精度
% This is the direct result of using the original algorithm,
% adding some specific update methods to this problem can further improve the accuracy
clc;
clear;
close all;
warning off
%% 固定随机数种子
noRNG=1;
rng('default')
rng(noRNG)
%% 载入数据
%% 数据预处理
load input
load output
%%
data.x=[input'];
data.y=[output];
num_Train=120; %训练集数量
data.len_train=num_Train;
num_Test=48; %测试集数量
index=randperm(num_Train+num_Test); %随机乱序
data.train_x=data.x(:,index(1:num_Train))';
data.train_y=data.y(:,index(1:num_Train))';
data.test_x=data.x(:,index(num_Train+1:end))';
data.test_y=data.y(:,index(num_Train+1:end))';
% 归一化
[data.train_x0,option.ps_x]=mapminmax(data.train_x');
data.train_x0=data.train_x0';
[data.train_y0,option.ps_y]=mapminmax(data.train_y');
data.train_y0=data.train_y0';
data.test_x0 = mapminmax('apply',data.test_x',option.ps_x);
data.test_x0=data.test_x0';
data.test_y0 = mapminmax('apply',data.test_y',option.ps_y);
data.test_y0=data.test_y0';
%%
data.weight=1;
data=data;
data.hiddenumber= [5];%隐含神经元数

%% 未优化神经网络
clear result
[x(1,:),result(1)]=creat_x_1(option,data);
%draw(result(1),'未优化')
data.m=result(1).m;
data.n=result(1).n;
data.m_lw=result(1).m_lw;
data.n_lw=result(1).n_lw;
data.m_iw=result(1).m_iw;
data.n_iw=result(1).n_iw;
data.m_b=result(1).m_b;
data.n_b=result(1).n_b;
data.len=result(1).len;
[y(1),result(1)]=aimFcn_1(x(1,:),option,data,result(1).net);
%% 参数设置
lb=-5;
ub=5;
option.lb=lb;
option.ub=ub;
dim=length(x(1,:));
%%
option.dim=dim; %八个决策变量
lb=0;
ub=1;
option.lb=lb;
option.ub=ub;
if length(option.lb)==1
option.lb=ones(1,option.dim)*option.lb;
option.ub=ones(1,option.dim)*option.ub;
end
option.fobj=@aimFcn_1;
%option.fobj0=option.fobj;
option.showIter=0;
%% 算法参数设置 Parameters
% 基本参数
option.numAgent=10; %种群个体数 size of population
option.maxIteration=100; %最大迭代次数 maximum number of interation
% 帝企鹅算法
option.v_lb=-(option.ub-option.lb)/4;
option.v_ub=(option.ub-option.lb)/4;
option.w2=0.5; %weight of Moving strategy III
option.w4=1;%weight of Moving strategy III
option.w5=1;%weight of Moving strategy III
option.pe=0.01; % rate to judge Premature convergence
option.gap0=ceil(sqrt(option.maxIteration*2))+1;
option.gapMin=5; % min gap
option.dec=2; % dec of gap
option.L=10; % Catastrophe
str_legend=[{'AFO1'},{'AFO2'}];
%% Initialize population individuals (common to control experiment algorithm)
%% 初始种群生成
x=ones(option.numAgent,option.dim);
y=ones(option.numAgent,1);
for i=1:option.numAgent
[x(i,:),result(i,1)]=creat_x_1(option,data);
[y(i,1),result(i,1)]=aimFcn_1(x(i,:),option,data,result(i).net);
end
%% 使用算法求解
% Based on the same population, solve the selected functions by using different algorithms
bestX=x;
rng(noRNG)
tic
[bestY(1,:),bestX(1,:),best_result1,recording(1)]=AFO1(x,y,result,option,data);
tt(1,1)=toc;
%%
figure
hold on
for i=1:length(recording)
plot((recording(i).bestFit),'LineWidth',2)
end
legend(str_legend)
title('fitness curve')
%% 未优化神经网络
rng(7)
[x(1,:),result(1)]=creat_x_1(option,data);
[y(1),result(1)]=aimFcn_1(x(1,:),option,data,result(1).net);

%%
figure
hold on
plot(result(1).ygabptest(i,:));
plot(best_result1.ygabptest(i,:));
plot(data.test_y(:,i));
legend(['未优化神经网络(mse=',num2str(result(1).mse(i)),')'],['AFO优化神经网络(mse=',num2str(best_result1.mse(i)),')'],['真实数据'])

3 仿真结果

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_88


4 参考文献

[1]李旭飞,王贞.求解约束优化问题的改进帝企鹅优化算法[J].计算机工程与设计,2021,42(03):703-710.

5 代码下载


 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_89

4 参考文献

[1]李旭飞,王贞.求解约束优化问题的改进帝企鹅优化算法[J].计算机工程与设计,2021,42(03):703-710.

5 代码下载


束优化问题的改进帝企鹅优化算法[J].计算机工程与设计,2021,42(03):703-710.

5 代码下载


,得到第一次更新的参数值w,v。

  5)重复步骤2-4,直到损失值达到了预先设定的阈值或迭代次数用完,得到最终的权值。

       以上即为BP算法的更新权值的过程,下面将上述实例的推导过程用代码实现:

1.2 帝企鹅算法

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_84

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_85

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_86

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_神经网络_87

2 部分代码



%% 2021.9.2  AFO 算法优化神经网络
% 2021.9.2 AFO algorithm optimizes neural network weights and thresholds
%% 这是使用原始算法的直接求解结果,添加专用于本问题的更新方式可以进一步提高精度
% This is the direct result of using the original algorithm,
% adding some specific update methods to this problem can further improve the accuracy
clc;
clear;
close all;
warning off
%% 固定随机数种子
noRNG=1;
rng('default')
rng(noRNG)
%% 载入数据
%% 数据预处理
load input
load output
%%
data.x=[input'];
data.y=[output];
num_Train=120; %训练集数量
data.len_train=num_Train;
num_Test=48; %测试集数量
index=randperm(num_Train+num_Test); %随机乱序
data.train_x=data.x(:,index(1:num_Train))';
data.train_y=data.y(:,index(1:num_Train))';
data.test_x=data.x(:,index(num_Train+1:end))';
data.test_y=data.y(:,index(num_Train+1:end))';
% 归一化
[data.train_x0,option.ps_x]=mapminmax(data.train_x');
data.train_x0=data.train_x0';
[data.train_y0,option.ps_y]=mapminmax(data.train_y');
data.train_y0=data.train_y0';
data.test_x0 = mapminmax('apply',data.test_x',option.ps_x);
data.test_x0=data.test_x0';
data.test_y0 = mapminmax('apply',data.test_y',option.ps_y);
data.test_y0=data.test_y0';
%%
data.weight=1;
data=data;
data.hiddenumber= [5];%隐含神经元数

%% 未优化神经网络
clear result
[x(1,:),result(1)]=creat_x_1(option,data);
%draw(result(1),'未优化')
data.m=result(1).m;
data.n=result(1).n;
data.m_lw=result(1).m_lw;
data.n_lw=result(1).n_lw;
data.m_iw=result(1).m_iw;
data.n_iw=result(1).n_iw;
data.m_b=result(1).m_b;
data.n_b=result(1).n_b;
data.len=result(1).len;
[y(1),result(1)]=aimFcn_1(x(1,:),option,data,result(1).net);
%% 参数设置
lb=-5;
ub=5;
option.lb=lb;
option.ub=ub;
dim=length(x(1,:));
%%
option.dim=dim; %八个决策变量
lb=0;
ub=1;
option.lb=lb;
option.ub=ub;
if length(option.lb)==1
option.lb=ones(1,option.dim)*option.lb;
option.ub=ones(1,option.dim)*option.ub;
end
option.fobj=@aimFcn_1;
%option.fobj0=option.fobj;
option.showIter=0;
%% 算法参数设置 Parameters
% 基本参数
option.numAgent=10; %种群个体数 size of population
option.maxIteration=100; %最大迭代次数 maximum number of interation
% 帝企鹅算法
option.v_lb=-(option.ub-option.lb)/4;
option.v_ub=(option.ub-option.lb)/4;
option.w2=0.5; %weight of Moving strategy III
option.w4=1;%weight of Moving strategy III
option.w5=1;%weight of Moving strategy III
option.pe=0.01; % rate to judge Premature convergence
option.gap0=ceil(sqrt(option.maxIteration*2))+1;
option.gapMin=5; % min gap
option.dec=2; % dec of gap
option.L=10; % Catastrophe
str_legend=[{'AFO1'},{'AFO2'}];
%% Initialize population individuals (common to control experiment algorithm)
%% 初始种群生成
x=ones(option.numAgent,option.dim);
y=ones(option.numAgent,1);
for i=1:option.numAgent
[x(i,:),result(i,1)]=creat_x_1(option,data);
[y(i,1),result(i,1)]=aimFcn_1(x(i,:),option,data,result(i).net);
end
%% 使用算法求解
% Based on the same population, solve the selected functions by using different algorithms
bestX=x;
rng(noRNG)
tic
[bestY(1,:),bestX(1,:),best_result1,recording(1)]=AFO1(x,y,result,option,data);
tt(1,1)=toc;
%%
figure
hold on
for i=1:length(recording)
plot((recording(i).bestFit),'LineWidth',2)
end
legend(str_legend)
title('fitness curve')
%% 未优化神经网络
rng(7)
[x(1,:),result(1)]=creat_x_1(option,data);
[y(1),result(1)]=aimFcn_1(x(1,:),option,data,result(1).net);

%%
figure
hold on
plot(result(1).ygabptest(i,:));
plot(best_result1.ygabptest(i,:));
plot(data.test_y(:,i));
legend(['未优化神经网络(mse=',num2str(result(1).mse(i)),')'],['AFO优化神经网络(mse=',num2str(best_result1.mse(i)),')'],['真实数据'])

3 仿真结果

基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_损失函数_88

 基于帝企鹅算法优化BP神经网络实现数据预测matlab代码_权值_89

4 参考文献

[1]李旭飞,王贞.求解约束优化问题的改进帝企鹅优化算法[J].计算机工程与设计,2021,42(03):703-710.

5 代码下载