本文共 3015 字,大约阅读时间需要 10 分钟。
title: ‘DeepLearning.ai笔记:(1-3)-- 浅层神经网络(Shallow neural networks)’
id: 2018091215 tags:首发于个人博客:,欢迎来访
前面两周讲的是一些logistic和向量化的内容,以及numpy的基本使用,在他之前的机器学习课程中已经讲过了,这里就不再赘述。Week3主要讲了如何搭建两层的神经网络。
这周的内容就围绕着这一张图来讲。
a j [ i ] a_{j}^{[i]} aj[i]
这就是每一层神经元的表达方式,上标中括号[],表示是第几层的神经元;下标表示这个是某一层的第几个神经元。
Input Layer:输入层,也用 a j [ 0 ] a_{j}^{[0]} aj[0],表示第0层
Hidden Layer:表示除了最后一层输出层以外的内部隐藏层
Output Layer:输出层,表示最后一层
而通常神经网络的层数一般不包括输入层。
w [ i ] w^{[i]} w[i]:每一层的参数 w w w的维度是(该层神经元个数,前面一层神经元个数)
b [ i ] b^{[i]} b[i]:为(每一层的神经元个数,1)
由此得到,计算单个数据的神经网络只需要4步:
z [ 1 ] = W [ 1 ] a [ 0 ] + b [ 1 ] z^{[1]} = W^{[1]}a^{[0]} + b^{[1]} z[1]=W[1]a[0]+b[1]
a [ 1 ] = σ ( z [ 1 ] ) a^{[1]} = \sigma(z^{[1]}) a[1]=σ(z[1])
z [ 2 ] = W [ 2 ] a [ 1 ] + b [ 2 ] z^{[2]} = W^{[2]}a^{[1]} + b^{[2]} z[2]=W[2]a[1]+b[2]
a [ 2 ] = σ ( z [ 2 ] ) a^{[2]} = \sigma(z^{[2]}) a[2]=σ(z[2])
我们知道,多个数据的表示就是 x ( i ) x^{(i)} x(i),使用小括号的上标。神经元也是一样。
如 a [ 1 ] ( i ) a^{[1] (i)} a[1](i)表示第1层神经元的第i个样本。
那么如果有m个样本,一直做for循环来计算出这些神经元的值,实在是太慢了,所以跟logistic一样,可以直接用向量化来表示,这个时候用大写字母来表示。
Z [ 1 ] = W [ 1 ] A [ 0 ] + b [ 1 ] Z^{[1]} = W^{[1]}A^{[0]} + b^{[1]} Z[1]=W[1]A[0]+b[1]
A [ 1 ] = σ ( Z [ 1 ] ) A^{[1]} = \sigma(Z^{[1]}) A[1]=σ(Z[1])
Z [ 2 ] = W [ 2 ] A [ 1 ] + b [ 2 ] Z^{[2]} = W^{[2]}A^{[1]} + b^{[2]} Z[2]=W[2]A[1]+b[2]
A [ 2 ] = σ ( Z [ 2 ] ) A^{[2]} = \sigma(Z^{[2]}) A[2]=σ(Z[2])
这个时候,例如 A [ 1 ] A^{[1]} A[1]是一个 ( n , m ) (n,m) (n,m)的矩阵,m是样本数,每一列表示一个样本,n是该层的神经元个数。
从水平上看,矩阵 A代表了各个训练样本。竖直上看,A的不同索引对应不用的隐藏单元。
对矩阵Z和X也是类似,水平方向对应不同的样本,竖直方向上对应不同的输入特征,也就是神经网络输入层的各个节点。
在此前都是用sigmoid作为激活函数的。但是激活函数不只有这一种,常用的有4种,分别是:sigmoid, tanh, ReLu, Leaky ReLu。
tips:
结论:
如果不用激励函数(其实相当于激励函数是f(x) = x),在这种情况下你每一层输出都是上层输入的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与只有一个隐藏层效果相当,这种情况就是多层感知机(MLP)了。
正因为上面的原因,我们决定引入非线性函数作为激励函数,这样深层神经网络就有意义了(不再是输入的线性组合,可以逼近任意函数)。这里给出了浅层神经网络的梯度下降法公式。其中 g [ 1 ] ′ ( Z [ 1 ] ) g^{[1]'}(Z^{[1]}) g[1]′(Z[1])表示你的激活函数的导数。
在神经网络中,如果将参数全部初始化为0 会导致一个问题,例如对于上面的神经网络的例子,如果将参数全部初始化为0,在每轮参数更新的时候,与输入单元相关的两个隐藏单元的结果将是相同的。
所以初始化时,W要随机初始化,b不存在对称性问题,所以可以设置为0
W = np.random.rand((2,2))* 0.01b = np.zero((2,1))
将W乘以0.01是为了让W初始化足够小,因为如果很大的话,Z就很大,用sigmoid或者tanh时,所得到的梯度就会很小,训练过程会变慢。
ReLU和Leaky ReLU作为激活函数时,不存在这种问题,因为在大于0的时候,梯度均为1。
好好做作业,才能有更深的体会!
转载地址:http://jerii.baihongyu.com/