3.1 神经网络概述(Neural Networks Overview)
在神经网络中:
- 圆括号 (i) 表示第 i 个训练样本
- 方括号 [i] 表示网络的第 i 层(layer)
在逻辑回归的神经网络中,计算完 z 后通常要计算 a ,也就是 σ ( z ) \sigma(z) σ(z) ,在最后一层的 a 计算结束后,计算 L ( a , y ) \mathscr{L}(a,y) L(a,y) 损失函数
3.2 神经网络表示(Neural Network Representation)
在有监督学习中,训练集中包含了输入层(Input layer) 和输出层(Output layer) ,隐藏层(Hidden layer) 的含义为:在训练集中看不到中间节点的具体数值
在向量化表示中,以上图为例:
- 输入的 x 矩阵记为 a [ 0 ] a^{[0]} a[0],隐藏层矩阵记为 a [ 1 ] a^{[1]} a[1],输出层记为 a [ 2 ] a^{[2]} a[2],且预测输出值 y ^ = a [ 2 ] \widehat{y} = a^{[2]} y =a[2],a 在此处意为 activation
- 隐藏层矩阵可表示为 a [ 1 ] = [ a 1 [ 1 ] a 2 [ 1 ] a 3 [ 1 ] a 4 [ 1 ] ] a^{[1]} = \begin{bmatrix}a_1^{[1]}\\a_2^{[1]}\\a_3^{[1]}\\a_4^{[1]}\end{bmatrix} a[1]=⎣⎢⎢⎢⎡a1[1]a2[1]a3[1]a4[1]⎦⎥⎥⎥⎤,其中 [1] 表示第一层,下标表示第几个节点
- 隐藏层和输出层分别有一些参数
- 隐藏层中: w [ 1 ] w^{[1]} w[1] shape (4, 3) ,4表示隐藏层中有4个节点,3表示输入层中有3个输入, b [ 1 ] b^{[1]} b[1] shape (4,1)
- 输出层中: w [ 2 ] w^{[2]} w[2] shape (1,4) ,4表示隐藏层中有4个节点,1表示输出层中有1个输出, b [ 2 ] b^{[2]} b[2] shape (1,1)
- 上图中神经网络为双层神经网络 (2 layer NN),因为通常输入层不算一个正式的层
3.3 计算神经网络的输出(Computing a NN’s Output)
在如上图所示的双层神经网络中:
隐藏层第一个节点:
z
1
[
1
]
=
w
1
[
1
]
T
x
+
b
1
[
1
]
z_1^{[1]} = w_1^{[1]T}x + b_1^{[1]}
z1[1]=w1[1]Tx+b1[1]
a
1
[
1
]
=
σ
(
z
1
[
1
]
)
a_1^{[1]} = \sigma(z_1^{[1]})
a1[1]=σ(z1[1])
隐藏层第二个节点:
z
2
[
1
]
=
w
2
[
1
]
T
x
+
b
2
[
1
]
z_2^{[1]} = w_2^{[1]T}x + b_2^{[1]}
z2[1]=w2[1]Tx+b2[1]
a
2
[
1
]
=
σ
(
z
2
[
1
]
)
a_2^{[1]} = \sigma(z_2^{[1]})
a2[1]=σ(z2[1])
以此类推,四个节点均要实现这两个方程,因此隐藏层逻辑回归方程为:
z
[
1
]
=
[
w
1
[
1
]
T
w
2
[
1
]
T
w
3
[
1
]
T
w
4
[
1
]
T
]
[
x
1
x
2
x
3
]
+
[
b
1
[
1
]
b
2
[
1
]
b
3
[
1
]
b
4
[
1
]
]
=
W
[
1
]
a
[
0
]
+
b
[
1
]
=
[
w
1
[
1
]
T
x
+
b
1
[
1
]
w
2
[
1
]
T
x
+
b
2
[
1
]
w
3
[
1
]
T
x
+
b
3
[
1
]
w
4
[
1
]
T
x
+
b
4
[
1
]
]
=
[
z
1
[
1
]
z
2
[
1
]
z
3
[
1
]
z
4
[
1
]
]
z^{[1]} = \begin{bmatrix}w_1^{[1]T}\\w_2^{[1]T}\\w_3^{[1]T}\\w_4^{[1]T}\end{bmatrix}\begin{bmatrix}x_1\\x_2\\x_3\end{bmatrix} + \begin{bmatrix}b_1^{[1]}\\b_2^{[1]}\\b_3^{[1]}\\b_4^{[1]}\end{bmatrix}= W^{[1]}a^{[0]} + b^{[1]} = \begin{bmatrix}w_1^{[1]T}x + b_1^{[1]}\\w_2^{[1]T}x + b_2^{[1]}\\w_3^{[1]T}x + b_3^{[1]}\\w_4^{[1]T}x + b_4^{[1]}\end{bmatrix}= \begin{bmatrix}z_1^{[1]}\\z_2^{[1]}\\z_3^{[1]}\\z_4^{[1]}\end{bmatrix}
z[1]=⎣⎢⎢⎢⎡w1[1]Tw2[1]Tw3[1]Tw4[1]T⎦⎥⎥⎥⎤⎣⎡x1x2x3⎦⎤+⎣⎢⎢⎢⎡b1[1]b2[1]b3[1]b4[1]⎦⎥⎥⎥⎤=W[1]a[0]+b[1]=⎣⎢⎢⎢⎡w1[1]Tx+b1[1]w2[1]Tx+b2[1]w3[1]Tx+b3[1]w4[1]Tx+b4[1]⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡z1[1]z2[1]z3[1]z4[1]⎦⎥⎥⎥⎤
a
[
1
]
=
[
a
1
[
1
]
a
2
[
1
]
a
3
[
1
]
a
4
[
1
]
]
=
σ
(
z
[
1
]
)
a^{[1]} = \begin{bmatrix}a_1^{[1]}\\a_2^{[1]}\\a_3^{[1]}\\a_4^{[1]}\end{bmatrix} = \sigma(z^{[1]})
a[1]=⎣⎢⎢⎢⎡a1[1]a2[1]a3[1]a4[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])
说明:
- z [ 1 ] z^{[1]} z[1]shape = (4, 1), W [ 1 ] W^{[1]} W[1]shape = (4, 3), a [ 0 ] a^{[0]} a[0]shape = (3, 1), b [ 1 ] b^{[1]} b[1]shape = (4, 1), a [ 1 ] a^{[1]} a[1]shape = (4, 1)
- z [ 2 ] z^{[2]} z[2]shape = (1, 1), W [ 1 ] W^{[1]} W[1]shape = (1, 4), a [ 1 ] a^{[1]} a[1]shape = (4, 1), b [ 2 ] b^{[2]} b[2]shape = (1, 1), a [ 2 ] a^{[2]} a[2]shape = (1, 1)
- 事实上, W [ i ] W^{[i]} W[i]就是 w T w^T wT
- 以上为单隐藏层网络的逻辑回归
3.4 向量化多个样本(Vectorizing across multiple examples)
假设现在仍是单隐藏层网络结构,但样本数为 m 个,则:
- 此时的输入 x 变为 x ( i ) x^{(i)} x(i),i 从1到 m,表示 m 个样本的输入
- 此时激活函数
a
[
1
]
a^{[1]}
a[1]、
a
[
2
]
a^{[2]}
a[2]则变为
a
[
1
]
(
i
)
a^{[1](i)}
a[1](i)、
a
[
2
]
(
i
)
a^{[2](i)}
a[2](i),圆括号表示第 i 个样本,方括号表示是网络的第几层参数
现在向量化的逻辑回归表示如下:
z [ 1 ] ( i ) = W [ 1 ] ( i ) x ( i ) + b [ 1 ] z^{[1](i)} = W^{[1](i)}x^{(i)} + b^{[1]} z[1](i)=W[1](i)x(i)+b[1] a [ 1 ] ( i ) = σ ( z [ 1 ] ( i ) ) a^{[1](i)} = \sigma(z^{[1](i)}) a[1](i)=σ(z[1](i))
z [ 2 ] ( i ) = W [ 2 ] ( i ) a [ 1 ] ( i ) + b [ 2 ] z^{[2](i)} = W^{[2](i)}a^{[1](i)} + b^{[2]} z[2](i)=W[2](i)a[1](i)+b[2] a [ 2 ] ( i ) = σ ( z [ 2 ] ( i ) ) a^{[2](i)} = \sigma(z^{[2](i)}) a[2](i)=σ(z[2](i))
其中
X = [ x ( 1 ) x ( 2 ) ⋯ x ( m ) ] X = \begin{bmatrix}x^{(1)}&x^{(2)}&\cdots&x^{(m)}\end{bmatrix} X=[x(1)x(2)⋯x(m)]
Z [ 1 ] = [ z [ 1 ] ( 1 ) z [ 1 ] ( 2 ) ⋯ z [ 1 ] ( M ) ] Z^{[1]} = \begin{bmatrix}z^{[1](1)}&z^{[1](2)}&\cdots&z^{[1](M)}\end{bmatrix} Z[1]=[z[1](1)z[1](2)⋯z[1](M)]
A [ 1 ] = [ a [ 1 ] ( 1 ) a [ 1 ] ( 2 ) ⋯ a [ 1 ] ( M ) ] A^{[1]} = \begin{bmatrix}a^{[1](1)}&a^{[1](2)}&\cdots&a^{[1](M)}\end{bmatrix} A[1]=[a[1](1)a[1](2)⋯a[1](M)]
Tips : - 以上Z和A矩阵的横向表示 m 个不同的训练样本,纵向表示的是神经网络里的不同节点
- X矩阵的横向也表示 m 个不同的训练样本,纵向表示的是样本的 n 个特征
3.5 向量化实现的解释(Explanation for vectorized implementation)
为方便书写,将 b 先设为0,可得到一层网络的 m 个样本的向量化逻辑回归,当 b 不等于0时,用Python的广播特性直接将 b 矩阵加上即可,结果也是一样的
3.6 激活函数(Activation functions)
在上面的讨论里,我们用的都是 σ \sigma σ函数作为激活函数,而激活函数有很多种:
-
sigmoid 函数: a = σ ( z ) = 1 1 + e − z a = \sigma(z) = \frac{1}{1+e^{-z}} a=σ(z)=1+e−z1
- 在二分分类里,输出层的激活函数可以使用 sigmoid 函数,因为 y = 0 或 1,则激活函数的范围在0 ~ 1之间比较合理,其余情况不要使用
- 图像:
-
tanh 函数(双曲正切): a = t a n h ( z ) = e z − e − z e z + e − z a = tanh(z) = \frac{e^z-e^{-z}}{e^z+e^{-z}} a=tanh(z)=ez+e−zez−e−z
- 使数据的平均值更接近 0 ,更能使数据集中化
- 除了二分分类的输出层,其余情况下 tanh 函数都要比 sigmoid 函数性能更优越
- g ( z [ i ] ) g(z^{[i]}) g(z[i]) 表示第 i 层的激活函数,每一层网络的激活函数可以不同,所以也可记为 g [ i ] ( z [ i ] ) g^{[i]}(z^{[i]}) g[i](z[i])来区分不同的激活函数
- sigmoid 函数和 tanh 函数都有的缺点:当 z 很大或很小时,函数的斜率很小,即导数的梯度很小,会使梯度下降法变得缓慢
- 图像:
-
ReLU 函数(Rectified Linear Unit 修正线性单元): a = m a x ( 0 , z ) a = max(0,z) a=max(0,z)
- 当 z 大于0时,导数为1; 当 z 小于0时,导数为0;当 z = 0时,导数没有意义,因为在这一点,函数不可微,但在编程过程中,该点导数为约等于0的极小值,可以直接将这点的导数赋值为0或1
- ReLU 函数的缺点:当 z < 0时,导数为 0,但在实际问题中一般没有问题,但也可使用 泄漏ReLU函数(Leaky ReLU)来弥补这个问题
- 图像:
-
Leaky ReLU函数(泄漏的ReLU函数): a = m a x ( k z , z ) a = max(kz,z) a=max(kz,z) , k k k为实数, k k k常用0.01
- 当 z < 0 时,函数不再等于 0
- ReLU 函数和泄漏ReLU函数的优点:函数的斜率不会有接近 0 的区域,使梯度学习的速度提升
- 图像:
3.7 为什么需要非线性激活函数呢?(Why do you need non-linear activation functions?)
线性函数与线性函数的四则运算结果仍是一个线性函数,如果隐藏层用的是线性激活函数 linear activation function(恒等激活函数 Identity activation function),则无论有几层隐藏层网络,计算结果仍为一个线性函数,那么复杂度与没有隐藏层的标准逻辑回归是一样的,除非引入非线性激活函数。
可以用线性激活函数的情况:
- 学习的问题是回归问题,预测的 y 值是个实数,而不是0或1,比如房价预测
- 通常情况下输出层的激活函数可以用线性激活函数
- 隐藏层在压缩(compression)问题中可以用线性激活函数,在此不做讨论
3.8 激活函数的导数(Dericatives of activation functions)
Sigmoid activation function:
- sigmoid function :
g
(
z
)
=
1
1
+
e
−
z
g(z) = \frac{1}{1+e^{-z}}
g(z)=1+e−z1
d
g
(
z
)
d
z
=
1
1
+
e
−
z
(
1
−
1
1
+
e
−
z
)
=
g
(
z
)
(
1
−
g
(
z
)
)
\frac{dg(z)}{dz} = \frac{1}{1+e^{-z}}(1-\frac{1}{1+e^{-z}}) = g(z)(1-g(z))
dzdg(z)=1+e−z1(1−1+e−z1)=g(z)(1−g(z))
- z = 10, g(z) = 1, d g ( z ) d z \frac{dg(z)}{dz} dzdg(z) = 0; z = -10, g(z) = 0, d g ( z ) d z \frac{dg(z)}{dz} dzdg(z) = 0; z = 0, g(z) = 1/2, d g ( z ) d z \frac{dg(z)}{dz} dzdg(z) = 1/4.
- g ′ ( z ) = d g ( z ) d z = a ( 1 − a ) g^{'}(z) = \frac{dg(z)}{dz} = a(1-a) g′(z)=dzdg(z)=a(1−a)
- tanh function :
g
(
z
)
=
t
a
n
h
(
z
)
=
e
z
−
e
−
z
e
z
+
e
−
z
g(z) = tanh(z) = \frac{e^z-e^{-z}}{e^z+e^{-z}}
g(z)=tanh(z)=ez+e−zez−e−z
g
′
(
z
)
=
d
g
(
z
)
d
z
=
1
−
(
t
a
n
h
(
z
)
)
2
=
1
−
g
2
(
z
)
g^{'}(z) = \frac{dg(z)}{dz} = 1-(tanh(z))^2 = 1-g^2(z)
g′(z)=dzdg(z)=1−(tanh(z))2=1−g2(z)
- z = 10, tanh(z) = 1, g ′ ( z ) g^{'}(z) g′(z) = 0; z = -10, tanh(z) = -1, g ′ ( z ) g^{'}(z) g′(z) = 0; z = 0, tanh(z) = 0, g ′ ( z ) g^{'}(z) g′(z) = 1.
- a = g(z), g ′ ( z ) = 1 − a 2 g^{'}(z) = 1-a^2 g′(z)=1−a2
- ReLU :
g
(
z
)
=
m
a
x
(
0
,
z
)
g(z) = max(0,z)
g(z)=max(0,z)
g
′
(
z
)
=
{
0
z
<
0
1
z
>
0
u
n
d
e
f
i
n
e
d
z
=
0
g^{'}(z) = \begin{cases}0&z<0\\ 1&z>0 \\undefined &z = 0\end{cases}
g′(z)=⎩⎪⎨⎪⎧01undefinedz<0z>0z=0
- z = 0时,导数值可赋值为1/0,一般不影响结果,因为z值完全为0的概率极小
- Leaky ReLU : g ( z ) = m a x ( 0.01 z , z ) g(z) = max(0.01z,z) g(z)=max(0.01z,z) g ′ ( z ) = { 0.01 z < 0 1 z ≥ 0 g^{'}(z) = \begin{cases}0.01&z<0\\ 1&z\geq0 \end{cases} g′(z)={0.011z<0z≥0
3.9 神经网络的梯度下降法(Gradient descent for neural networks)
- Parameters : w [ 1 ] , b [ 1 ] , w [ 2 ] , b [ 2 ] w^{[1]},b^{[1]},w^{[2]},b^{[2]} w[1],b[1],w[2],b[2], n x = n [ 0 ] , n [ 1 ] , n [ 2 ] = 1 n_x = n^{[0]},n^{[1]},n^{[2]} = 1 nx=n[0],n[1],n[2]=1
- Cost function : J ( w [ 1 ] , b [ 1 ] , w [ 2 ] , b [ 2 ] ) = 1 m ∑ i = 1 n L ( y ^ , y ) J(w^{[1]},b^{[1]},w^{[2]},b^{[2]}) = \frac{1}{m}\sum_{i=1}^{n}\mathscr{L}(\hat{y},y) J(w[1],b[1],w[2],b[2])=m1∑i=1nL(y^,y), ,其中 y ^ = a [ 2 ] \hat{y} = a^{[2]} y^=a[2]
- Gradient descent :
- Repeat {
compute predicts ( y ^ ( i ) , i = 1 , ⋯ , m \hat{y}^{(i)},i = 1,\cdots,m y^(i),i=1,⋯,m)
d w [ 1 ] = d J d w [ 1 ] dw^{[1]} = \frac{dJ}{dw^{[1]}} dw[1]=dw[1]dJ, d b [ 1 ] = d J d b [ 1 ] db^{[1]} = \frac{dJ}{db^{[1]}} db[1]=db[1]dJ, ⋯ \cdots ⋯
w [ 1 ] : = w [ 1 ] − α d w [ 1 ] w^{[1]} := w^{[1]} - \alpha dw^{[1]} w[1]:=w[1]−αdw[1]
b [ 1 ] : = b [ 1 ] − α d b [ 1 ] b^{[1]} := b^{[1]} - \alpha db^{[1]} b[1]:=b[1]−αdb[1]
w [ 2 ] : = w [ 2 ] − α d w [ 2 ] w^{[2]} := w^{[2]} - \alpha dw^{[2]} w[2]:=w[2]−αdw[2]
b [ 2 ] : = b [ 2 ] − α d b [ 2 ] b^{[2]} := b^{[2]} - \alpha db^{[2]} b[2]:=b[2]−αdb[2]
}
- Repeat {
- Forward Propagation :
z [ 1 ] = w [ 1 ] X + b [ 1 ] z^{[1]} = w^{[1]}X+b^{[1]} z[1]=w[1]X+b[1]
A [ 1 ] = g [ 1 ] ( z [ 1 ] ) A^{[1]} = g^{[1]}(z^{[1]}) A[1]=g[1](z[1])
z [ 2 ] = w [ 2 ] X + b [ 2 ] z^{[2]} = w^{[2]}X+b^{[2]} z[2]=w[2]X+b[2]
A [ 2 ] = g [ 2 ] ( z [ 2 ] ) = σ ( z [ 2 ] ) A^{[2]} = g^{[2]}(z^{[2]}) = \sigma(z^{[2]}) A[2]=g[2](z[2])=σ(z[2]) - Back Propagation :
Y = [ y [ 1 ] y [ 2 ] ⋯ y [ m ] ] Y = [y^{[1]}\ y^{[2]} \cdots y^{[m]}] Y=[y[1] y[2]⋯y[m]]
d z [ 2 ] = A [ 2 ] − Y dz^{[2]} = A^{[2]} - Y dz[2]=A[2]−Y
d w [ 2 ] = 1 m d z [ 2 ] A [ 1 ] T dw^{[2]} = \frac{1}{m}dz^{[2]}A^{[1]T} dw[2]=m1dz[2]A[1]T
d b [ 2 ] = 1 m n p . s u m ( d z [ 2 ] , a x i s = 1 , k e e p d i m s = T r u e ) db^{[2]} = \frac{1}{m}np.sum(dz^{[2]},axis = 1, keepdims = True) db[2]=m1np.sum(dz[2],axis=1,keepdims=True) % 对矩阵水平相加求和,keepdims为了防止python自动输出秩为1的数组(python中的broadcasting)
d z [ 1 ] = w [ 2 ] T d z [ 2 ] ∗ g [ 1 ] ′ ( z [ 1 ] ) dz^{[1]} = w^{[2]T}dz^{[2]}*g^{[1]'}(z^{[1]}) dz[1]=w[2]Tdz[2]∗g[1]′(z[1]) % ( n [ 1 ] , m n^{[1]},m n[1],m) * ( n [ 1 ] , m n^{[1]},m n[1],m),* : elements product,即逐个元素相乘
d w [ 1 ] = 1 m d z [ 1 ] X T dw^{[1]} = \frac{1}{m}dz^{[1]}X^T dw[1]=m1dz[1]XT
d b [ 1 ] = 1 m n p . s u m ( d z [ 1 ] , a x i s = 1 , k e e p d i m s = T r u e ) db^{[1]} = \frac{1}{m}np.sum(dz^{[1]}, axis = 1, keepdims = True) db[1]=m1np.sum(dz[1],axis=1,keepdims=True) % ( n [ 1 ] , 1 n^{[1]},1 n[1],1)
3.10 直观理解反向传播(选修)(Backpropagation intuition(Optional))
* :矩阵元素对应相乘
dot :矩阵乘法
3.11 随机初始化(Random Initialization)
- logistic recession中,可以将参数全部初始化为0,但神经网络中不可以,为什么呢?
若将权重初始化为0(W, b可以初始化为0,因为W随机后隐藏单元的函数已经不同了,不需要再破坏其对称性),所有隐藏单元都是对称的,梯度下降将没有作用 - 随机初始化:
W [ 1 ] = n p . r a n d o m . r a n d n ( ( 2 , 2 ) ) ∗ 0.01 W^{[1]} = np.random.randn((2, 2)) * 0.01 W[1]=np.random.randn((2,2))∗0.01
b [ 1 ] = n p . z e r o ( ( 2 , 1 ) ) b^{[1]} = np.zero((2, 1)) b[1]=np.zero((2,1))
W [ 2 ] = n p . r a n d o m . r a n d n ( ( 1 , 2 ) ) ∗ 0.01 W^{[2]} = np.random.randn((1, 2)) * 0.01 W[2]=np.random.randn((1,2))∗0.01
b [ 2 ] = 0 b^{[2]} = 0 b[2]=0- Why * 0.01 ? Not 100 or 1000?
- 因为我们用tanh/sigmoid激活函数时,如果权重太大,则Z = Wx + b,Z就会很大,则激活函数的值将变化缓慢,也就是说梯度下降的速度会变化缓慢
- 如果网络深度很深的话,可能需要选取不是0.01的其他常数,但仍是一个较小的数
- Why * 0.01 ? Not 100 or 1000?