小白也能看懂的BP反向传播算法之Towards-Backpropagation

本文相关代码可以从Backpropagation下载

想要理解backpropagation反向传播算法,就必须先理解微分!本文会以一个简单的神经元的例子来讲解backpropagation反向传播算法中的微分的概念。

image.png

这是一个非常简单的神经元,如图所示,接收两个输入a, b,然后在神经元内部对两个神经元进行相乘操作,得到a*b的输出!

然后,我们可以想象这样一个情景,现在对于某个特定的输入a,b,输出结果与预期结果相比较小,为了提高准确率,那我们就要将输出结果增加,以更符合预期的结果!

所以,我们现在的目标就是通过改变a,b的值来增加神经元的输出!

Method 1

第一个方法是很直观的,我们就随机的给输入a,b的两个值添加一个随机值,然后用一个步长step来控制增加的程度,用python代码实现:

import random


def product(a, b):
    return a * b


def methodOne():
    a = 5
    b = 6
    step = 0.01
    a = a + step * (random.random())
    b = b + step * (random.random())
    print(product(a, b))

methodOne()

运行程序,我们可以得到输出30.04698146865633(由于涉及到随机数,所以读者的运行结果会和此处有区别,但一定会是比30大的数),是比原本的输出30增加了相应值的,说明我们的目标实现了!但是如果我们继续测试,就会发现程序是存在问题的:

  • 不可靠!如果我们改变输入值,会发现有时候值会增加,有时候又会减少!,比如以下这个例子:
def testTwo():
    a = -5
    b = -6
    step = 0.01
    a = a + step * (random.random())
    b = b + step * (random.random())
    print(product(a, b))

testTwo()

运行程序,我们会得到结果29.970177554213326,是比原本的输出30小的。只因为我们将输入值a,b变为了负数,这个算法就失效了!究其原因,因为我们对于不同的输入值,变化的都是random()函数,也就是一个在(0,1)之间的正数。而对于负数的输入,增加一个正数,最后反而导致绝对值减小,也就导致输出的结果变小了!

所以,通过以上这个例子,我们可以得出结论: 对于 a = a + step * (random.random())中step后面所乘的系数,我们不能一概而论,而是应该更多的控制它的值,也就是根据不同的输入值来控制,也就是说,step所乘的系数,也就是输入值的变化应该是一个关于输入值的函数

Method 2

Method 1中的结论是,我们应该有一个step乘以的应该是一个关于输入值的函数。也就是我们需要知道在输入值那个点上,输出结果关于输入值的一个变化率,如果在这个点上,输出结果是随着输入值增加而增加,那么step乘以一个正数即可,反之,则需要乘以一个负数才能使输出结果增加!显然这就是函数在某点上的微分的定义!

首先我们将神经元内部的函数写出来

image.png

神经元输出是一个关于输入的函数!然后我们将输入值a增加一个h

image.png

此时新的输出值就变成 (a+h)*b,展开就是a*b+h*b,所以我们可以看到此时输出值相对于原有的输出值的变化就是h*b,只要我们保证h*b是正值,就是说可以保证是输出结果增加,而保证正值的方法自然就是h和b同号!更深入的理解,我们将a的值增加h,最后导致输出结果,也就是 函数f的值增加h*b,这时候就可以理解b为函数f在点(a,b)处关于a的变化率!这就是微分的概念了,如果读者有微积分基础,会发现这里实际上f就是一个二元函数的微分,b就是函数f在点(a,b)的微分!微分的实质就是函数在某点的变化率,如果是多元函数就是函数在某点关于某个变量的变化率!多元函数对某一个变量微分时候,通常会将其他变量看作常量!

image.png

以上公式就是微分的计算方法!

但实际上,学过微积分,都应该掌握了一套微分的基本法则,我们往往可以根据这套法则,直接写出函数的微分!可以参考Derivative-rules 对于我们这里的函数f,我们可以直接写出关于a的微分

image.png

自然,关于b的微分就是

image.png

求出了微分,就相当于知道了变量在某点的变化率,那么很自然,a,b的更新规则就是

image.png

def methodTwo(a, b):
    step = 0.01
    a = a + step * b
    b = b + step * a
    print(product(a, b))

methodTwo(5, 6)
methodTwo(-5, -6)

我们发现输出结果30.616035999999998和30.616035999999998,不管输入的值是正是负,都成功将输出结果增加了!而正是利用了微分的概念才能做到,微分实际上就是梯度,梯度就指明了函数上升最快的方向!读者可以参考笔者相关梯度下降的文章梯度下降

最后我们来详细分析一下,为什么利用微分更新输入可以做到?

我们深入分析微分几何意义!一个函数对某个变量的微分实际上就是函数在关于这个变量的变化率,变化率的方向是正的,也就是说的变化率,指的是增加的变化率!我们看看我们输入的更新方程

image.png

多元函数的微分关于某个变量的微分的意义就是,就是将其他变量全部看成常量,函数关于此变量的变化率,变化率的方向是正的,也就是说上升的方向,如果想要知道下降的变化率,即是负微分

我们再举一个单变量函数的例子来分析一下如何利用微分更新变量值

image.png

我们看到上面这个函数关于x先上升,再下降!我们假设两个场景

场景1:

首先,想象我们现在处于A点,我们想要改变变量x的值,从而使函数y的值增加。从图中我们可以清晰的看出,我们只要直接增加x的值,就可以增加函数值。然后结合微分,我们的更新方法就是

image.png

场景2:

现在想象我们在C点,也要改变x的值让函数值y增加,这时候我们从图像中可以看到,我们减少x的值,就可以增加函数值!而这正是由函数的微分决定的。我们求取函数关于x在此点的微分,会发现微分是负值,所以我们依然利用场景1中的更新公式,也可以达到增加函数值的目的。

微分会反映函数的变化趋势,如果我们想要让函数值增加,微分会告诉我们一个正确的更新变量的方向

场景3:

想象我们此时处于B的左侧,但是非常接近B点!从图像中,我们也会知道此时微分的是正的,也就是我们增加x的值就能使函数值y的值增加!但要注意的一点是,如果我们的step也就是步长如果过大,会导致跑到右边去了,可能还会导致函数值的下降!所以我们就要调整步长!这其实就是一个梯度上升的问题,与梯度下降类似,读者有兴趣可以参考笔者相关文章梯度下降

我会在这里结束本文的介绍!希望通过本文读者能对微分有一个理解,同时知道如何将微分利用到更新变量值中,从而改变函数值!

下一篇文章小白也能看懂的BP反向传播算法之Into-Backpropagation我会将这个利用微分更新变量的方法,应用到多个神经元的场景中,慢慢读者就会接触到真正的backpropagation反向传播算法

本文相关代码可以从Backpropagation下载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Hadoop数据仓库

HAWQ + MADlib 玩转数据挖掘之(十一)——分类方法之决策树

一、分类方法简介 1. 分类的概念         数据挖掘中分类的目的是学会一个分类函数或分类模型(也常常被称作分类器),该模型能把数据库中的数据项映射到给定...

32610
来自专栏人工智能LeadAI

基于Spark /Tensorflow使用CNN处理NLP的尝试

01 前言 关于CNN如何和NLP结合,其实是被这篇文章(http://www.wildml.com/2015/11/understanding-convolu...

3876
来自专栏深度学习之tensorflow实战篇

数据预处理—剔除异常值,平滑处理,标准化(归一化)

数据预处理的主要任务如下: (1)数据清理:填写空缺值,平滑噪声数据,识别,删除孤立点,解决不一致性 (2)数据集成:集成多个数据库,数据立方体,文件 (3)数...

1.2K7
来自专栏智能算法

Learning to Rank 小结

一、学习排序(Learning to Rank) LTR(Learning torank)学习排序是一种监督学习(SupervisedLearnin...

4515
来自专栏机器之心

教程 | 利用TensorFlow和神经网络来处理文本分类问题

3417
来自专栏磐创AI技术团队的专栏

FastText的内部机制

1103
来自专栏漫漫深度学习路

tensorflow学习笔记(四十五):sess.run(tf.global_variables_initializer()) 做了什么?

当我们训练自己的神经网络的时候,无一例外的就是都会加上一句 sess.run(tf.global_variables_initializer()) ,这行代码的...

2596
来自专栏小鹏的专栏

01 TensorFlow入门(2)

Working with Matrices:         了解TensorFlow如何使用矩阵对于通过计算图理解数据流非常重要。 Getting read...

2716
来自专栏编程软文

前端慌不慌?用深度学习自动生成HTML代码

5416
来自专栏杂文共赏

卷积神经网络究竟做了什么?

神经学习的一种主要方式就是卷积神经网络(CNN),有许多种方法去描述CNN到底做了什么,一般通过图像分类例子通过数学的或直观的方法来介绍如何训练和使用CNN。

5168

扫码关注云+社区

领取腾讯云代金券