前言
本文的例子和素材均来自 www.3blue1brown.com/lessons/neu...
本文主要解释了特征信息在神经网络中的传播方式以及全连接神经网络的数学表达式。
信息如何在神经网络中传递
本节所指的"信息"并不是指普通的数据,而是类似于特征信息等。
权重(weight)
我们假设只有一张图片作为输入,其中包含的数据信息仅限于每个像素的灰度值。我们的目标是在神经网络的第二层中使用一个神经元来表示输入图片中间偏上部分是否包含一个长方形。如下图:
显然,现有的数据不足以完成此任务,因此需要引入一个概念:"权重"(weight)。权重代表每个神经元之间的重要性,实质上是一个数字,影响着每个神经元之间的连接。
引入了权重的概念后,解决上述问题变得简单了许多。我们只需将第一层中代表"长方形"像素的神经元与第二层的目标神经元之间的权重设置得更高,而将第一层中其他神经元与目标神经元之间的权重设置为0。这样,在计算第二层神经元的激活值时,其他神经元的影响就会被排除掉。
我们用a代表神经元,w代表权重。因此,第二层的神经元激活值可表示为:
w1 * a1 + w2 * a2 ... + wn * an
这样,当输入图片中的"长方形"对应的像素被激活时,经过第一层计算后,就能够激活第二层相应的神经元。而如果其他区域出现长方形,由于权重设置较低,计算后的激活值仍然很小,因此无法激活下一层的神经元。这意味着我们只关注于这个区域的神经元。
但是: 如果一个面积大于所需"长方形"的区域也会被激活。比如,下图中的两张图都能激活第二层的神经元。
如果我只想关注一个3*8大小的长方形怎么办呢?我们可以在长方形外围增加一圈负值的权重
权重也可以为负数,
这样,只有3*8的区域能获得最大的激活值,而像上图左侧那种情况的激活值会因为负权重而变得很小。
偏差(bias)
在计算下一个神经元的激活值时,我们需要考虑如何判断它是否应该被激活。一种简单的想法是,大于0的值激活,小于0的值不激活。但是,这样的规则并不适用于所有情况,因为不同的神经元可能需要不同的判断标准。
因此,我们引入了一个称为偏差的变量。尽管我们仍然使用大于0激活、小于0不激活的统一标准,但对于某些神经元,我们可能希望设置一个更高的激活阈值,比如大于10才激活。这时,我们只需在计算结果后对偏差进行运算即可。
css
(w1 * a1 + w2 * a2 ... + wn * an)- b
// b = 10,即把是否激活改为了大于10
训练神经网络的过程实质上就是不断调整权重和偏差的值。这些权重和偏差就像一个个水龙头和阀门,它们的作用是确保输入的"水"能够流向正确的"闸口",也就是正确的输出。
想象一下如果让你手动的去调整一个神经网络每个神经元的权重和偏差,那工作量是多么庞大。
总结:权重告诉了你应该关注哪些神经元,偏差告诉你神经元应该到什么程度才激活
激活函数
在上一章节我们提到了,要把像素灰度值都压缩到0-1之间,所以目前为止我们的神经元激活值都需要在0-1之间,再计算完权重和偏差以后的结果可能是任何值,所以我们要再进行一次激活运算,假设激活函数为σ,那么完整的计算公式为:
css
σ((w1 * a1 + w2 * a2 ... + wn * an) - b)
激活函数的选择有很多,比如本例的把任何数字都压缩到0-1的sigmoid算法
或者现在比较流行的ReLu算法
你可能会有疑问,为什么不能跳过激活函数呢?少一次运算,直接使用图片的原始RGB值作为输入,然后使用计算得到的真实结果作为输出。答案是当然可以,但这样做会导致你的函数仅仅是一个线性函数,只涉及到简单的加减乘除运算,缺乏足够的表现力,无法更好地拟合目标模型。关于这一点,colah.github.io/posts/2014-...这篇文章做了很好的解释。(目前我也还在学习中)
全连接神经网络数学表达式
在上一节已经列出了单个神经元的表达式:
css
σ((w1 * a1 + w2 * a2 ... + wn * an) - b)
对于一整个神经网络,其中包含了多个神经元,我们用
a(x.y):表示第x层的第y个神经元的激活值
w(x.y):表示第二层第x个神经元与第一层第y个神经元的权重
b(x):表示第二层第x个神经元的偏差
因为涉及多个神经元的操作,我们可以用矩阵来概括这一系列的运算:
我们用大写字母W表示权重矩阵,b表示偏差矩阵,a(0)表示第0层神经元激活值矩阵。因此我们可以得到下一层的激活值表达式为:
总结
本文带领读者初步认识了权重、偏差和激活函数的概念,并使用数学表达式描述了神经网络的基本结构。在接下来的章节中,我将为读者介绍神经网络是如何通过调整权重和偏差来达到预期效果的。