神经网络整体架构"/>
07 神经网络整体架构
神经网络整体架构
我们先看看神经网络是什么样子的,如下图。
可以说神经网络是一个层次的结构,有一个输入层,隐层 1,隐层 2 和输出层。可以说是由多个层组成了一个完整的神经网络。输入层相当于输入的 x x x,比如说现在的输入有 3 个像素点 x 1 x_1 x1, x 2 x_2 x2, x 3 x_3 x3。
中间两个层具体的元素很多参考资料中将它们称做神经元,其实神经元是不存在的。那么中间层里面的元素的是什么呢?其实就是权重参数的计算结果。比如说, x 1 x1 x1 是和这些带箭头的线相连的,没有这些线,是到不了隐层 1 的节点的。所以这些线非常重要,我们把与输入层相连接的线表示为第一层的权重系数 W 1 W_1 W1, W 1 W_1 W1 左边连接的是 x x x,右边连接的是隐层 1,所以 W 1 W_1 W1 在这个例子中其实就是一个 3 x 4 的矩阵。
而且我们首先需要定义好隐层是有多大?或者说是有多少个神经元?那么这个神经元其实就相当于权重参数当中的一个部分。 W 1 W_1 W1 相当于把输入层和隐层 1 连接起来。那么后续做了什么操作呢?第一个隐层和第二个隐层之间又通过很多线相连,那么我们将这两层之间的直线定义为 W 2 W_2 W2,同理,隐层 2 和输出层之间通过 W 3 W_3 W3 相连。
之前说过,一个得分函数为 W ∗ x W*x W∗x。那么对于神经网络来说,它的得分函数就是 W 1 ∗ x 1 W_1*x_1 W1∗x1 得到一个中间结果,然后用 W 2 W_2 W2 乘以中间结果 W 1 ∗ x 1 W_1*x_1 W1∗x1,又得到一个中间结果 W 2 ( W 1 ∗ x 1 ) W_2(W_1*x_1) W2(W1∗x1),然后再用 W 3 W_3 W3 乘以中间结果 W 2 ( W 1 ∗ x 1 ) W_2(W_1*x_1) W2(W1∗x1),得到最后输出结果 W 3 ( W 2 ( W 1 ∗ x 1 ) ) W_3(W_2(W_1*x_1)) W3(W2(W1∗x1))。
通过上面的计算过程可以得出,其实神经网络是由这些权重参数的一个组合最终得出输出值。那么对于这个神经网络模型来说,我们需要指定哪些参数呢?有些参数是必须要指定的,比如 W 1 W_1 W1, W 2 W_2 W2 和 W 3 W_3 W3 它们的 shape 分别是多大,即 W 1 W_1 W1 前面连多大,后面连多大,这些是必须要指定出来的。
那么可能你会有这样的疑问?其实 W ∗ x W*x W∗x 也能完成这个式子,那么为什么还要加隐层呢?这个后面再揭晓。
下面有一个线性方程: f = W x f = Wx f=Wx,如果神经网络使用线性的方程,相当于给它加了一些局限性。我们所认为的神经网络,它应该是能向任意的方向进行伸展,如果给它加上了一个线性的条件,那么就只能是横着或者竖着,有很大的局限性。刚才说的神经网络的第一个特点,它是一个层次的结构。那么它的第二个非常重要的特点,它是一个非线性的结构,刚才的模型中有说到 W 2 W_2 W2 需要乘上 W 1 ∗ x W_1*x W1∗x,这里我又加上了一个 max 函数。
这里把加上的 m a x max max 函数叫做激活函数。激活函数的作用就是增加神经网络模型的非线性,比如之前的 Sigmoid 函数就是一个激活函数,它能够是先把任意一个值映射到 0-1 之间。
那么我们把 Sigmoid 函数作为激活函数,有没有什么问题呢?有没有更好的激活函数呢?对于一个神经网络来说,其中包含求导的操作,如之前的例子中,如果要求 W 1 W_1 W1,需要乘上 W 1 W_1 W1 的导数,这么来就存在一个导数累乘的操作。假设在 Sigmoid 函数中 A A A 点求梯度,就是在 A A A 点的切线值。
如果该点值稍微大一些,比如在 B B B 点,那么它的导数就是 0 左右。
如果值更大的话,那么该点的导数就更趋近于 0,也就是说,如果数值比较大或者比较小,它的导数值都会趋近于 0,意味着接下来求导的时候会发生梯度消失的现象,梯度消失的后果就是没办法更新参数 W W W 的值。这就是 Sigmoid 函数被淘汰的原因,一旦神经网络的层次非常深,梯度消失的现象就会非常严重,一旦发生了梯度消失的现象,我们就没办法完成反向传播,导致神经网络永远不会收敛。
所以我们引入了另外一个激活函数 ReLU 函数,当 x x x 值小于的时候,都等于 0,当 x x x 大于 0 时,都等于下图所示的直线。
对于 ReLU 激活函数来说,它能够解决梯度消失的问题,另一方面求导十分的简单。所以现在深度学习大多都是使用 ReLU 作为激活函数。
更多问题
1. 数据预处理的问题
下面再来说说数据预处理的问题。当图像数据来了之后,我们是直接输入还是进行先处理呢?通常情况下会做一个处理。一般来说,一般都会以 0 为中心化,即使得数据集中每个数据减去均值。以 0 为中心化之后 x x x 轴就会浮动得小一些, y y y 轴相对来说浮动得大一些。那么接下来我们就可以做归一化处理,使得 y y y 值范围都在 0-1 之间,即样本数据除以方差。
2. 权重初始化的问题
接下来再来讨论权重初始化的问题,之前说过在神经网络模型中最重要的是参数 W W W,而且必须要对所有的 W W W 进行一个初始的赋值。 W W W 初始值绝对不能是 0,因为之前说过反向传播的过程涉及到 W W W 的累乘,只要其中的一个 W W W 为 0,那么最终得到的结果必定是 0,那么就没有意义。所以对于权值的初始化,需要产生一种策略,通常会进行高斯初始化或者随机初始化( W W W 为矩阵, D D D 表示行, H H H 表示列),我们只需要指出 W W W 的 shape 大小即可。
还有一个参数 b b b,虽然说 b b b 对最后结果的结果影响很小,但是 b b b 还是得进行初始化,一般初始化为 0 或者 1 (常数均可)即可。
3. DROP-OUT
还有最后一个知识点 DROP-OUT,先看图(1)中层与层之间是一个全连接的操作,比如 x 1 x_1 x1 和 L 1 L_1 L1 层中每个节点之间都存在连线, x 2 x_2 x2, x 3 x_3 x3, x 4 x_4 x4, x 5 x_5 x5 也是如此。同理, L 1 L_1 L1 层中每个节点与 L 2 L_2 L2 层每个节点也是全连接的关系。 因为图(1)中的神经元个数相对来说还比较少,所以线与线之间还可以看清,但是如果神经元的个数有成百上千个呢,它们之间的连接方式是不是太复杂了。这么复杂的模型十分容易导致过拟合。那怎么解决这个过拟合的风险呢?
那么很多学者提出了 DROP-OUT 的方式,它的思想就是当我们在进行一次神经网络迭代的时候(训练神经网络),有些时候代入部分神经元即可(图(2)中不带×的神经元),比如说这次前相传播和反向传播数据集只用到 x 1 x_1 x1, x 4 x_4 x4, x 5 x_5 x5, L 1 L_1 L1 层中只用到 w 2 w_2 w2 和 w 5 w_5 w5,依次类推。那么我们每次都是用这几个来进行训练吗?当然不是,这是一个随机的过程,比如说我指定一个 DROP_OUT 率为 60%,意思是每次都选择 60% 的神经元参与传播过程,剩下的 40% 不需要更新。下次迭代再重新随机选择 60% 的神经元。这样就能够削减神经网络的大小,使得神经网络显得不那么臃肿,以致于不太容易过拟合。
更多推荐
07 神经网络整体架构
发布评论