BP神经网络

本文总字数:7985,阅读预计需要:20分钟

1  预测机

1.1 预测机的构建

预测机根据输入推测输出结果。
例如下图需要预测机根据输入的千米数得到英里数。

现有案例为:

考虑千米与英里之间应该存在线性关系,即它的形式应该是“英里=千米×C”,其中C为常数。这里不用英里/千米的方式得到C。
随机使用C = 0.5进行验证。

编号为2 的真实示例告诉我们,答案应该是62.137,因此结果是不准确的。输出结果和期望结果存在误差。

随机选择的常数C,得到的输出结果存在误差很正常,而且得到误差可以指导C值如何进行修改。根据上面结果可知C值小了,因此下一步将C值增大,继续验证。C为0.6。

根据结果还是存在误差,再次重复这个过程,微调C, 将其从0.6调到0.7。

根据结果可知,误差变成负数,调节过大超调了,并且C=0.6比C=0.7的误差绝对值小,因此可以再C=0.6的基础上进行微调。将C从0.6调到0.61。

如果输出值越 来越接近正确答案,即误差值越来越小,那么我们就不要做那么大的调整。使用这种方式,我们就可以避免像先前那样得到超调的结果。因此重复上面的操作,不停的迭代最终能够找到答案。

1.2 关键点:

  • 所有有用的计算机系统都有一个输入和一个输出,并在输入和输出之间进行某种类型的计算。神经网络也是如此。
  • 当我们不能精确知道一些事情如何运作时,我们可以尝试使用模型来估计其运作方式,在模型中,包括了我们可以调整的参数。如果我们不知道如何将千米转换为英里,那么我们可以使用线性函数作为模型,并使用可调节的梯度值作为参数。
  • 改进这些模型的一种好方法是,基于模型和已知真实示例之间的比较,得到模型偏移的误差值,调整参数

2 分类器

2.1 分类器的构建

分类器与预测器并无太大差别。
上述的简单机器接受了一个输入,并做出应有的预测,输出结果,所以我们将其称为预测器。我们根据结果与已知真实示例进行比较所得到的误差,调整内部参数,使预测更加精确。
现在有两种虫子,其宽度与长度不同,需要我们进行分类,如何去做。

 根据上图中已有的两种虫子的分类可知,可以使用一条直线将两种虫子类别进行区分。

 假设这条直线是过原点的直线y = A * x,则选中的虫子,计算机就可以通过其尺寸在这条直线的上方还是下方,判断虫子的种类。

首先将实例描绘在坐标系中

根据实例,随机选择A值,当A值为0.25时,直线如下图所示,不能将两种虫子类型划分,根据y的误差值(大一些/小一些),ΔA= E / x,可以调节直线的斜率A (new)= A(old)+ΔA ,根据瓢虫的误差值得到A=0.3367,根据数据一瓢虫继续调整直线,根据误差调节直线斜率A = 2.9。

 当时上面迭代有一个问题:使用各个训练数据 样本进行改进,那么我们所得到的是,最终改进的直线与最后一次训练样本非常匹配。实际上,最终改进的直线不会顾及所有先前的训练样本,而 是抛弃了所有先前训练样本的学习结果,只是对最近的一个实例进行了学习。

在机器学习中,有一种重要的思路叫适度改进(moderate)。就是说,不要使改进过于激烈。我们采用ΔA 几分之一的一个变化值,而不是采用整个ΔA,那么整个样本都能起到作用。并且当训练数据本身不能确信为完全正确并且包含在现实世界测量中普遍 出现的错误或噪声这两种情况时,有节制的调整可以抑制这些错误或噪声的影响。这种方法使得错误或噪声得到了调解和缓和。

因此,改进公式中将添加一个调节系数:
ΔA= L(E / x )
调节系数通常被称为学习率(learning rate),在此,我们称之为L。
使用新的改进方式进行调节。直线明显靠近中间,不会偏向于一边。设置L = 0.5。

2.2 总结:

根据上面预测器以及分类器的原理可知都是使用误差值(实例与模型输出值)调节数学模型中的参数,进而得到合理的预测器或分类器。
这也是神经网络的关键所在。下一步开始进入神经网络的主题。

3 神经网络

 3.1 神经元——大自然的计算机器

传统的计算机按照严格的串行顺 序,相当准确具体地处理数据。对于这些冰冷坚硬的计算机而言,不存在模糊性或不确定性。而另一方面,动物的大脑表面上看起来以慢得多的节 奏运行,却似乎以并行方式处理信号,模糊性是其计算的一种特征。让我们来观察生物大脑中的基本单元——神经元。

虽然神经元有各种形式,但是所有的神经元都是将电信号从一端传输 到另一端,沿着轴突,将电信号从树突传到树突。然后,这些信号从一个 神经元传递到另一个神经元。这就是身体感知光、声、触压、热等信号的机制。来自专门的感觉神经元的信号沿着神经系统,传输到大脑,而大脑本身主要也是由神经元构成的。神经元中关键部件——树突和终端。

我们需要多少个神经元才能执行相对复杂的有趣任务呢?
一般说来,能力非常强的人类大脑有大约1000亿个神经元!一只果蝇拥有约10万个神经元,能够飞翔、觅食、躲避危险、寻找食物以及执行许
多相当复杂的任务。而10万个神经元,这个数字恰好落在了现代计算机试图复制的范围内。

生物神经元与简单的线性函数不一样,不 能简单地对输入做出的响应,生成输出。也就是说,它的输出不能采用这种形式:输出=(常数*输入)+(也许另一常数)。
观察表明,神经元不会立即反应,而是会抑制输入,直到输入增强, 强大到可以触发输出。
你可以这样认为,在产生输出之前,输入必须到达 一个阈值。就像水在杯中——直到水装满了杯子,才可能溢出。直观上,这是有道理的——神经元不希望传递微小的噪声信号,而只是传递有意识 的明显信号。下图说明了这种思想,只有输入超过了阈值(threshold),足够接通电路,才会产生输出信号。

虽然这个函数接受了输入信号,产生了输出信号,但是我们要将某种称为激活函数的阈值考虑在内。在数学上,有许多激活函数可以达到这样
的效果。一个简单的阶跃函数可以实现这种效果。

你可以看到,在输入值较小的情况下,输出为零。然而,一旦输入达到阈值,输出就一跃而起。具有这种行为的人工神经元就像一个真正的生物神经元。科学家所使用的术语实际上非常形象地描述了这种行为,他们说,输入达到阈值时,神经元就激发了。

下图所示的S形函数称为S函数(sigmoid function)。这个函数,比起冷冰冰、硬邦邦的阶跃函数要相对平滑,这使得这个函数更自然、更接近现实。自然界很少有冰冷尖锐的边缘!

S函数,有时也称为逻辑函数

思考我们如何建模人工神经。
首先需要认识到的第一件事情是生物神经元可以接受许多输入,而不仅 仅是一个输入。
对于所有这些输入,我们该做些什么呢?
我们只需对它们进行相加, 得到最终总和,作为S函数的输入,然后输出结果。这实际上反映了神经元的工作机制。
下图说明了这种组合输入,然后对最终输入总和使用阈值的思路。

如果组合信号不够强大,那么S阈值函数的效果是抑制输出信号。如 果总和x 足够大,S函数的效果就是激发神经元。

树突收集了这些电信号,将其组合形成更强的电信号。如果信号足够 强,超过阈值,神经元就会发射信号,沿着轴突,到达终端,将信号传递
给下一个神经元的树突。下图显示了使用这种方式连接的若干神经元

需要注意的一点是,每个神经元接受来自其之前多个神经元的输入, 并且如果神经元被激发了,它也同时提供信号给更多的神经元。
将这种自然形式复制到人造模型的一种方法是,构建多层神经元,每 一层中的神经元都与在其前后层的神经元互相连接。下图详细描述了这种
思想。

下图再一次显 示了连接的节点,但是这次在每个连接上显示了相关的权重。较小的权重将弱化信号,而较大的权重将放大信号。
此处,我需要解释一下权重符号旁边的有趣小数字(即下标)。简单 说来,权重w2,3 与前一层节点2传递给下一层的节点3的信号相关联。因此,权重
w1,2 减小或放大节点1传递给下一层节点2的信号。为了详细说明这种思路,下图突出显示了第一层和第二层之间的两条连接。

为什么必须把前后层的每 一个神经元与所有其他层的神经元互相连接?
原因有两点,第一是这种一致的完全连接形式事实上可以相对容 易地编码成计算机指令;
第二是神经网络的学习过程将会弱化这些实际上 不需要的连接(也就是这些连接的权重将趋近于0),因此对于解决特定任务所需最小数量的连接冗余几个连接,也无伤大雅。

随着神经网络学习过程的进行,神经网络通过调整优化网络内部的链接权重改进输出,一些权重可能会变为零或接近于零。零或几乎为零的权重意味着这些链接对网络的 贡献为零,因为没有传递信号。零权重意味着信号乘以零,结果得到零,
因此这个链接实际上是被断开了。

3.2 神经网络工作方式

尝试使用只有两层、 每层两个神经元的较小的神经网络,来演示神经网络如何工作,如下图所示。

两个输入值分别为1.0和0.5。这些值输入到这个较小 的神经网络,如下图所示。
每个节点使用激活函数,将输入转变成输出。我们还将使用先前看到 的S函数y = 1/(1 + e−x ),其中神经元输入信号的总和为x ,神经元输出为y。
权重是什么?权重的初始值应该为多少?这是一个很好的问题。初始使用一些随机权重:

随机初始值,这也是我们在先前简单的线性分类器中 选择初始斜率值时所做的事情。随着分类器学习各个样本,随机值就可以得到改进。对于神经网络链接的权重而言,这也是一样的。
在这个小型的神经网络中,由于连接每一层中两个节点的组合就只有 四种连接方式,因此只有四个权重。下图标出了我们当前所知的所有数字。

第一层节点是输入层,这一层不做其他事情,仅表示输入信号。也就 是说,输入节点不对输入值应用激活函数。历史就是这样规定的。神经网络的第一层是输入层,这层所 做的所有事情就是表示输入,仅此而已。
接下来的第二层,我们需要做一些计算。下图就是我们先前所看到的一幅 图,但是现在,这幅图包括使用链接权重调节输入信号的过程。

先让我们关注第二层的节点1。第一层输入层中的两个节点连 接到了这个节点。因此,组合经过了权重调节后的输入,如下所示:
x = (第一个节点的输出*链接权重)+(第二个节点的输出*链接权重)
x =(1.0 * 0.9)+(0.5 * 0.3)
x = 0.9 + 0.15
x = 1.05
不希望看到:不使用权重调节信号,只进行一个非常简单的信号 相加1.0 + 0.5。权重是神经网络进行学习的内容,这些权重持续进行优化,得到越来越好的结果。
因此,使用激活函数y = 1 /(1 + e -x )计算该节点的 输出。
y = 1 /(1 + 0.3499)= 1 / 1.3499。因此,y = 0.7408。

同样第二层第二个节点。组合调节输入x 为:
x = (第一个节点的输出*链接权重)+(第二个节点的输出*链接权重)
x =(1.0 * 0.2)+(0.5 * 0.8)
x = 0.2 + 0.4
x = 0.6
因此,现在我们可以使用S激活函数y = 1/(1 + 0.5488) = 1/1.5488计算节 点输出,得到y = 0.6457。

上面是神经网络根据输出通过内部权重组合以及激活函数的作用得到输出的过程。
由此可知在这个过程中权重系数是非常重要的,权重系数关系到最终输出结果的准确性,而随机的权重系数是不能作为解决某种问题的神经网络的,需要根据问题存在的实例,进行训练神经网络,得到一组适应于此问题的权重系数,从而在解决此类问题是,就可以通过问题的输出得到相应的结果。

3.3 矩阵乘法在神经网络中的用途

第一个矩阵包含两层节点之间的权重。第二个矩阵包含第一层输入层 的信号。通过两个矩阵相乘,我们得到的答案是输入到第二层节点组合调 节后的信号。仔细观察,你就会明白这点。由权重w1,1 调节的input_1加上 由权重w2,1 调节的input_2,就是第二层第一个节点的输入值。这些值就是在应用S函数之前的x的值。
下图非常清楚地显示了这一点。

为什么转换成矩阵相乘呢?因为我们可以使用矩阵乘法表示所有计算,计算出组合调节后的信号x ,输入到第二层的节点中。我们可以使用下式,非常简洁地表示:
X = W
此处,W 是权重矩阵,I 是输入矩阵,X 是组合调节后的信号,即输入到第二层的结果矩阵。矩阵通常使用斜体显示,表示它们是矩阵,而不是单个数字。

现在,我们不需要在乎每一层有多少个节点。如果我们有较多的节点,那么矩阵将会变得较大。但是,我们不需要写出长长的一串数字或大量的文字。我们可以简单地写为W I ,不管I有2个元素还是有200个元素。

有关激活函数,我们该了解些什么呢?激活函数其实很简单,并不需要矩阵乘法。我们所需做的,是对矩阵X 的每个单独元素应用S函数y = 1 /(1 + e -x )。
激活函数只是简单地应用阈值,使反应变得更像是在生物神经元中观察到的行为。因此,来自第二层的最终输出是:
O = sigmoid ( X )
斜体的O 代表矩阵,这个矩阵包含了来自神经网络的最后一层中的所有输出。

表达式X = W I 适用于前后层之间的计算。比如说,我们有3层,我们简单地再次进行矩阵乘法,使用第二层的输出作为第三层的输入。当然,这个输出应该使用权重系数进行调节并进行组合。

3.4 采用矩阵乘法演示三层神经网络工作方式

3.4.1 三层神经网络工作方式

演示使用矩阵进行计算得到经由神经网络馈送的信号,下图显示了具有3层、每层具有3个节点的神经网络示例。为了保证图的清晰,我们并没有标上所有的权重。

介绍一些常用的术语。第一层为输入层,最后一层为输出层,中间层我们称之为隐藏层。虽然隐藏层听起来很神秘、很黑暗,但是很遗憾,我们这样称呼中间层,其理由并不神秘。中间层的输出不需要很明显地表示为输出,因此我们称之为“隐藏”层。

下面演示一下图中所描述的示例网络。我们观察到了3个输入是0.9、0.1和0.8。因此,输入矩阵I 为:

输入到中间层的组合调节信号为X = W I ,其中I 为输入信号矩阵,W 为权重矩阵。这个神经网络的I W 是什么样的呢?图中显示了这个神经网络的一些权重,但是并没有显示所有的权重。下图显示了所有的权重,同样,这些数字是随机列举的。在这个示例中,权重没有什么特殊的含义。

 
W input_hidden 是输入层和隐藏层之间的权重。我们需要另一个权重矩阵来表示隐藏层和输出层之间的链接,这个矩阵我们称之为W hidden_output 。

第一个输入节点和中间隐藏层第一个节点之间的权重为w 1,1 = 0.9,正如上图中的神经网络所示。同样,你可以看到输入的第二节点和隐藏层的第二节点之间的链接的权重为w 2,2 = 0.8。图中并没有显示输入层的第三个节点和隐藏层的第一个节点之间的链接,我们随机编了一个权重w3。
算出输入到隐藏层的组合调节输入值。给这个输入值一个名称,考虑到这个组合输入是到中间层,而不是最终层,因此,我们将它称为X hidden 。


得到了输入到中间隐藏层的组合调节输入值,它们为1.16、0.42和0.62。
可视化这些输入到第二层隐藏层的组合调节输入。

对这些节点应用了S激活函数,使得节点对信号的反应更像自然界中节点的反应,

X hidden 层中的元素上应用S函数,生成中间隐藏层输出矩阵。

当信号通过中间层时,我们对这些信号进行了计算,也就是说我们计算出了中间层的输出值。这个过程是非常清晰的,也就是应用激活函数到中间层的组合输入信号上。让我们使用这个新信息,更新下图。

如何处理通过第三层的信号呢?
可以采用与处理第二层信号相同的方式进行处理,这没有任何实质的区别。仍然可以得到第三层的输入信号,就像得到第二层的输入信号一样。依然使用激活函数,使得节点的反应与我们在自然界中所见到的一样。因此,需要记住的事情是,不管有多少层神经网络,都“一视同仁”,即组合输入信号,应用链接权重调节这些输入信号,应用激活函数,生成这些层的输出信

继续计算最终层的组合调节输入X = W I 。这一层的输入信号是第二层的输出信号,也就是刚刚解出的O hidden 。所使用的权重就是第二层和第三层之间的链接权重W hidden_output ,而不是第一层和第二层之间的链接权重。因此,我们得到:


则从初始输入信号开始,前馈信号,并得到了最终层的组合输入信号。

剩下的工作就是应用S激活函数。

成功演示使用矩阵相乘追踪了神经网络中的信号,从信号进入神经网络,通过神经网络的各层,并得到了最终输出层的输出信号。

3.4.2 小结

3.2—3.4小结只是演示了神经网络在输入数据下如何得到输出结果,为保证输出结果的准确性,需要通过实例训练神经网络,得到一组适合此类问题的权重系数组合。训练方式是将神经网络的输出值与训练样本中的输出值进行比较,计算出误差,通过使用这个误差值来调整神经网络本身,进而改进神经网络的输出值。

3.5 误差的分配

先前,通过调整节点线性函数的斜率参数,来调整简单的线性分类器。使用误差值,也就是节点生成了答案与所知正确答案之间的差值,引导我们进行调整。实践证明,误差与所必须进行的斜率调整量之间的关系非常简单,调整过程非常容易。

当输出和误差是多个节点共同作用的结果时,如何更新链接权重呢?下图详细阐释了这个问题。

一种思想就是在所有造成误差的节点中平分误差,如下图所示。

另一种思想是不等分误差。

至此在神经网络中在两件事情上使用了权重。
第一件事情,在神经网络工作中,我们使用权重,将信号从输入向前传播到输出层。
第二件事情,使用权重,将误差从输出向后传播到网络中。称这种方法为误差反向传播

3.6 多个输出节点反向传播误差

在未受过训练的神经网络中,两个输出节点都有误差,这是很正常的。在网络中,需要使用这两个误差 值来告知如何调整内部链接权重。
第一个输出节点的误差标记为e1 ,等于由训练数据提供的所期望的输出值t1 与实际输出值o1 之间的差。也就是,e1 = ( t1 -o1 )。我们将第二个输出节点的误差标记为e2 。
按照所连接链接的比例,也就是权重w1,1 和w2,1 ,对误差e1 进行了分割。类似地,我们按照权重w1,2 和w2,2 的比例分割了e2 。

使用误差e1 的信息,来调整权重w1,1 和w2,1 。通过这种分割方式,使用e1 的一部分来更新w1,1
类似地,用来调整w2,1 的e1 部分为:

3.7 反向传播误差到更多层中

使用在输出层的误差值引导调整馈送到最终层的链接权重。输 出误差标记为eoutput ,将在输出层和隐藏层之间的链接权重标记为who 。
采用与隐藏层节点相关联的这些误差ehidden ,再次将 这些误差按照输入层和隐藏层之间的链接权重wih 进行分割。下图就显示了此逻辑。

如果神经网络具有多个层,那么就从最终输出层往回工作,对每一层重复应用相同的思路。误差信息流具有直观意义。同样,你明白为什么称之为误差的反向传播了。

训练样本数据只告诉我们最终输出节点的输出应该为多少,而没有告 诉我们任何其他层节点的输出应该是多少。因此不能说这个误差等于中间层节点所需目标输出值与实际输出值之间的差。
第一个隐藏层节点的误差是与这个节点前向连接所有链接中分割误 差的和。在上图中,我们得到了在权重为w1,1 的链接上的输出误差eoutput,1 的一部分,同时也得到了在权重为w1,2 的链接上第二个输出节点的输出误差eoutput,2 的一部分。

 

posted @   北极星!  阅读(184)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
历史上的今天:
2021-04-06 小论文格式要求
2020-04-06 两个51相互之间单片机如何进行串口通信
2020-04-06 (stm32f103学习总结)—stm32pwm
2020-04-06 (stm32f103学习总结)—stm32 PMW输出实验
>>博客统计:随笔 -615  文章 -0  评论 -50 
点击右上角即可分享
微信分享提示