• softmax中的smooth程度控制


    转载链接如下:

    Softmax理解之Smooth程度控制 - 王峰的文章 - 知乎 https://zhuanlan.zhihu.com/p/49939159

    本文主要衔接前面 从最优化角度理解softmax 的文章,指出了集中sommoth化后函数存在的问题(以softmax和LogSumMax为例)。具体内容如下:

    在第一篇文章中我们利用最优化里常见的 smooth 操作,将一个难以优化的分类目标函数经过两步 smooth 化后转变为常见的 Softmax交叉熵损失函数。文章发出来以后, 

     跟我说优化目标可以改得更简洁一些:

    通过网络输出 [公式] 个分数,使得目标分数最大。

    换成数学语言,就是要让:

    [公式]

    这样,其对应的损失函数形式就非常简单了:

    [公式]

    这个损失函数起到的作用是:当 [公式] 恰好是 [公式] 中最大的元素时,损失函数为0;当某非目标分数 [公式] 大于目标分数 [公式] 时,就产生了一个正的损失。同样的,通过使用 LogSumExp 函数就可以将这个损失函数转化为 Softmax 交叉熵损失。感兴趣的读者可以自行推导一下作为练习。

    经过这样的修改我们将所有的 [公式] 一视同仁,其实是不利于我后面引入 margin 项的。不过对于本篇文章关于 smooth 的理解倒是非常有利,所以这篇文章将会基于这个组目标-损失函数来进行分析。

    结合第一篇文章和本文所描述的 smooth 方法,我们知道 Softmax 交叉熵损失可以理解为在使用 LogSumExp 函数对 max 函数进行替代,那么这样替代除了使得优化更容易进行下去有什么副作用呢?本文将从 smooth 程度控制的角度来讲一下 Softmax 交叉熵损失的缺点。

    为了让读者更容易看明白,这里再把 Softmax 和 LogSumExp 两个函数的定义写一下:

     

    有了这两个公式,我们来看一组例子:

    x = [1 2 3 4]
    softmax(x) = [0.0321 0.0871 0.2369 0.6439]
    LSE(x) = 4.4402

    从这个例子来看,本来1和4只差4倍,通过指数函数的放大作用,Softmax后的结果相差大约20倍。这样看,Softmax起到了近似 one-hot max 的作用,但 0.6439 其实也不算靠近1,近似效果不佳。

    下面我们将 x 放大10倍:

    x = [10 20 30 40]
    softmax(x) = [9.36e-14 2.06e-9 4.54e-5 1.00]
    LSE(x) = 40.00

    可以看到,放大10倍之后,不管是 Softmax 还是 LogSumExp 都起到了理想的作用。

    那缩小10倍呢?

    x = [0.1 0.2 0.3 0.4]
    softmax(x) = [0.2138 0.2363 0.2612 0.2887]
    LSE(x) = 1.6425

    可以看到在这种情况下,Softmax 和 LogSumExp 都不再能够很好地近似了,Softmax 的最大值和最小值差距不到一倍,而 LogSumExp 竟然比 max(x) 大了4倍多。

    也就是说 Softmax 交叉熵损失在输入的分数较小的情况下,并不能很好地近似我们的目标函数。在使用 [公式] 对 [公式] 进行替换时, [公式] 将会远大于 [公式] ,不论 [公式] 是不是最大的,都会产生巨大的损失。我们在第一篇文章中分析过,稍高的 [公式] 可以在类间引入一定的间隔,从而提升模型的泛化能力。但过大的间隔同样是不利于分类模型的,这样训练出来的模型必然结果不理想。

    总结一下, [公式] 的幅度既不能过大、也不能过小,过小会导致近对目标函数近似效果不佳的问题;过大则会使类间的间隔趋近于0,影响泛化性能。

    那么如何去控制 [公式] 的幅度呢?在增强学习、知识蒸馏等领域,使用的 Softmax 交叉熵损失通常是带有温度项 [公式] 的:

    [公式]

    温度项控制着 Softmax 的 smooth 程度, [公式] 越小,则 Softmax 越接近one-hot max, [公式] 越大,则近似效果越差。那么只要我们引入这一项,并将 [公式] 设置得足够小,是不是就能解决问题了呢?

    其实没那么容易,注意到这个 [公式] 是施加在所有的分数 [公式] 上的,所以这是对分数的一个线性变换,由于 [公式] 本身就是通过一个内积层(全连接层)得到的,线性-线性还是线性,所以这个 [公式]在优化过程中会被融合进前边的内积层,只要进行充分的训练,是不会产生什么实际的影响的。

    为了解决这一问题也有好几种方案,首先最好想到的就是根据当前分数 [公式] 的大小动态地设置 [公式],就像炼丹一样,随时把控火炉的温度,很符合我们炼丹师的风格2333...

    但这样做太麻烦了,去年有一篇文章提出了一种叫 Feature Incay 的方法,加一个约束项让特征的幅度拉大,这样就可以缓解小幅度的 [公式] 的问题(注意特征跟 [公式] 并不是同一回事,中间还有个内积层,所以这是个间接的影响)。而且这篇文章也提到了不能使特征幅度过长,所以使用的约束项是特征幅度的倒数,这样较小幅度的特征获得的拉长效果要比较大幅度的特征获得的要多很多。这篇文章最终被ICLR workshop收录,值得一看。

    Feature Incay 的缺点在于:一是提升特征幅度跟提升 [公式] 的幅度之间总归是差一层,二是通过约束项来拉升特征幅度也不能保证就没有小幅度的特征存在,总之就是不那么直接。不过这些都可以通过调参来调节嘛,我们炼丹师最擅长了。

    另一种方案是将特征和权重全部归一化,这样 [公式] 就从特征与权重的内积变成了特征与权重的余弦,由于余弦值的范围是 [公式] ,所以 [公式] 的幅度就大致被定下来了,然后我们再乘上一个尺度因子 [公式] 来拉长 [公式] 的幅度,来保证输入到 Softmax 里的分数能在一个合适的范围:

    [公式]

    这里的 [公式] 表示是由归一化后的特征与权重的内积(即余弦)得到的分数。这个方法的优点在于我们是可以估计出 Softmax 大概需要的 [公式] 的幅度是多少的,所以在设置这个 [公式] 的时候相对于约束项前边的 [公式] 更加有理论可循。至于是什么理论呢?公式太多我懒得在博客里打了,欢迎阅读我的NormFace 论文 (Proposition 2),或者是我的博士论文(定理3.1)。

  • 相关阅读:
    Javascript在使用import 与export 区别及使用
    【repost】Python正则表达式
    js常见算法
    【repost】 JS变量重复声明以及忽略var 声明的问题及其背后的原理
    【repost】javascript callback
    【repost】js window对象属性和方法相关资料整理
    Donald Knuth
    前端知识体系
    【repost】让你一句话理解闭包(简单易懂)
    【repost】图解Javascript上下文与作用域
  • 原文地址:https://www.cnblogs.com/zf-blog/p/14474832.html
Copyright © 2020-2023  润新知