BP——反向传播算法公式推导及代码

BP——反向传播算法计算过程详解人工神经网络的结构前向传播激活函数反向传播梯度下降具体计算过程本文主要参考吴恩达和李宏毅的深度学习视频,然后自己做的笔记反向传播计算部分参考李宏毅的视频讲解,要是有童鞋也对反向传播这一部分的计算不那么清明,可以考虑选择留下来看看我的笔记,也可以移步李宏毅大神的视频讲解人工神经网络的结构(注:Markdown敲公式对我来说太困难,后面的公式都用图片的形式展...
摘要由CSDN通过智能技术生成

本文主要参考吴恩达和李宏毅的深度学习视频,然后自己做的笔记
反向传播计算部分参考李宏毅的视频讲解,要是有童鞋也对反向传播这一部分的计算不那么清明,可以考虑选择留下来看看我的笔记,也可以移步李宏毅大神的视频讲解

人工神经网络的结构

(注:Markdown敲公式对我来说太困难,后面的公式都用图片的形式展示)
神经网络的结构包括:输入层(input layer)、隐藏层(hidden layer)、输出层(output layer)。如下图所示:
神经网络结构
当然,隐含层可以有无数层,这里我只画了两层。
输入层输入的数据是训练样本(x1,x2,…,xn,y),训练样本中的x1到xn表示输入的特征值,而y则表示咱们希望输出的预期值。
隐含层将会进行一系列的计算来缩小训练样本的估计值y’与预期值y之间的误差。
输出层则会输出训练后得到的估计值y’。

前向传播

为了后面的表示方便,我们这里先约定一下每个神经元的表示方法。
aj[l][i]:第i个样本的第l层上第j个神经元的输入,且有 a[0] = x 。
z:中间变量
J:代价函数
g():激活函数

前向传播主要完成两个任务:

  1. 计算每一个神经元的激活值a;
  2. 是计算最后的代价函数J(y’, y)(如果我们这里只有一个输入样本的话,那么应该叫做损失函数)。

即将用到的公式有(这里就以上面给出的人工神经网络结构为例子,即一个样本的表示形式):
在这里插入图片描述
我们定义
前向传播的计算流程:

  1. 输入的准备工作:a[0]、w[1]、b[1]都排排坐,下面准备吃果果啦~
    在这里插入图片描述
  2. 求出a[1]
    在这里插入图片描述
    根据【人工神经网络结构图】可知,咱们的三个输入都连接到了三个神经元上,每个神经元都要有一个输出,因此咱们最后求得的a[1]也是一个3*1的向量。

咱们将上面的式子扔到神经网络中表示:
前向传播计算流程
看到没有,每一个神经元都要进行一次z和a的计算,一直传到输出层,输出层求得的a就是咱们样本的估计值!

在python中表示求解z、a的式子为:

z = np.dot(w.T, x)+b
a = sigmoid(z)    #这里我采用sigmoid()函数作为激活函数,这个函数主要是用来作二分类
  1. 损失函数J(y’, y)在python中的表示:

损失函数:求解单个样本的误差
代价函数:求解多个样本的误差

cost = -y * np.log(y') - (1 - y) * np.log(1 - y')   #这里只是单个样本的损失函数,如果咱们有m个样本的话就需要将这m个样本的损失值全部加起来再除以m求得这m个样本的代价函数。

激活函数

激活函数的作用:加入非线性因素,解决线性不可分问题。(比如说,现在给你一个得用歪七扭八的线来划分两个区域,你用直线肯定是不可能把他俩完美的分开的,但是加入非线性因素以后,你就可以拟合出一条近乎完美的线来划分这两个区域啦~)

激活函数有很多种,咱在上面使用的是用于二分类的一种常用的激活函数,一般用在输出层。(不同层可以使用不同的激活函数,还有一点很重要的是:激活函数得是可微的!因为咱们在反向传播阶段得对激活函数求导!)

各种激活函数详情请咨询:千奇百怪的激活函数 来源:wikipedia

反向传播

老规矩,先约定一波:
dw: J对w求偏导
db: J对b求偏导
dz: J对z求偏导
da: J对a求偏导

步骤:

  1. 求解dw, db
  2. 更新w, b

方法:梯度下降
小工具:链式求导

咱们在计算时一定一定会用到的四个公式:
反向传播必备公式
现在看不太明白这几个公式没有关系,咱们先往后走,看看具体是怎么计算的,一会再看这些公式心就明朗啦~ 加油加油,马上就完了!

梯度下降

咱们要清楚,方向传播的目的就是为了找到一个最好的w和b,让咱们的损失达到最小,让咱们的结果无限逼近最优解。那么为了让咱们这个值达到最优,咱们就要采用梯度下降的方法来不断优化这个值。当然,学习率的选择也是非常重要的。不然就可能出现两种不太招人待见的情况:1.要训练贼多次才能到达最优解;2.始终到不了最优解。
梯度下降
箭头所指的方向就是梯度下降的方向。

具体计算过程

step1. 计算隐藏层误差(这里以第一个神经元为例)
思路:要求解dw[1]和db[1],先要求解出dz[1],要求dz[1],那么先要知道da[1]。因此咱们求解的过程就是da—>dz—>dw,db
过程如下:
计算隐藏层误差
可以看到上面的求解过程就是一个链式求导过程。一层一层的剥开,一层一层的求解。

step2. 计算输出层误差
输出层误差的求解过程中间只有一个da[L]这个中间变量。这个就留给大家自己写啦!(其实我最开始的地方都已经给出了)

step3. 咱们都知道每一层的dw和db是如何得到的了,现在要做的就是更新w和b了!还是用上面更新的那个公式来求解!这里我也不重复写了~

完结了~
咱们在实现过程中实际上也是不断迭代求解w和b来训练整个网络结构,使得整个网络的损失达到最小!

下面是大家最喜欢的部分!不贴代码的博客不是好博客!

import math
import random
import string

random.seed(0)


# calculate a random number where:  a <= rand < b
def rand(a, b):
    return (b - a) * random.random() + a


# Make a matrix (we could use NumPy to speed this up)
def makeMatrix(I, J, fill=0.0):
    m = []
    for i in range(I):
        m.append([fill] * J)
    return m


  • 66
    点赞
  • 283
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值