0%

Coursera Deep Learning笔记 正则化与梯度相关

训练集、验证集、测试集(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) = \frac{1}{m} \sum^{m}_{i=1} \mathcal{L}(a^{(i)}, y^{(i)}) + \frac{\lambda}{2m} ||w||_1 \]

其中 \[ ||w||_1 = \sum^{n_x}_{j=1} |w_j| \]

使用L1正则化, w最终会是稀疏的(w中含很多0), 有利于压缩模型, 但也没有降低太多内存, 所以不能将压缩作为L1正则化的目的. 通常我们使用L2正则化.

对于L2正则化, 为代价函数添加L2范数: \[ J(w, b) = \frac{1}{m} \sum^{m}_{i=1} \mathcal{L}(a^{(i)}, y^{(i)}) + \frac{\lambda}{2m} ||w||_2^2 \]

其中 \[ ||w||^2_2 = \sum^{n_x}_{j=1} w_j^2 = w^Tw \]

尽管 \(b\) 也是参数, 但我们没有必要添加 \(\frac{\lambda}{2m}b^2\) 项, 因为 \(w\) 几乎涵盖了所有参数, 而 \(b\) 只是众多参数中的一个, 可以忽略不计(当然加上也没问题).

神经网络中的L2正则化

弗罗贝尼乌斯范数(相当于矩阵的L2范数): \[ ||w^{[l]}||_F^2 = \sum_{i=1}^{n^{[l-1]}} \sum_{j=1}^{n^{[l]}} (w_{ij}^{[l]})^2 \]

\[ 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 \]

则在反向传播时, \[ \begin{aligned} dw^{[l]} & = (\text{from backprop}) + \frac{\lambda}{m}w^{[l]} \\ w^{[l]} & = w^{[l]} -\alpha dw^{[l]} \\ \end{aligned} \]

正则项说明, 无论 \(w^{[l]}\) 是什么, 我们都试图使之更小(趋于0). 则计算得的 \(z^{[l]} = w^{[l]}a^{[l-1]} + b^{[l]}\)此时也更小, \(z^{[l]}\) 更容易(以tanh例)落在激活函数 \(g(z^{[l]})\) 中间那一段接近线性的部分, 以达到简化网络的目的(线性的激活函数使得无论多少层的网络, 效果都和一层一样).

随机失活(Dropout)正则化

对每一轮的训练, Dropout 遍历网络的每一层, 设置神经网络中每一层每个节点的失活概率, 被随机选中失活的节点临时被消除, 不参与本轮的训练, 于是得到一个更小的网络.

最常用的为反向随机失活(Inverted Dropout).

该方法在向前传播时, 根据随机失活的概率 (例如0.2), 将每一层(例如 \(l\) 层)的 \(a^{[l]}\) 矩阵(a=g(z))中被选中失活的元素置为0. 则该层的 \(a^{[l]}\) 相当于少了 20% 的元素. 为了不影响下一层 \(z^{[l+1]}\) 的期望值, 我们需要 \(a^{[l]}\) /= 0.8 以修正权重.

由于训练时的 "\(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]} \]

\[ \begin{aligned} \hat{y} & = W^{[L]}W^{[L-1]}...W^{[2]}W^{[1]}x \\ & = W^{[L]}W^{L-1}x \end{aligned} \]

可知若 \(W\) 中有元素权重为 1.5 , 则最终得到 \(1.5^{L-1}\) , 若层数很深, 计算得 \(\hat{y}\) 也很大; 同理若权重为 0.5 , 进行 \(L-1\) 次幂运算后值会很小. 这便是梯度爆炸与梯度消失.

有效的解决方案: 由于 \(z=w_1x_1+w_2x_2+...+w_nx_n\) (忽略 \(b\) ), 为了预防 \(z\) 太大或太小, 则\(n\) 越大时, 期望 \(w_i\) 越小, 则在随机(0~1)初始化 \(W\) 时, 我们对其乘上一个小于1的倍数, 使之更小.

对于Tanh, 权重乘上 \(\sqrt{\frac{1}{n^{[l-1]}}}\), 或者 \(\sqrt{\frac{2}{n^{[l-1]}+n^{[l]}}}\)

对于Relu, 权重乘上 \(\sqrt{\frac{2}{n^{[l-1]}}}\)

梯度检验

在反向传播的时候, 如果怕自己 \(d\theta[i] = \frac{\partial J}{\partial \theta_i}\) 等算错, 可以用导数的定义, 计算 \[ d\theta_{approx}[i] = \frac{J(\theta_1, \theta_2, ..., \theta_i + \varepsilon, ...) - J(\theta_1, \theta_2, ..., \theta_i - \varepsilon, ...)}{2\varepsilon} \]

然后根据两者误差估计自己是否算错. 该方法仅用来调试, 且不能同 Dropout 同时使用.