做试卷的网站,空间网站打不开,怎样创建网站流程,深圳东门步行街图片大纲
验证集loss上升#xff0c;准确率也上升#xff08;即将overfitting#xff1f;#xff09;训练集loss一定为要为0吗
Q1. 验证集loss上升#xff0c;准确率也上升
随着置信度的增加#xff0c;一小部分点的预测结果是错误的#xff08;log lik 给出了指数级的惩…大纲
验证集loss上升准确率也上升即将overfitting训练集loss一定为要为0吗
Q1. 验证集loss上升准确率也上升
随着置信度的增加一小部分点的预测结果是错误的log lik 给出了指数级的惩罚在损失中占主导地位。与此同时大量其他点开始预测良好argmax plabel主导了预测的准确性。 Q2. 训练集loss一定为要为0吗
一般来说我们是用训练集来训练模型但希望的是验证机的损失越小越好而正常来说训练集的损失降到一定值后验证集的损失就会开始上升因此没必要把训练集的损失降低到 0
既然如此在已经达到了某个阈值之后我们可不可以做点别的事情来提升模型性能呢ICML2020 的论文《Do We Need Zero Training Loss After Achieving Zero Training Error?》回答了这个问题不过实际上它并没有很好的描述 “为什么”而只是提出了 “怎么做”
假设原来的损失函数是 L ( θ ) \mathcal {L}(\theta) L(θ)现在改为 L ~ ( θ ) \tilde {\mathcal {L}}(\theta) L~(θ) L ~ ( θ ) ∣ L ( θ ) − b ∣ b (1) \tilde{\mathcal{L}}(\theta)|\mathcal{L}(\theta)-b|b\tag{1} L~(θ)∣L(θ)−b∣b(1)
其中 b b b 是预先设定的阈值。当 L ( θ ) b \mathcal {L}(\theta)b L(θ)b 时 L ~ ( θ ) L ( θ ) \tilde {\mathcal {L}}(\theta)\mathcal {L}(\theta) L~(θ)L(θ)这时就是执行普通的梯度下降而 L ( θ ) b \mathcal {L}(\theta)b L(θ)b 时 L ~ ( θ ) 2 b − L ( θ ) \tilde {\mathcal {L}}(\theta)2b-\mathcal {L}(\theta) L~(θ)2b−L(θ)注意到损失函数变号了所以这时候是梯度上升。因此总的来说就是以 b b b 为阈值低于阈值时反而希望损失函数变大。论文把这个改动称为 “Flooding” 这样做有什么效果呢论文显示在某些任务中训练集的损失函数经过这样处理后验证集的损失能出现 “二次下降Double Descent”如下图 如何解释这个方法呢可以想像当损失函数达到 b b b 之后训练流程大概就是在交替执行梯度下降和梯度上升。直观想的话感觉一步上升一步下降似乎刚好抵消了。事实真的如此吗我们来算一下看看。假设先下降一步后上升一步学习率为 ε \varepsilon ε那么 θ n θ n − 1 − ε g ( θ n − 1 ) θ n 1 θ n ε g ( θ n ) \begin{equation}\begin{aligned}\theta_n \theta_{n-1} - \varepsilon g(\theta_{n-1})\\ \theta_{n1} \theta_n \varepsilon g(\theta_n) \end{aligned}\tag{2}\end{equation} θnθn−1−εg(θn−1)θn1θnεg(θn)(2)
其中 g ( θ ) ∇ θ L ( θ ) g (\theta)\nabla_{\theta}\mathcal {L}(\theta) g(θ)∇θL(θ)现在我们有 θ n 1 θ n − 1 − ε g ( θ n − 1 ) ε g ( θ n − 1 − ε g ( θ n − 1 ) ) ≈ θ n − 1 − ε g ( θ n − 1 ) ε ( g ( θ n − 1 ) − ε ∇ θ g ( θ n − 1 ) g ( θ n − 1 ) ) θ n − 1 − ε 2 2 ∇ θ ∥ g ( θ n − 1 ) ∥ 2 \begin{equation}\begin{aligned}\theta_{n1} \, \theta_{n-1} - \varepsilon g(\theta_{n-1}) \varepsilon g\big(\theta_{n-1} - \varepsilon g(\theta_{n-1})\big)\\ \approx\,\theta_{n-1} - \varepsilon g(\theta_{n-1}) \varepsilon \big(g(\theta_{n-1}) - \varepsilon \nabla_{\theta} g(\theta_{n-1}) g(\theta_{n-1})\big)\\ \,\theta_{n-1} - \frac{\varepsilon^2}{2}\nabla_{\theta}\Vert g(\theta_{n-1})\Vert^2 \end{aligned}\tag{3}\end{equation} θn1≈θn−1−εg(θn−1)εg(θn−1−εg(θn−1))θn−1−εg(θn−1)ε(g(θn−1)−ε∇θg(θn−1)g(θn−1))θn−1−2ε2∇θ∥g(θn−1)∥2(3) 近似那一步实际上是使用了泰勒展开我们将 θ n − 1 \theta_{n-1} θn−1 看作 x x x ε g ( θ n − 1 ) \varepsilon g (\theta_{n-1}) εg(θn−1) 看作 Δ x \Delta x Δx由于 g ( x − Δ x ) − g ( x ) − Δ x ∇ x g ( x ) \frac{g(x - \Delta x) - g(x)}{-\Delta x} \nabla_x g(x) −Δxg(x−Δx)−g(x)∇xg(x) 所以 g ( x − Δ x ) g ( x ) − Δ x ∇ x g ( x ) g(x - \Delta x) g(x) - \Delta x \nabla_x g(x) g(x−Δx)g(x)−Δx∇xg(x) 最终的结果就是相当于学习率为 ε 2 2 \frac {\varepsilon^2}{2} 2ε2、损失函数为梯度惩罚 ∥ g ( θ ) ∥ 2 ∥ ∇ θ L ( θ ) ∥ 2 \Vert g (\theta)\Vert^2 \Vert \nabla_{\theta} \mathcal {L}(\theta)\Vert^2 ∥g(θ)∥2∥∇θL(θ)∥2 的梯度下降。更妙的是改为 “先上升再下降”其表达式依然是一样的这不禁让我想起 “先涨价 10% 再降价 10%” 和 “先降价 10% 再涨价 10% 的故事”。因此平均而言Flooding 对损失函数的改动相当于在保证了损失函数足够小之后去最小化 ∥ ∇ x L ( θ ) ∥ 2 \Vert \nabla_x \mathcal {L}(\theta)\Vert^2 ∥∇xL(θ)∥2也就是推动参数往更平稳的区域走这通常能提高泛化性更好地抵抗扰动因此一定程度上就能解释 Flooding 有作用的原因了
本质上来讲这跟往参数里边加入随机扰动、对抗训练等也没什么差别只不过这里是保证了损失足够小后再加扰动
想要使用 Flooding 非常简单只需要在原有代码基础上增加一行即可
logits model(x)
loss criterion(logits, y)
loss (loss - b).abs() b # This is it!
optimizer.zero_grad()
loss.backward()
optimizer.step()有心是用这个方法的读者可能会纠结于 b b b 的选择原论文说 b b b 的选择是一个暴力迭代的过程需要多次尝试 The flood level is chosen from b ∈ { 0 , 0.01 , 0.02 , . . . , 0.50 } b\in \{0, 0.01,0.02,...,0.50\} b∈{0,0.01,0.02,...,0.50} 不过笔者倒是有另外一个脑洞 b b b 无非就是决定什么时候开始交替训练罢了那如果我们从一开始就用不同的学习率进行交替训练呢也就是自始自终都执行 θ n θ n − 1 − ε 1 g ( θ n − 1 ) θ n 1 θ n ε 2 g ( θ n ) \begin{equation}\begin{aligned}\theta_n \theta_{n-1} - \varepsilon_1 g(\theta_{n-1})\\ \theta_{n1} \theta_n \varepsilon_2 g(\theta_n) \end{aligned}\tag{4}\end{equation} θnθn−1−ε1g(θn−1)θn1θnε2g(θn)(4)
其中 ε 1 ε 2 \varepsilon_1 \varepsilon_2 ε1ε2这样我们就把 b b b 去掉了引入了 ε 1 , ε 2 \varepsilon_1, \varepsilon_2 ε1,ε2 的选择天下没有免费的午餐。重复上述近似展开我们就得到 θ n 1 θ n − 1 − ε 1 g ( θ n − 1 ) ε 2 g ( θ n − 1 − ε 1 g ( θ n − 1 ) ) ≈ θ n − 1 − ε 1 g ( θ n − 1 ) ε 2 ( g ( θ n − 1 ) − ε 1 ∇ θ g ( θ n − 1 ) g ( θ n − 1 ) ) θ n − 1 − ( ε 1 − ε 2 ) g ( θ n − 1 ) − ε 1 ε 2 2 ∇ θ ∥ g ( θ n − 1 ) ∥ 2 θ n − 1 − ( ε 1 − ε 2 ) ∇ θ [ L ( θ n − 1 ) ε 1 ε 2 2 ( ε 1 − ε 2 ) ∥ ∇ θ L ( θ n − 1 ) ∥ 2 ] \begin{equation}\begin{aligned} \theta_{n1} \, \theta_{n-1} - \varepsilon_1g(\theta_{n-1})\varepsilon_2g(\theta_{n-1} - \varepsilon_1g(\theta_{n-1}))\\ \approx\, \theta_{n-1} - \varepsilon_1g(\theta_{n-1}) \varepsilon_2(g(\theta_{n-1}) - \varepsilon_1\nabla_\theta g(\theta_{n-1})g(\theta_{n-1}))\\ \, \theta_{n-1} - (\varepsilon_1 - \varepsilon_2) g(\theta_{n-1}) - \frac{\varepsilon_1\varepsilon_2}{2}\nabla_{\theta}\Vert g(\theta_{n-1})\Vert^2\\ \,\theta_{n-1} - (\varepsilon_1 - \varepsilon_2)\nabla_{\theta}\left[\mathcal{L}(\theta_{n-1}) \frac{\varepsilon_1\varepsilon_2}{2(\varepsilon_1 - \varepsilon_2)}\Vert \nabla_{\theta}\mathcal{L}(\theta_{n-1})\Vert^2\right] \end{aligned}\tag{5}\end{equation} θn1≈θn−1−ε1g(θn−1)ε2g(θn−1−ε1g(θn−1))θn−1−ε1g(θn−1)ε2(g(θn−1)−ε1∇θg(θn−1)g(θn−1))θn−1−(ε1−ε2)g(θn−1)−2ε1ε2∇θ∥g(θn−1)∥2θn−1−(ε1−ε2)∇θ[L(θn−1)2(ε1−ε2)ε1ε2∥∇θL(θn−1)∥2](5)
这就相当于自始自终都在用学习率 ε 1 − ε 2 \varepsilon_1-\varepsilon_2 ε1−ε2 来优化损失函数 L ( θ ) ε 1 ε 2 2 ( ε 1 − ε 2 ) ∥ ∇ θ L ( θ ) ∥ 2 \mathcal {L}(\theta) \frac {\varepsilon_1\varepsilon_2}{2 (\varepsilon_1 - \varepsilon_2)}\Vert\nabla_{\theta}\mathcal {L}(\theta)\Vert^2 L(θ)2(ε1−ε2)ε1ε2∥∇θL(θ)∥2 了也就是说一开始就把梯度惩罚给加了进去这样能提升模型的泛化性能吗《Backstitch: Counteracting Finite-sample Bias via Negative Steps》里边指出这种做法在语音识别上是有效的请读者自行测试甄别
效果检验
我随便在网上找了个竞赛然后利用别人提供的以 BERT 为 baseline 的代码对 Flooding 的效果进行了测试下图分别是没有做 Flooding 和参数 b 0.7 b0.7 b0.7 的 Flooding 损失值变化图值得一提的是没有做 Flooding 的验证集最低损失值为 0.814198而做了 Flooding 的验证集最低损失值为 0.809810
根据知乎文章一行代码发一篇 ICML底下用户 Curry 评论所言“通常来说 b b b 值需要设置成比 Validation Error 开始上升 ’ 的值更小1/2 处甚至更小结果更优”所以我仔细观察了下没有加 Flooding 模型损失值变化图大概在 loss 为 0.75 到 1.0 左右的时候开始出现过拟合现象因此我又分别设置了 b 0.4 b0.4 b0.4 和 b 0.5 b0.5 b0.5做了两次 Flooding 实验结果如下图
值得一提的是 b 0.4 b0.4 b0.4 和 b 0.5 b0.5 b0.5 时验证集上的损失值最低仅为 0.809958 和 0.796819而且很明显验证集损失的整体上升趋势更加缓慢。接下来我做了一个实验主要是验证 “继续脑洞” 部分以不同的学习率一开始就交替着做梯度下降和梯度上升的效果其中梯度下降的学习率我设为 1 e − 5 1e-5 1e−5梯度上升的学习率为 1 e − 6 1e-6 1e−6结果如下图验证集的损失最低仅有 0.783370
References
我们真的需要把训练集的损失降低到零吗 LossUpAccUp -Github https://wmathor.com/index.php/archives/1551/