加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

[bigdata-126] 一般形式的反向传导算法BP最简推导-3

发布时间:2020-12-14 04:57:56 所属栏目:大数据 来源:网络整理
导读:前述两篇推导还是太繁琐了,有一种更简单的方式。因为排版的问题,直接贴图。 根据上述公式,可以实现一个简单的验证性python代码 #!/usr/bin/env python#!-*- coding:utf-8 -*-#bp alogrithmimport mathimport numpy as np#active functiondef f(x): return

前述两篇推导还是太繁琐了,有一种更简单的方式。因为排版的问题,直接贴图。







根据上述公式,可以实现一个简单的验证性python代码

#!/usr/bin/env python
#!-*- coding:utf-8 -*-

#bp alogrithm

import math
import numpy as np

#active function
def f(x):
    return 1.0/(1+math.exp(-x))

#应激函数的一阶导数
def d_f(x):
    return f(x)*(1-f(x))

#神经网络层数
p=3
#神经网络每层的神经元数量,第一个值是None,是为了脚标从1开始
d = [None,2,3,1]

#有一个None,是为了脚标从1开始
#权重矩阵
W = [None]
#bias
b = [None]

#z^l_{j,i}
z = [None]
#a^l_{j,i}
a = [None]
#a一阶偏导
del_a = [None]

for i in range(1,p):
    #随机初始化权重矩阵
    W.append(np.array(0.01*np.random.rand(d[i+1],d[i])))
    #随机初始化bias
    b.append(np.array(0.01*np.random.rand(1,1)))

for i in range(1,p+1):
    #初始化z值
    z.append(np.zeros((d[i],1),np.float64))
    #初始化a值
    a.append(np.zeros((d[i],np.float64))
    #初始化a的一阶偏导
    del_a.append(np.zeros((d[i],np.float64))

#样本
x = np.array([0.0,1.0],np.float64).reshape((2,1))
y = np.array([1.0],np.float64)
#学习速率
eta = 0.1;

###开始计算
n = 1
#最大迭代次数
max_iter = 200

#将输入层设置为样本x
a[1]=x

#循环计算
while n <= max_iter:
    print('第'+str(n)+'迭代'+'-'*20)

    #计算z^l_{j,i}和z^l_{j,i}
    for l in range(2,p+1):
        print('*'*5)
        print(' ' * 2,'计算z[' + str(l) + ']')
        print(' ' * 4,'a['+str(l-1)+']=',a[l-1])
        print(' ' * 4,'W['+str(l-1)+']=',W[l-1])
        print(' ' * 4,'b['+str(l-1)+']=',b[l-1])
        z[l] = np.dot(W[l-1],a[l-1])+b[l-1]
        print(' ' * 4,'z['+str(l)+']=',z[l])

        print(' '*2,'计算a['+str(l)+']')
        for i in range(d[l]):
            a[l][i,0] = f(z[l][i,0])
        print(' ' * 4,'a['+str(l)+']=',a[l])
    print(' ' * 2,'计算a和z结束')

    #计算frac{partial J}{partial a^l_{j,i}}
    print('*'*5)
    print(' '*2,'计算del_a')
    #第p层需要单独计算
    for i in range(d[p]):
        del_a[p][i] = -(y[i]-a[p][i,0])
    print(' '*4,'del_a['+str(p)+']=',del_a[p])
    #第i层
    print(' '*4,'**')
    for i in range(p-1,-1):
        #第i层的第j个神经元
        for j in range(d[i]):
            #先将其值置0
            del_a[i][j,0] = 0
            #然后求和
            for k in range(d[i+1]):
                del_a[i][j,0] += W[i][k,j]*d_f(z[i+1][k,0])*del_a[i+1][k][0]
        print(' ' * 4,'del_a[' + str(i) + ']=',del_a[i])

    #计算新的W_l_{j,i}
    #第l层
    for l in range(p-1,-1):
        #第l层第i个神经元
        print('W['+str(l)+']=',W[l])
        print('b['+str(l)+']=',b[l])
        for i in range(d[l]):
            for j in range(d[l+1]):
                W[l][j,i] -= eta*del_a[l+1][j]*d_f(z[l+1][j,0])*a[l][i,0]
                b[l] -= eta*del_a[l+1][j]*d_f(z[l+1][j,0])
        print('new W[' + str(l) + ']=',W[l])
        print('new b[' + str(l) + ']=',b[l])
    n += 1


latex的文档

documentclass[a4paper,12pt]{article}
usepackage{CJK}

%define the tile
title{BackPropagation Alogrithom}

usepackage{graphicx}
usepackage{pythonhighlight}

begin{document}

begin{CJK}{UTF8}{gkai}

%generates the title
maketitle

section{前馈神经网络}
前馈神经网络:设神经网络的层数是$p$,各层分别记为$L^1,L^2,...,L^p$,每层的神经元数量记为$d^1,d^2,d^p$,每个神经元的应激函数记为$f(x)$。

训练集是${(mathbf{x}^k,mathbf{y}^k) } k=1,m$,显而易见,$mathbf{x^k} in R^{d^1times 1}$,$mathbf{y^k} in R^{d^ptimes 1}$,$mathbf{x}^k$是一维列向量且元素个数跟神经网络输入层的神经元数量相同,同理$mathbf{y}^k$是一维列向量且元素个数跟神经网络输出层神经元数量相同。


为推导方便,设$(mathbf{x},mathbf{y})$是一组样本。根据神经网络的定义,在第$l$层,第$i$个神经元的输入值记为$z^l_i$,输出值记为$a^l_i$,有如下关系:
begin{eqnarray*}
a^l_i &=& f(z^l_i)
z^{l+1}_j &=& sum_{i=1}^{d^l}mathbf{W}^{l}_{j,i}a^l_i+ mathbf b^l
end{eqnarray*}
上述两式,定义了神经网络的计算方式。其中,$mathbf{W}^l$是第$l$层和第$l+1$层之间的权重矩阵,$mathbf{W}^l_{j,i}$是第$l$层的第$i$个神经元的与第$l+1$层的第$j$个神经元的权重系数,$mathbf b^l$是第$l$层的bias。对于输入层,可以视为$a^1_i=mathbf{x}_i$,也就是说,输入层的第$i$个输出值是样本$mathbf x$的第$i$个元素。

神经网络对$(mathbf{x},mathbf{y})$拟合误差的代价函数如下:
begin{eqnarray*}
J(mathbf{W},mathbf{b};mathbf{x},mathbf{y})&=&frac{1}{2}sum_{q=1}^{d^p}(mathbf{y}_q-a^p_q)^2
&=&frac{1}{2}sum_{q=1}^{D}(mathbf{y}_q-a^p_q)^2
&=&frac{1}{2}sum_{q=1}^{D}(mathbf{y}_q-f(z^p_q))^2
end{eqnarray*}
其中,$D=d^p$,代价函数的形式在求解中不会变动,因此用$D$以避免计算中的误解,$mathbf{y}_q$是$mathbf{y}$的第$q$个元素,后文$J(mathbf{W},mathbf{y})$将简写为$J$。


section{权重系数和偏差的一阶偏导求解}

前馈神经网络的输出,是样本值进入输入层,从前向后,逐层计算。BP算法求解优化问题,让拟合误差从后向前,从输出层逐层传递到隐层和输入层,由此优化所有权重系数,由此得名BackPropagation反向传播。BP算法的求解推导,本质就是推导相邻两层之间的关系。

$J$对$mathbf b^l$的一阶偏导通式:
begin{eqnarray*}
frac{partial J}{partial mathbf b^l} 
&=& sum_{j=1}^{d^{l+1}} frac{partial{J}}{partial a^{l+1}_j}frac{partial a^{l+1}_j}{partial z^{l+1}_j}frac{partial z^{l+1}_j}{partial mathbf b^l}
&=& sum_{j=1}^{d^{l+1}}  frac{partial{J}}{partial a^{l+1}_j}frac{partial a^{l+1}_j}{partial z^{l+1}_j}
&=& sum_{j=1}^{d^{l+1}}  frac{partial{J}}{partial a^{l+1}_j}f^{'}(z^{l+1}_j)
end{eqnarray*}

$J$对$mathbf{W}^l_{j,i}$的一阶偏导通式:
begin{eqnarray*}
frac{partial{J}}{partial mathbf{W}^l_{j,i}}
&=&frac{partial{J}}{partial a^{l+1}_j}frac{partial a^{l+1}_j}{partial z^{l+1}_j}frac{partial z^{l+1}_j}{partial mathbf{W}^{l}_{j,i}}
&=&frac{partial{J}}{partial a^{l+1}_j}frac{partial a^{l+1}_j}{partial z^{l+1}_j}a^{l}_{j,i}
&=&frac{partial{J}}{partial a^{l+1}_j}f^{'}(z^{l+1}_j)a^{l}_{i}
end{eqnarray*}

上式的$frac{partial{J}}{partial a^{l+1}_j}$,也可以通过反向传播的方式求解,其通式$frac{partial{J}}{partial a^{l}_j}(l< p)$求解如下:
begin{eqnarray*}
frac{partial{J}}{partial {a}^l_{j}}
&=&sum_{r=1}^{d^{l+1}}frac{partial J}{partial a^{l+1}_r} frac{partial a^{l+1}_r}{partial z^{l+1}_r}frac{partial z^{l+1}_r}{partial a^l_j}
&=& sum_{r=1}^{d^{l+1}} frac{partial J}{partial a^{l+1}_r} frac{partial a^{l+1}_r}{partial z^{l+1}_r}mathbf{W}^{l}_{r,j}
&=& sum_{r=1}^{d^{l+1}} frac{partial J}{partial a^{l+1}_r} f^{'}(z^{l+1}_r)mathbf{W}^{l}_{r,j}
end{eqnarray*}

newpage

以梯度下降法优化$mathbf{W}^l_{j,i}$和$mathbf b^l$,$eta$是学习速率,公式如下:
begin{eqnarray*}
mathbf{W}^l_{j,i} &=& mathbf{W}^l_{j,i} - eta frac{partial J}{partial mathbf{W}^l_{j,i}}
mathbf{b}^l &=& mathbf{b}^l - eta frac{partial J}{partial mathbf{b}^l}
end{eqnarray*}



section{反向传播计算步骤}
步骤如下:

1.以极小随机值对$mathbf W$和$mathbf b$进行初始化。

2.样本$(mathbf x,mathbf y)$前向传播计算输出值。

3.计算$frac{partial J}{partial a^p_{r}}$,也就是$frac{partial J}{partial a^p_{r}}=-(y_r-a^p_r)$。

4.根据上面推导的公式,从后往前计算所有的$frac{partial{J}}{partial a^{l}_j}$。

5.根据上面推导的公式,从后往前计算所有的$frac{partial{J}}{partial mathbf{W}^l_{j,i}}$。

6.根据上面推导的公式,从后往前计算所有的$frac{partial{J}}{partial mathbf{b}^l}$。

7.更新所有的$mathbf W^l_{j,i}$和$mathbf b^l$。

8.重复步骤2至7,直至终止条件达成。

section{推广到多样本和正则化情况}
对样本集而言,考虑正则化,代价函数如下:
begin{eqnarray*}
mathbf J(mathbf{W},mathbf{b};mathbf{X},mathbf{Y})
&=&sum_{k=1}^{m}J(mathbf{W},mathbf{b}; mathbf x_k,mathbf y_k)+ frac{lambda}{2}  sum_{l=1}^{p-1} sum_{j=1}^{d^{l+1}} sum_{i=1}^{d^{l}} (W^l_{j,i})^2
end{eqnarray*}

对$W^l_{j,i}$求一阶偏导:
begin{eqnarray*}
frac{mathbf J(mathbf{W},mathbf{Y})}{partial W^l_{j,i}} 
&=&sum_{k=1}^{m}frac{partial J_k}{partial W^l_{j,i}}+ lambda W^l_{j,i}
end{eqnarray*}

从本质上来说,等价于所有样本的一阶偏导之和再加上一个系数。


end{CJK}
end{document}

grid

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读