训练集、验证集、测试集(Train, Dev, Test Sets)
当数据量小的时候, 70% 训练, 30% 测试;或 60% 训练、20% 验证、20%测试. 当我们有大于100万条数据时, 测试集验证集各取1万条即可, 足以评估单个分类器.
确保验证集和测试集的数据来自同一分布.
如果不需要无偏估计, 可以不设置测试集. 当没设立测试集的时候, 验证集通常被人们称为测试集.
偏差、方差(Bias, Variance)
高偏差(high bias)称为"欠拟合"(underfitting), 练集误差与验证集误差都高.
高方差(high variance)称为过拟合(overfitting), 训练集误差很低而验证集误差很高. 解决方法是正则化或准备更多的数据.
正则化(Regularization)
逻辑回归中的L1正则化, L2正则化
对于L1正则化, 为代价函数添加L1范数:
J(w,b)=1m∑i=1mL(a(i),y(i))+λ2m∣∣w∣∣1
J(w, b) = \frac{1}{m} \sum^{m}_{i=1} \mathcal{L}(a^{(i)}, y^{(i)}) + \frac{\lambda}{2m} ||w||_1
J(w,b)=m1i=1∑mL(a(i),y(i))+2mλ∣∣w∣∣1
其中
∣∣w∣∣1=∑j=1nx∣wj∣
||w||_1 = \sum^{n_x}_{j=1} |w_j|
∣∣w∣∣1=j=1∑nx∣wj∣
使用L1正则化, w最终会是稀疏的(w中含很多0), 有利于压缩模型, 但也没有降低太多内存, 所以不能将压缩作为L1正则化的目的. 通常我们使用L2正则化.
对于L2正则化, 为代价函数添加L2范数:
J(w,b)=1m∑i=1mL(a(i),y(i))+λ2m∣∣w∣∣22
J(w, b) = \frac{1}{m} \sum^{m}_{i=1} \mathcal{L}(a^{(i)}, y^{(i)}) + \frac{\lambda}{2m} ||w||_2^2
J(w,b)=m1i=1∑mL(a(i),y(i))+2mλ∣∣w∣∣22
其中
∣∣w∣∣22=∑j=1nxwj2=wTw
||w||^2_2 = \sum^{n_x}_{j=1} w_j^2 = w^Tw
∣∣w∣∣22=j=1∑nxwj2=wTw
尽管 bbb 也是参数, 但我们没有必要添加 λ2mb2\frac{\lambda}{2m}b^22mλb2 项, 因为 www 几乎涵盖了所有参数, 而 bbb 只是众多参数中的一个, 可以忽略不计(当然加上也没问题).
神经网络中的L2正则化
弗罗贝尼乌斯范数(相当于矩阵的L2范数):
∣∣w[l]∣∣F2=∑i=1n[l−1]∑j=1n[l](wij[l])2
||w^{[l]}||_F^2 = \sum_{i=1}^{n^{[l-1]}} \sum_{j=1}^{n^{[l]}} (w_{ij}^{[l]})^2
∣∣w[l]∣∣F2=i=1∑n[l−1]j=1∑n[l](wij[l])2
则
J(w,b)=1m∑i=1mL(y^(i),y(i))+λ2m∑l=1L∣∣w∣∣F2 J(w, b) = \frac{1}{m} \sum^{m}_{i=1} \mathcal{L}(\hat{y}^{(i)}, y^{(i)}) + \frac{\lambda}{2m} \sum_{l=1}^{L}||w||_F^2 J(w,b)=m1i=1∑mL(y^(i),y(i))+2mλl=1∑L∣∣w∣∣F2
则在反向传播时,
dw[l]=(from backprop)+λmw[l]w[l]=w[l]−αdw[l]
\begin{aligned}
dw^{[l]} & = (\text{from backprop}) + \frac{\lambda}{m}w^{[l]} \\
w^{[l]} & = w^{[l]} -\alpha dw^{[l]} \\
\end{aligned}
dw[l]w[l]=(from backprop)+mλw[l]=w[l]−αdw[l]
正则项说明, 无论 w[l]w^{[l]}w[l] 是什么, 我们都试图使之更小(趋于0). 则计算得的 z[l]=w[l]a[l−1]+b[l]z^{[l]} = w^{[l]}a^{[l-1]} + b^{[l]}z[l]=w[l]a[l−1]+b[l]此时也更小, z[l]z^{[l]}z[l] 更容易(以tanh例)落在激活函数 g(z[l])g(z^{[l]})g(z[l]) 中间那一段接近线性的部分, 以达到简化网络的目的(线性的激活函数使得无论多少层的网络, 效果都和一层一样).
随机失活(Dropout)正则化
对每一轮的训练, Dropout 遍历网络的每一层, 设置神经网络中每一层每个节点的失活概率, 被随机选中失活的节点临时被消除, 不参与本轮的训练, 于是得到一个更小的网络.
最常用的为反向随机失活(Inverted Dropout).
该方法在向前传播时, 根据随机失活的概率 (例如0.2), 将每一层(例如 lll 层)的 a[l]a^{[l]}a[l] 矩阵(a=g(z))中被选中失活的元素置为0. 则该层的 a[l]a^{[l]}a[l] 相当于少了 20% 的元素. 为了不影响下一层 z[l+1]z^{[l+1]}z[l+1] 的期望值, 我们需要 a[l]a^{[l]}a[l] /= 0.8 以修正权重.
由于训练时的 "a[l]a^{[l]}a[l] /= 0.8" 修复了权重, 在测试阶段无需使用 Dropout.
Dropout 不能与梯度检验同时使用, 因为 Dropout 在梯度下降上的代价函数J难以计算.
其他正则化
数据扩增: 比如训练分类猫咪的图片, 将图片左右翻转、旋转一个小角度、稍微变形处理等, 可以人工合成数据.
Early Stopping: 运行梯度下降时, 我们可以绘制训练误差, 当验证集误差不降反增的时候, 停止训练. 缺点是可能导致代价J值不够小, 却又没解决继续训练可能导致的过拟合问题.
归一化(Normalizing)
输入的归一化有两个步骤: 均值调整为0, 方差归一化. 归一化直观的理解就是使得代价函数更圆, 更容易优化代价函数.
梯度消失/爆炸(Vanishing / Exploding Gradients)
为了方便理解,假设使用了线性激活函数 g(z)=z , 且
W=W[L−1]=...=W[2]=W[1]
W=W^{[L-1]}=...=W^{[2]}=W^{[1]}
W=W[L−1]=...=W[2]=W[1]
则
y^=W[L]W[L−1]...W[2]W[1]x=W[L]WL−1x
\begin{aligned}
\hat{y} & = W^{[L]}W^{[L-1]}...W^{[2]}W^{[1]}x \\
& = W^{[L]}W^{L-1}x
\end{aligned}
y^=W[L]W[L−1]...W[2]W[1]x=W[L]WL−1x
可知若 WWW 中有元素权重为 1.5 , 则最终得到 1.5L−11.5^{L-1}1.5L−1 , 若层数很深, 计算得 y^\hat{y}y^ 也很大; 同理若权重为 0.5 , 进行 L−1L-1L−1 次幂运算后值会很小. 这便是梯度爆炸与梯度消失.
有效的解决方案: 由于 z=w1x1+w2x2+...+wnxnz=w_1x_1+w_2x_2+...+w_nx_nz=w1x1+w2x2+...+wnxn (忽略 bbb ), 为了预防 zzz 太大或太小, 则nnn 越大时, 期望 wiw_iwi 越小, 则在随机(0~1)初始化 WWW 时, 我们对其乘上一个小于1的倍数, 使之更小.
对于Tanh, 权重乘上 1n[l−1]\sqrt{\frac{1}{n^{[l-1]}}}n[l−1]1, 或者 2n[l−1]+n[l]\sqrt{\frac{2}{n^{[l-1]}+n^{[l]}}}n[l−1]+n[l]2
对于Relu, 权重乘上 2n[l−1]\sqrt{\frac{2}{n^{[l-1]}}}n[l−1]2
梯度检验
在反向传播的时候, 如果怕自己 dθ[i]=∂J∂θid\theta[i] = \frac{\partial J}{\partial \theta_i}dθ[i]=∂θi∂J 等算错, 可以用导数的定义, 计算
dθapprox[i]=J(θ1,θ2,...,θi+ε,...)−J(θ1,θ2,...,θi−ε,...)2ε
d\theta_{approx}[i] = \frac{J(\theta_1, \theta_2, ..., \theta_i + \varepsilon, ...) - J(\theta_1, \theta_2, ..., \theta_i - \varepsilon, ...)}{2\varepsilon}
dθapprox[i]=2εJ(θ1,θ2,...,θi+ε,...)−J(θ1,θ2,...,θi−ε,...)
然后根据两者误差估计自己是否算错. 该方法仅用来调试, 且不能同 Dropout 同时使用.