第三周 浅层神经网络
Core:如何实现神经网络。
神经网络表示(只有一个隐藏层的神经网络):
隐藏层的含义是在训练集中这些中间节点的真正数值是不知道的,在训练集中无法看到。
输入特征的数值的表示方式:
One:
Two:,a表示**的意思,它意味着网络中不同层的值会传递给后面的层。
注意每层参数的维度:
要想计算神经网络的输出,所需要的只是以上4行代码,知道如何输入单个特征向量x,并且向量化训练样本:通过把不同训练样本堆叠起来构成矩阵,只要稍稍修改公式,就可以得到之前类似于Logistic回归的结果,同时计算出不只有一个样本的神经网络输出,可一次性计算整个训练集。
多个例子中的向量化(学会如何将不同的训练样本向量化,输出结果和logistic回归相似):
将上面的输入方式变一下,让神经网络可以几乎同时计算所有样本的输出,
之前是
现在为了不用for,要将整个计算向量化。如何把for循环变成向量化实现呢?(把不同样本向量化)
把小向量化,堆叠到矩阵各列,构成大矩阵。(列向量堆叠法,把单个样本的向量横向堆叠,堆叠的横向指标就对应于不同的训练样本,当从左往右扫的时候,就扫过了整个训练集。而在竖向,竖向指标就对应于神经网络里的不同节点,即the hidden unit’s number。最左上角的节点对应着第一个训练样本,第一个隐藏单元的**函数。往下一个节点对应着the activation in the second hidden unit on the first training example)
横向扫过不同的训练样本,竖向扫过不同的隐藏单元。
对于X而言,此法横向扫过不同的训练样本,竖向对应不同的输入特征,实际上是神经网络输入层的不同节点。
**函数
使用tanh函数有类似数据中心化的效果,使得数据的平均值接近0。对于二值分类,输出层用sigmoid function更加合理,而对于隐藏层则可以使用tanh函数。So,不同层的**函数可以不一样。
Sigmoid function和tanh function都有一个缺点,即非常大或者非常小时,导数的梯度或者说函数的斜率接近于0会拖慢梯度下降法。
ReLU,即修正线性单元。可以解决上述问题。
在选择**函数时有一个经验法则,如果做的是二元分类(输出是0或者1),则sigmoid activation function很适合作为输出层的**函数。然后,其他所有单元都用ReLU(当今用途最为广泛)。
ReLU的缺点:当为负数时,导数为0。
the leaky ReLU (带泄露的ReLU):当为负数时,导数不再为0,它有一个很平缓的斜率。这通常比ReLU**函数更好,不过实际中使用频率没有那么高。
用ReLU的话,神经网络的学习速度通常会快得多,比使用tanh和sigmoid function还要快。
In fact,有足够多的隐藏单元,会使得大于0,所以用ReLU法对大多数训练样本来说还是很快的。
关于上图the leaky ReLU的0.01只是一种可能的情况。
为什么神经网络需要非线性**函数?
要让神经网络能够计算出有趣的函数,必须使用非线性**函数。
如果要用线性**函数,或者叫恒等**函数,那么神经网络只是把输入线性组合再输出。线性隐层一点用都没有。
只有一个地方可以使用线性**函数,,就是如果要机器学习的是回归问题,y是一个实数,如预测房地产价格,在输出层用线性**函数。不过,在隐藏单元不能用线性**函数。
**函数的导数
当对神经网络使用反向传播的时候,需要计算**函数的斜率或者导数,如tanh function。
梯度下降算法的具体实现,如何处理单隐层神经网络?
提供所需的方程来实现反向传播或者梯度下降。为训练参数,需要梯度下降。当训练神经网络时,初始化随机参数很重要,而不是全部初始化为0。
梯度下降的一次迭代循环,可重复迭代多次,直到参数看起来收敛。
在下图中y是真值。keepdims为true可以防止直接输出古怪的rank 1 array。对于输出层假设用的是sigmoid function,已经包含在式子中了。如果不想用keepdims,可以用reshape显式指出维度。总之,要想实现算法,必须能够正确执行正向传播和反向传播运算,必须可以计算出所需要的导数to 用梯度下降法学习网络的参数。
权重的随机初始化
对于Logistic回归,可以将权重初始化为0。但如果将神经网络的各参数数组全部初始化为0,再应用梯度下降法,则会完全失效。Let us see why
把偏置项b设为0是完全可行的,但对于w而言,不能这样做。
原因:
详细:对于网络输入的任何样本,和是一样的,两个隐藏单元做的是一样的事情。当计算反向传播时,出于对称和是一样的,这两个隐藏单元会以同样的方式初始化。节点在计算完全一样的函数,可以证明,在每次训练迭代之后,两个隐藏单元仍然在计算完全相同的函数。
精简:当将w的所有值初始化为0时,因为两个隐藏单元一开始就在做同样的计算,两个隐藏单元对输出单元的影响一样大,在一次迭代后,这种对称性依旧存在,两个隐藏单元依旧是对称的,所以归纳2-3次迭代就可以证明,无论训练神经网络多长时间,两个隐藏单元依旧在计算完全一样的函数,所以在这种情况下,多个隐藏单元真的没有意义,因为他们计算的都是同样的东西。最好是两个不同的隐藏单元,计算不同的函数。
解决方案:随机初始化所有参数,习惯上会把参数初始化为很小的随机值(这样可以防止减慢学习速度)。
注意,b完全没有对称性问题,可以初始化为0。
这里无需破坏对称性。
当网络很浅的时候,用0.01is OK,但是当网络变得很深时,可能要试试除0.01外的其他常数。不管怎样,初始化参数一般都很小。
参考信息:https://zhuanlan.zhihu.com/p/31992727