栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

max函数的平滑(log-sum-exp trick)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

max函数的平滑(log-sum-exp trick)

1 起源

在一些问题中,我们的目标函数是max(x1,x2,...xn) 或者min(x1,x2,....xn),但是max和min都不是可微函数,因而这些目标函数无法直接用到深度学习任务中

2 交叉熵与softmax

        在神经网络中,假设我们最后一层使用的是softmax,来得到各个概率分布,softmax的形式为,其中

        而在分类问题或者一些其他问题中,我们会使用到交叉熵,其中的每一项,我们都有形如

        其中,减号后面的部分,就是这一个博客需要说明的log-sum-exp (LSE)

2.1 softmax的上下溢出

        假设我们目前有两个例子:一个数据集为[10000,10000,10000](很大的数,exp(xi)之后会上溢出);另一个数据集为[-10000,-10000,-10000](很小的数,exp(xi)之后会下溢出)

        这两组数据,如果我们用肉眼去看,肯定可以很轻松地得到它的概率分布为,但是,如果我们用python去计算这两个数据集的概率的时候:会是这样的情况:

import numpy as np
def softmax(lst):
    lst_exp=np.exp(lst)
    total=np.sum(lst_exp)
    return(lst_exp/total)


softmax([10,10,10])
#array([0.33333333, 0.33333333, 0.33333333])
#数值不大的时候,可以得到正确的softmax结果

softmax([10000,10000,10000])
'''
RuntimeWarning: overflow encountered in exp
  This is separate from the ipykernel package so we can avoid doing imports until
pythonpython37libsite-packagesipykernel_launcher.py:5: RuntimeWarning: invalid value encountered in true_divide
  """
array([nan, nan, nan])
'''

softmax([-10000,-10000,-10000])

'''
 RuntimeWarning: invalid value encountered in true_divide
  """
array([nan, nan, nan])
'''

        我们可以发现,数值不是很大/小的时候,是可以得到正确的softmax结果的,但是如果是我们给的这两组极大/小的数据集,那么会得到上/下溢出,得不到正确的softmax结果

        在softmax的时候是针对指数进行操作的,值一定会很大。但是之后在计算cross-entropy的时候由于log的存在导致值又回到正常范围。

        因此在实际操作中,考虑如何去重写,以得到正常范围内的值。也就是如何去近似log-sum-exp。

3 log-sum-exp trick

我们假设第j项是x中最大的:

                   

                            

而之前我们计算softmax项的时候,有:

所以我们现在有:

此时差分比绝对数值要小很多了,大的数据也就可以计算了

#这里的意义其实和前面的softmax函数有一点小小的出入,这里是前面softmax的结果再经过了log之后的内容

np.log([1/3,1/3,1/3])
#array([-1.09861229, -1.09861229, -1.09861229])

import numpy as np
def softmax_log(lst):
    max_val=np.max(lst)
    lst=lst-max_val
    #lst就相当于xk-xj
    
    lst_exp=np.exp(lst)
    total=np.sum(lst_exp)
    total=np.log(total)
    #最后一项
    
    return(lst-total)

softmax_log([10000,10000,10000])
#array([-1.09861229, -1.09861229, -1.09861229])


softmax_log([-10000,-10000,-10000])
#array([-1.09861229, -1.09861229, -1.09861229])

softmax_log([100,100,100])
#array([-1.09861229, -1.09861229, -1.09861229])
 4 max的平滑

根据泰勒分解,我们有:

于是我们这里令 上式的X为x+a,c为x,f(X)=log(X)

所以

也即 

而当xj是最大的一项时,我们第二项可以忽略不计(值比第一项要小很多)

所以

参考资料 关于LogSumExp - 知乎 (zhihu.com)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/715406.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号