相关课件:https://download.csdn.net/download/haoyutiangang/10495501
2.1 训练 / 开发 / 测试集
- 训练集: 训练数据模型
- 开发验证集: 选择最好的模型
- 测试集: 无偏评估算法的运行状况
数据划分比例
- 小数据量(10-10000):60/20/20
- 大数据量(1000000) : 98/1/1
- 超大数据量: 99.5/0.25/0.25
- 应该确保开发验证集与测试集来自同一分布。
- 在不需要无偏评估的时候可以没有测试集,只有训练集和开发验证集,这时候有些人把开发验证集叫做测试集,所以当别人说他们只有训练集和测试集时,其实应该说只有训练集合开发验证集。
2.2 偏差 / 方差
- 高偏差:欠拟合
- 高方差:过拟合
评判
以下假设最优误差可以达到很小
训练集误差 | 测试集误差 | 结论 |
---|---|---|
1% | 10% | 高方差 |
15% | 16% | 高偏差 |
15% | 30% | 高偏差 & 高方差 |
0.5% | 1% | 低偏差 & 低方差 |
2.3 机器学习基础
- 高偏差:欠拟合
- 增加网络结构,比如增加隐藏层数量
- 训练更长的时间(不一定好使)
- (寻找合适的网络架构)
- 高方差:过拟合
- 获取更多的数据
- 正则化(regularization)
- (寻找合适的网络架构)
通过以上方法我们可以实现降低一方的同时不增加另一方,这也是深度学习对监督式学习的裨益。
2.4 正则化(Regularization)
过拟合(低偏差,高方差)的时候第一想到的应该是正则化,因为获取更多的数据有时并不那么容易。
2.4.1 逻辑回归(Logistic regression)
逻辑回归的L2正则化,因为W变化影响大,所以正则化时仅对w进行正则化
J
(
w
,
b
)
=
1
m
  
∑
i
=
1
m
L
(
y
^
(
i
)
,
y
(
i
)
)
+
λ
2
m
  
∣
∣
w
∣
∣
2
2
J(w,b) = \frac{1}{m}\;\sum_{i=1}{m}L(\hat y^{(i)}, y^{(i)}) + \frac{\lambda}{2m}\;||w||_2^2
J(w,b)=m1i=1∑mL(y^(i),y(i))+2mλ∣∣w∣∣22
- L2 正则化: 每一项平方的和
λ 2 m    ∣ ∣ w ∣ ∣ 2 2 = λ 2 m    ∑ j = 1 n x w j 2 = λ 2 m    w T w \frac{\lambda}{2m}\;||w||_2^2 = \frac{\lambda}{2m}\; \sum_{j=1}^{n_x}w_j^2 = \frac{\lambda}{2m}\;w^Tw 2mλ∣∣w∣∣22=2mλj=1∑nxwj2=2mλwTw - L1 正则化:每一项和的绝对值
λ m    ∣ ∣ w ∣ ∣ 1 = λ m    ∑ j = 1 n x ∣ w j ∣ \frac{\lambda}{m}\;||w||_1 = \frac{\lambda}{m}\; \sum_{j=1}^{n_x}|w_j| mλ∣∣w∣∣1=mλj=1∑nx∣wj∣
lambda 为Python保留字,编程时可以用lambd代替。
2.4.2 神经网络(Neural network)
神经网络的正则化
J
(
w
[
1
]
,
b
[
1
]
,
.
.
.
,
w
[
l
]
,
b
[
l
]
)
=
1
m
  
∑
i
=
1
m
L
(
y
^
(
i
)
,
y
(
i
)
)
+
λ
2
m
∑
l
=
1
L
∣
∣
w
[
l
]
∣
∣
F
2
J(w^[1],b^[1],...,w^[l],b^[l]) = \frac{1}{m}\;\sum_{i=1}^{m} L(\hat y^{(i)}, y^{(i)}) + \frac{\lambda}{2m} \sum_{l=1}{L} ||w^{[l]}||_F^2
J(w[1],b[1],...,w[l],b[l])=m1i=1∑mL(y^(i),y(i))+2mλl=1∑L∣∣w[l]∣∣F2
后面仍然是每一项平方的加和, 该矩阵范数称为“Frobenius norm”
2.4.3 权重衰减
加入正则化后,梯度变为:
d
W
[
l
]
=
(
f
r
o
m
_
b
a
c
k
p
r
o
p
)
+
λ
m
W
[
l
]
dW^{[l]} = (from\_backprop) + \frac{\lambda}{m}W^{[l]}
dW[l]=(from_backprop)+mλW[l]
梯度更新公式变为:
W
[
l
]
:
=
W
[
l
]
−
α
  
d
W
[
l
]
W^{[l]} := W^{[l]} - \alpha \; dW^{[l]}
W[l]:=W[l]−αdW[l]
代入可得:
W
[
l
]
:
=
W
[
l
]
−
α
[
(
f
r
o
m
_
b
a
c
k
p
r
o
p
)
+
λ
m
W
[
l
]
]
=
W
[
l
]
−
α
  
λ
m
W
[
l
]
−
α
(
f
r
o
m
_
b
a
c
k
p
r
o
p
)
=
(
1
−
α
λ
m
)
W
[
l
]
−
α
(
f
r
o
m
_
b
a
c
k
p
r
o
p
)
\begin{aligned} W^{[l]} &:= W^{[l]} - \alpha [(from\_backprop) + \frac{\lambda}{m}W^{[l]}] \\ &= W^{[l]} - \alpha \; \frac{\lambda}{m}W^{[l]} - \alpha (from\_backprop) \\ &= (1-\frac{\alpha\lambda}{m})W^{[l]} - \alpha (from\_backprop) \end{aligned}
W[l]:=W[l]−α[(from_backprop)+mλW[l]]=W[l]−αmλW[l]−α(from_backprop)=(1−mαλ)W[l]−α(from_backprop)
因为W系数小于1,所以相当于给了W一个衰减的参数,故L2范数正则化也被称为"权重衰减(Weight decay)"。
2.5 为什么正则化可以减少过拟合
上文介绍,L2正则化后
W
[
l
]
:
=
(
1
−
α
λ
m
)
W
[
l
]
−
α
(
f
r
o
m
_
b
a
c
k
p
r
o
p
)
W^{[l]} := (1-\frac{\alpha\lambda}{m})W^{[l]} - \alpha (from\_backprop)
W[l]:=(1−mαλ)W[l]−α(from_backprop)
当lambda变得很大时,W会变得很小甚至趋近于零,而神经网络就趋近于线性回归,由于线性回归不能解决复杂拟合的情况,所以在一定程度上可以起到消除过拟合的问题。
当然实际情况中,我们不会设置特别大的lambda, 但是从分析我们可以知道,存在一个lambda可以部分消除过拟合而不至于欠拟合。
2.6 Dropout 正则化
Dropout(随机失活): 随机消除一些神经元节点,保留下来的较小规模结构的神经网络进行训练。
2.6.1 实现方法
反向随机失活:Inverted dropout
假设我们要对第3层进行dropout(修改的是a3)
keep_prob = 0.8 # 设置神经元保留概率
d3 = np.random.rand(a3.shape[0], a3.shape[1]) < keep_prob # 随机消除矩阵
a3 = np.multiply(a3, d3) # 随机消除后的a3
a3 /= keep_prob # 除以keep_prob,保持Z4期望值不变,Z4 = W4+b4
仅在训练阶段使用dropout,在测试阶段不要使用,那样会使预测结果变得随机。
2.7 理解 Dropout
- 由于任何节点都可能被消除,所以无法依赖于某一个节点或者某一个输入特征,从而起到压缩权重的作用(权重分布更加均匀)
- 不同层的 keep_prob 可变,怀疑哪层造成过拟合则可以在那一层设置较小的keep_prob
- 通产不对输入层进行dropout
缺点: 由于每次J都在变化,所以无法绘制出梯度下降图。
使用:
- 关闭dropout, 即设置keep_prob = 1
- 运行代码,确保J单调递减
- 再打开dropout进行训练
2.8 其他正则化方法
- 数据扩增(Data augmentation): 图片变换增加图片数据量,转换,剪裁等等。
- early_stopping: 提前停止梯度下降。
- 缺点: 无法单独处理偏差和方差,经常在方差不大的时候停止,此时偏差不够理想。
2.9 归一化输入
讲的是对输入的归一化,归一化到同样的范围内
归一化均值
μ = 1 m ∑ i = 1 m x ( i ) x = x − μ \begin{aligned} &\mu = \frac{1}{m}\sum_{i=1}^{m}x^{(i)} \\ &x = x - \mu \end{aligned} μ=m1i=1∑mx(i)x=x−μ
归一化方差:
σ 2 = 1 m ∑ i = 1 m x ( i ) 2 x = x / σ 2 \begin{aligned} &\sigma^2 = \frac{1}{m}\sum_{i=1}^{m}x^{(i)^2} \\ &x = x / \sigma^2 \end{aligned} σ2=m1i=1∑mx(i)2x=x/σ2
在训练集和测试集上使用同样的均值和方差进行归一化
不使用归一化的代价函数中很可能我们需要很多次迭代才能到达全局最优解;如果使用了归一化,无论从哪个位置开始迭代,我们都能以相对很少的迭代次数找到全局最优解。
2.10 梯度消失与梯度爆炸
假设g(z) = z; b = 0
y ^ = W [ l ] W [ l − 1 ] . . . W [ 1 ] X \hat y = W^{[l]}W^{[l-1]}...W^{[1]}X y^=W[l]W[l−1]...W[1]X
- 当各层W相等且大于1时,激活函数的值将以指数级递增
- 当各层W相等且小于1时,激活函数的值将以指数级递减
在梯度函数上出现的以指数级递增或者递减的情况就分别称为梯度爆炸或者梯度消失。
2.11 神经网络的权重初始化
随机初始化权重W
Z
=
W
1
X
1
+
W
2
X
2
+
W
n
X
n
+
b
Z = W_1X_1+W_2X_2+W_nX_n +b
Z=W1X1+W2X2+WnXn+b
为了消除梯度消失和梯度爆炸,我们想把W设置为1附近。
所以可以设置w_i 为1/n
w
[
l
]
=
n
p
.
r
a
n
d
o
m
.
r
a
n
d
n
(
s
h
a
p
e
)
∗
n
p
.
s
q
r
t
(
1
n
[
l
−
1
]
)
w^{[l]} = np.random.randn(shape)*np.sqrt(\frac{1}{n^{[l-1]}})
w[l]=np.random.randn(shape)∗np.sqrt(n[l−1]1)
这里除以的是输入个数的算术平方根。
-
tanh 是合适于
n p . s q r t ( 1 n [ l − 1 ] ) np.sqrt(\frac{1}{n^{[l-1]}}) np.sqrt(n[l−1]1)
又称为Xavier初始化 -
relu适合于
n p . s q r t ( 2 n [ l − 1 ] ) np.sqrt(\frac{2}{n^{[l-1]}}) np.sqrt(n[l−1]2)
当然你也可以将其作为一个参数进行调试,但是相比于其他参数而言,这个参数调参的优先级较低。
2.12 梯度的数值逼近
使用双边误差的方法去逼近导数更准确, 精度比单边导数高很多
f
′
(
θ
)
=
l
i
m
ε
→
0
f
(
θ
+
ε
)
−
f
(
θ
−
ε
)
2
ε
O
(
ε
2
)
f'(\theta) = lim_{\varepsilon\to0} \frac{f(\theta + \varepsilon) - f(\theta - \varepsilon)}{2\varepsilon} \\ O(\varepsilon^2)
f′(θ)=limε→02εf(θ+ε)−f(θ−ε)O(ε2)
2.13 梯度检验
因为复杂函数求导比较复杂,容易出错,所以需要进行梯度检验,验证我们的反向传播计算是否准确。
- 参数
W [ 1 ] , b [ 1 ] , W [ 1 ] , b [ 1 ] , . . . , W [ n ] , b [ n ] d W [ 1 ] , d b [ 1 ] , d W [ 1 ] , d b [ 1 ] , . . . , d W [ n ] , d b [ n ] W^{[1]}, b^{[1]}, W^{[1]}, b^{[1]},..., W^{[n]}, b^{[n]}\\ dW^{[1]}, db^{[1]}, dW^{[1]}, db^{[1]},..., dW^{[n]}, db^{[n]} W[1],b[1],W[1],b[1],...,W[n],b[n]dW[1],db[1],dW[1],db[1],...,dW[n],db[n]
- 参数向量连接:将各个参数转化为列向量(n*1的矩阵),然后按照顺序连接这些列向量为一个大的列向量 theta。
- 导参数向量连接:同上
- 逼近求导:循环向量的每一个值i,利用双边导数定义计算 J_i+ , J_i- , 从而计算出 J’(下面说明 J_i+的计算方法,J_i-类似)
- 向量矩阵的第 i 个值加上很小的 epsilon
- 将向量反向转化为参数 W,…b
- 利用各个参数求出 J 是为 J_i+, 同理可求J_i-
- 3中循环各个 i 后计算的 J’ 组合为一个导数列向量d_theta_approx, 与2的 d_theta 进行梯度检验
c h e c k = ∣ ∣ d θ a p p r o x − d θ ∣ ∣ 2 ∣ ∣ d θ a p p r o x ∣ ∣ 2 + ∣ ∣ d θ ∣ ∣ 2 check = \frac{ || d\theta_{approx} - d\theta ||_2}{||d\theta_{approx}||_2 + ||d\theta ||_2} check=∣∣dθapprox∣∣2+∣∣dθ∣∣2∣∣dθapprox−dθ∣∣2
其中 ||.||_2 表示欧几里得范数,表示平方只和的平方根,得到欧氏距离。
- check 的值:
- 10e(-7) great!
- 10e(-5) please check!
- 10e(-3) wrong!
2.14 关于梯度检验实现的注记
- 不要在训练中使用
- 仅仅用于 debug
- 如果梯度检验失败,仔细检查d_theta_approx的每一项,哪一项与 d_theta 相差越大,对应到参数 W或 b.可能帮你定位到 bug
- 记着使用正则化
- 不可与 dropout 同时使用,此时可以设置 dropout 的 keep_prob = 1.0
- 随机初始化参数为比较小的值