【深度学习】1.3浅层神经网络

神经网络表示

在一个双层神经网络中(因为一般不把输入层看作一个标准的层):
输入特征的数值可以用a[0] = x表示,这个a意味着网络中不同层的值,会传递给后面的层。因此,输入层将x的值传递给隐藏层,就将输入层的激活值称为a[0]。通常也称输入层为第零层。
下一层为隐藏层,这一层的数据我们是不知道的,它也同样会产生一些激活值,将其记作a[1]。这里的第一个单元,或者说节点,可以记为a1[1];第二个节点记作a2[1]
最后的输出层会产生某个数值a[2],是个实数,那么y hat的值就等于a[2]
隐藏层和输出层是带有参数的,

多个例子中的向量化

在这里插入图片描述
对于输入的特征向量x,对于这单个训练样本,可以用它生成一个a[2] = y hat。
若有m个训练样本,可能需要重复这个过程。比如用第一个训练样本x[1]来计算a[2](1) = y hat[1](对第一个样本的预测值);用第二个训练样本x[2]来计算a[2](2) = y hat[2];…;用第m个训练样本x[m]来计算a[2](m) = y hat[m]
Tips:a[2](i):圆括号里的i表示训练样本i,方括号指的是第二层。
若非向量化的实现,需要进行如下训练遍历m个训练样本:
在这里插入图片描述
之前定义了矩阵X = [x(1), x(2),…,x(m)],即训练样本以列的形式堆在一起,这是一个nx×m的矩阵。
因此,可以令矩阵Z[1] = [z[1](1), z[1](2),…, z[1](m)],A[1] = [a[1](1), a[1](2),…, a[1](m)],同样定义一下Z[2]和A[2]
将训练样本横向堆叠起来构成矩阵X,就可以导出一个在网络中正向传播算法的向量化实现。

向量化实现的解释

为了便于说明,令b[1] = 0,那么有:
z[1](1) = w[1]x(1), z[1](2) = w[1]x(2), z[1](3) = w[1]x(3)

激活函数

之前经常使用**σ(z)**作为激活函数,但其实更常用的是tanh(z)这个函数,tanh(z) = (ez - e-z) / (ez + e-z)。
使用二元分类的时候,更多会用到σ()函数作为输出层。
为了表示不同层的不同激活函数,可能会用方括号上标,比如g[1]()表示隐藏层, g[2]()表示输出层(在此讨论的仍是双层神经网络系统)。

不过,σ()函数和tanh()函数都有一个缺点,就是如果z非常大或者非常小,那么导数的梯度,或者说这个函数的斜率可能就很小。所以z非常大或者非常小时,函数的斜率很接近0,这样会拖慢梯度下降算法。

在机器学习中有一个很常用的修正线性单元(rectified linear unit, ReLU),
在这里插入图片描述
只要z为正,导数就是1;当z为负时,斜率为0;当z为0时,导数是没有定义的。但编程中,z刚好等于0000000000的概率是很低的。所以实际应用中可以不用考虑z为0的情况,也可以给z=0时赋值为0或1。

在选择激活函数时,有一些经验。如果输出值是0和1,即如果在做二元分类,那么σ函数很适合作为输出层的激活函数,然后其他所有单元都用ReLU(若不确定隐层用什么,就可以用ReLU作为激活函数)。
但ReLU还有另一个版本,叫做带泄漏的ReLU(the Leaky ReLU),当z为负时,函数不再为0,它有一个很平缓的斜率。这通常比ReLU激活函数更好,不过实际中使用的频率没那么高。
ReLU和带泄漏的ReLU好处在于:对于很多z空间,激活函数的导数、激活函数的斜率和0差很远。因为ReLU没有这种函数斜率接近0的情况,这种情况会减慢学习的速度,所以在实际中使用ReLU激活函数可以使神经网络的学习速度快很多。虽然对于z的一半范围来说,ReLU的斜率为0,但在实践中有足够多的隐藏单元令z大于0,所以对大多数训练样本来说还是很快的。

总结:
1.σ函数:
在这里插入图片描述
除非用在二元分类的输出层,不然绝对不要用。

2.tanh函数:
在这里插入图片描述
和σ函数相比,tanh几乎在所有场合都更优越。

3.ReLU函数:
在这里插入图片描述

它是最常用的默认激活函数。

4.带泄漏的ReLU:
在这里插入图片描述
其中,a是0.01*z和z两者的最大值,这样函数图像就会拐一下。常数为0.01,也可以把它设成学习函数的另一个参数。

为什么需要非线性激活函数

线性激活函数也叫恒等激活函数,比如g(z)=z,那么神经网络只是把输入线性组合再输出。事实证明,如果使用线性激活函数,或者如果没有激活函数,那么无论神经网络有多少层,一直在做的只是计算线性激活函数,所以不如直接去掉全部隐藏层。
若在隐藏层使用线性激活函数,在输出层使用σ函数,那么这个模型的复杂度和没有任何隐藏层的标准逻辑logistic回归是一样的。
因此,线性隐层一点用都没有!因为两个线性函数的组合本身就是线性函数,所以除非引入非线性,不然就算有很多网络层数,也没有办法计算更有趣的函数。
只有一个地方可以使用线性激活函数g(z)=z,就是如果机器学习的是回归问题,在输出层使用,所以输出y是一个实数,比如想预测房地产价格,所以y不是0和1,而是一个实数。但隐藏单元不能用线性激活函数(除了与压缩有关的一些非常非常特殊的情况),它们可以用ReLU或者tanh或者带泄漏的ReLU或者别的。

激活函数的导数

当对神经网络使用反向传播的时候,需要计算激活函数的斜率或者导数。接下来介绍激活函数的选择以及如何计算这些函数的斜率。
1.σ函数
在这里插入图片描述
在这里插入图片描述
2.tanh函数
在这里插入图片描述
在这里插入图片描述
3.ReLU
在这里插入图片描述
4.带泄漏的ReLU
在这里插入图片描述

神经网络的梯度下降法

有这样几个nx,分别为n[0]、n[1]、n[2]=1,那么参数w[1]为(n[1], n[0])维,b[1]为(n[1], 1)维,w[2]为(n[2], n[1])维,b[2]为(n[2], 1)维。还有一个神经网络的成本函数(假设在做二元分类)
在这里插入图片描述
其中,L表示神经网络预测出y hat时的损失函数。

要训练参数的话,需要对算法做梯度下降。在训练神经网络时,随机初始化参数很重要,而不是全部都初始化0。当将参数初始化成某些值之后,每个梯度下降循环都会计算预测值,所以要计算出i=1到m的预测值y hat。然后需要计算导数,所以需要计算dw[1](成本函数J对参数w[1]的导数)、db[1](成本函数J对变量b[1]的导数)…
然后梯度下降最后会更新,w[1] = w[1] - α(学习率)dw[1],b[1] = b[1] - αdb[1],…这是梯度下降的一次迭代循环,然后重复这些步骤很多次,直到参数收敛。

正向传播的方程(4个):
Z[1] = w[1]X + b[1]
A[1] = g[1](Z[1])
Z[2] = w[2]A[1] + b[2]
A[2] = g[2](Z[2]) = σ(Z[2])

反向传播的方程(6个):
dZ[2] = A[2] - Y
dW[2] = dZ[2] A[1]T / m
db[2] = np.sum(dZ[2], axis=1, keepdims = True) / m
dZ[1] = W[2]TdZ[2] * g[1]’(Z[1])
dW[1] = dZ[1]XT / m
db[1] = np.sum(dZ[1], axis=1, keepdims = True) / m

其中,这些都针对所有样本,Y为基本真值,是1×m矩阵(将m个样本横向堆叠起来);np.sum是python的numpy命令,用来对矩阵的一个维度求和,axis=1就是水平相加求和,加上开关keepdims就是防止python直接输出古怪的秩为1的数组(它的维度是(n[2],)),所以加上keepdims=True确保python输出的矩阵对于db[2]这个向量输出的维度是(n[2],1),也可以不用keepdims,使用reshape。

随机初始化

对于logistic回归,可以将权重初始化为零。但如果将神经网络的各参数数组全部初始化为0,再使用梯度下降算法,那会完全无效。
在这里插入图片描述
如果有两个输入特征,那么n[0]=2;有两个隐藏单元,所以n[1]=2。所以和隐层相关的矩阵W[1]是2×2的,假设将它全部初始化成全部是0的2×2矩阵,令b[1]也为全0的2×1矩阵。将偏置项b初始化为0实际上是可行的,但将W全部初始化0就有问题了。这种初始化形式的问题在于:给网络输入任何样本,隐层的a[1]1和a[1]2是一样的,这两个隐藏单元都在做完全一样的计算,所以这两个激活函数完全一样。当计算反向传播时,出于对称性,dz[1]1和dz[1]2也是相同的,这两个隐藏单元会以同样的方式初始化。假设输出的权重也是一样的,那么W[2]就等于0的一个1×2的矩阵。但如果以这种方式初始化神经网络,那两个隐藏单元就完全一样了。这就是所谓的完全对称,意味着节点计算完全一样的函数。可以通过迭代法证明,每次训练迭代之后,两个隐藏单元仍然在计算完全相同的函数。
对于更大的神经网络,如果有三个输入特征,或者隐藏单元的数目非常多,那么用类似的方法可以证明。

这个问题的解决方案是随机初始化所有参数
可以令W[1] = np.random.randn((2,2)) × 0.01,即先产生参数为(2,2)的高斯分布随机变量,再乘以一个很小的数字,就将权重初始化成很小的随机数。选择0.01而不是10或100是因为,我们通常喜欢把权重矩阵初始化成非常非常小的随机值;因为有时候如果权重太大,当计算激活函数时,z值会很大或者很小,对于tanh函数或者σ函数,就会落在图像的平缓部分,梯度的斜率非常小意味着梯度下降法会非常慢,所以学习会很慢。令b[1] = np.zeros((2,1)),因为b没有上述的破坏对称性问题,所以将其初始化0是可以的。只要W随机初始化,那么一开始是用不同的隐藏单元计算不同的函数,并不破坏对称性。类似的定义W[2] = np.random.randn((2,1)) × 0.01和b[2]

当训练一个单隐层神经网络时,这是一个相对较浅的神经网络,没有太多的隐藏层,将权重设为0.01是可以的。但当训练的是一个很深的神经网络的时候,可能需要试试0.01以外的常数(下一节会谈到)。不管怎样,初始化参数一般都很小

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值