参考:
吴恩达视频课
深度学习笔记
1. 神经网络概览
xW[1]b[1]⎫⎭⎬⟹z[1]=W[1]x+b[1]⟹a[1]=σ(z[1])
xW[1]b[1]⎭⎬⎫⟹z[1]=W[1]x+b[1]⟹a[1]=σ(z[1])
第一层根据输入计算
z[1]
z[1],然后计算第一层的输出
a[1]
a[1]
a[1]=σ(z[1])W[2]b[2]⎫⎭⎬⎪⎪⟹z[2]=W[2]a[1]+b[2]⟹a[2]=σ(z[2])⟹L(a[2],y)
a[1]=σ(z[1])W[2]b[2]⎭⎬⎫⟹z[2]=W[2]a[1]+b[2]⟹a[2]=σ(z[2])⟹L(a[2],y)
把第一层的输出
a[1]
a[1] 作为第二层的输入,计算
z[2]
z[2],代入 sigmoid
函数,得到输出
a[2]
a[2],进而计算损失函数
da[1]=dσ(z[1])dW[2]db[2]⎫⎭⎬⎪⎪⟸dz[2]=d(W[2]a[1]+b[2])⟸da[2]=dσ(z[2])⟸dL(a[2],y)
da[1]=dσ(z[1])dW[2]db[2]⎭⎬⎫⟸dz[2]=d(W[2]a[1]+b[2])⟸da[2]=dσ(z[2])⟸dL(a[2],y)
还有反向的求导过程
2. 神经网络的表示
3. 神经网络的输出
每个神经网络单元的工作包括两部分:计算
z
z,然后根据激活函数(sigmoid)计算
σ(z)
σ(z)
z[1]1z[1]2z[1]3z[1]4=w[1]T1x+b[1]1,a[1]1=σ(z[1]1)=w[1]T2x+b[1]2,a[1]2=σ(z[1]2)=w[1]T3x+b[1]3,a[1]3=σ(z[1]3)=w[1]T4x+b[1]4,a[1]4=σ(z[1]4)
z1[1]z2[1]z3[1]z4[1]=w1[1]Tx+b1[1],a1[1]=σ(z1[1])=w2[1]Tx+b2[1],a2[1]=σ(z2[1])=w3[1]Tx+b3[1],a3[1]=σ(z3[1])=w4[1]Tx+b4[1],a4[1]=σ(z4[1])
[layer]
上标表示第几层,下标表示该层的第几个节点
a[1]=⎡⎣⎢⎢⎢⎢⎢a[1]1a[1]2a[1]3a[1]4⎤⎦⎥⎥⎥⎥⎥=σ(z[1])
a[1]=⎣⎢⎢⎢⎡a1[1]a2[1]a3[1]a4[1]⎦⎥⎥⎥⎤=σ(z[1])
- 输入一个样本的特征向量,四行代码计算出一个简单神经网络的输出,那么多个样本呢?往下看
4. 多样本向量化
对于 m 个样本,(i)
表示第i
个样本
z[1](i)a[1](i)z[2](i)a[2](i)=W[1](i)x(i)+b[1](i)=σ(z[1](i))=W[2](i)a[1](i)+b[2](i)=σ(z[2](i))
z[1](i)a[1](i)z[2](i)a[2](i)=W[1](i)x(i)+b[1](i)=σ(z[1](i))=W[2](i)a[1](i)+b[2](i)=σ(z[2](i))
- 为了向量化计算,进行堆叠
x=⎡⎣⎢⎢⎢⋮x(1)⋮⋮x(2)⋮⋮⋯⋮⋮x(m)⋮⎤⎦⎥⎥⎥
x=⎣⎢⎢⎡⋮x(1)⋮⋮x(2)⋮⋮⋯⋮⋮x(m)⋮⎦⎥⎥⎤
Z[1]=⎡⎣⎢⎢⎢⋮z[1](1)⋮⋮z[1](2)⋮⋮⋯⋮⋮z[1](m)⋮⎤⎦⎥⎥⎥
Z[1]=⎣⎢⎢⎡⋮z[1](1)⋮⋮z[1](2)⋮⋮⋯⋮⋮z[1](m)⋮⎦⎥⎥⎤
A[1]=⎡⎣⎢⎢⎢⋮α[1](1)⋮⋮α[1](2)⋮⋮⋯⋮⋮α[1](m)⋮⎤⎦⎥⎥⎥
A[1]=⎣⎢⎢⎡⋮α[1](1)⋮⋮α[1](2)⋮⋮⋯⋮⋮α[1](m)⋮⎦⎥⎥⎤
z[1](i)=W[1](i)x(i)+b[1]α[1](i)=σ(z[1](i))z[2](i)=W[2](i)α[1](i)+b[2]α[2](i)=σ(z[2](i))⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪⟹⎧⎩⎨⎪⎪A[1]=σ(z[1])z[2]=W[2]A[1]+b[2]A[2]=σ(z[2])
z[1](i)=W[1](i)x(i)+b[1]α[1](i)=σ(z[1](i))z[2](i)=W[2](i)α[1](i)+b[2]α[2](i)=σ(z[2](i))⎭⎪⎪⎬⎪⎪⎫⟹⎩⎨⎧A[1]=σ(z[1])z[2]=W[2]A[1]+b[2]A[2]=σ(z[2])
列向看,对应于不同的特征,就是神经网络中的该层的各个节点
行向看,对应于不同的训练样本
5. 激活函数
tanh
激活函数是 sigmoid
的平移伸缩结果,其效果在所有场合都优于sigmoid
,tanh
几乎适合所有场合
- 例外是,二分类问题的输出层,想让结果介于 0,1之间,所以使用
sigmoid
激活函数
tanh
、 sigmoid
两者的缺点:
- 在特别大或者特别小
z
z 的情况下,导数的梯度 或者 函数的斜率会
变得特别小
,最后就会接近于0,导致降低梯度下降的速度。
激活函数的选择经验:
-
如果输出是0、1值(二分类问题),输出层 选择sigmoid
函数,其它所有单元都选择Relu
函数
-
隐藏层通常会使用Relu
激活函数。有时,也会使用tanh
激活函数,但Relu
的一个缺点是:当是负值的时候,导数等于0
-
另一个版本的Relu
被称为Leaky Relu
,当是负值时,这个函数的值不等于0,而是轻微的倾斜,这个函数通常比Relu
激活函数效果要好,尽管在实际中Leaky ReLu
使用的并不多
ReLu
、Leaky ReLu
的优点:
-
sigmoid
函数需要进行浮点四则运算,在实践中,使用ReLu
激活函数学习的更快
-
sigmoid
和tanh
函数的导数在正负饱和区的梯度接近于0
,这会造成梯度弥散,而Relu
和Leaky ReLu
函数大于0部分都为常数,不会产生梯度弥散现象。(Relu
进入负半区的时候,梯度为0,神经元此时不会训练,产生所谓的稀疏性,而Leaky ReLu
不会有这问题)
-
虽然ReLu
的梯度一半都是0,但是,有足够的隐藏层使得
z
z 值大于0,所以对大多数的训练数据来说学习过程仍然可以很快
6. 为什么需要 非线性激活函数
线性隐藏层一点用也没有,因为线性函数的组合本身就是线性函数,所以除非你引入非线性,否则你无法计算出更有趣的函数,即使网络层数再多也不行
- 不能在隐藏层用线性激活函数,可以用
ReLU
、tanh
、leaky ReLU
或者其他的非线性激活函数
- 唯一可以用 线性激活函数的通常就是输出层;在隐藏层使用
线性
激活函数非常少见
7. 激活函数的导数
sigmoid
a=g(z);g′(z)=ddzg(z)=a(1−a)
a=g(z);g′(z)=dzdg(z)=a(1−a)
tanh
a=g(z);g′(z)=ddzg(z)=1−a2
a=g(z);g′(z)=dzdg(z)=1−a2
-
ReLu
Rectified Linear Unit
g′(z)=⎧⎩⎨01undefined if z<0 if z>0 if z=0
g′(z)=⎩⎨⎧01undefined if z<0 if z>0 if z=0
z=0
z=0 时,可以让导数为 0,或者 1
-
Leaky ReLU
Leaky linear unit
g′(z)=⎧⎩⎨0.011undefined if z<0 if z>0 if z=0
g′(z)=⎩⎨⎧0.011undefined if z<0 if z>0 if z=0
z=0
z=0 时,可以让导数为 0.01,或者 1
8. 随机初始化
对于一个神经网络,如果你把权重或者参数都初始化为0,那么梯度下降将不会起作用。
W[1]W[2]=np.random.randn(2,2)∗0.01,b[1]=np.zeros((2,1))=np.random.randn(2,2)∗0.01,b[2]=0
W[1]W[2]=np.random.randn(2,2)∗0.01,b[1]=np.zeros((2,1))=np.random.randn(2,2)∗0.01,b[2]=0
常数为什么是0.01,而不是100或者1000,sigmoid/tanh
激活函数在很平坦的地方,学习非常慢
当你训练一个非常非常深的神经网络,你可能要试试0.01以外的常数
作业
01.神经网络和深度学习 W3.浅层神经网络(作业:带一个隐藏层的神经网络)
我的CSDN博客地址 https://michael.blog.csdn.net/
长按或扫码关注我的公众号(Michael阿明),一起加油、一起学习进步!
转载:
https://blog.csdn.net/qq_21201267/article/details/108229980