softmax的上下溢问题

问题描述

在解决多分类问题时,常常使用softmax作为激活函数:softmax(xi)=exij=1nejx

一次计算过程基本如下:

def softmax(inputs):
    length = len(inputs)
    exps = []
    sum = 0
    for item in inputs:
        exp_val = math.exp(item) # item就是x_i
        sum = sum + exp_val # sum就是 $\sum (e^x_j)$
        exps.append(exp_val)
    return exps/sum # 返回一个list,list中每个元素对应于每个x_i计算后的值

计算过程当然是没什么问题,但是对于计算机而言,它能够计算、存储的数值大小、精度总要有个上下限:

  • 当inputs中的数比较大时:可能出现上溢
    inputs = [1000, 2000, 3000],那么e^x_i 就会超过上限,从而报错:OverflowError,更别提后续的求和、求商。这就是上溢。
  • 当inputs中的数比较小时:可能出现下溢
    inputs = [-1000, -2000. -3000],e^x_i 同样超过了计算机的精度范围,也就直接记为0,从而使得分母的值为0,那么整个计算结果在python中就会显示ZeroDivisionError,在numpy中标记为“nan"。这就是下溢。

对于上下溢问题(通常是下溢),一个典型表现就是对NN做训练时,准确率没有变化:因为经过softmax的输出并不是一个数,后续的损失、优化无法进行,参数得不到更新,那自然每次都是一样的结果。

解决:softmax的冗余性

根据上述softmax公式进行推导:
softmax(xi+x)=exi+xj=1nexj+x=exexij=1n(exejx)=exexiexj=1nejx=exij=1nejx=softmax(xi)

我们可以看到对于任意一个数a, x+a和x在softmax中的结果都是一样的,即softmax(x)=softmax(x+a),这个结论被称为softmax的冗余性。
我们令 x=x+a,其中a=max(x),则:

  • (x+a)的最大值等于0,避免了上溢的问题;
  • 同时,因为一定有x+a=0, 所以分母中的各个加数至少有一个为1,也就不可能为0,由此避免下溢的问题。

参考

https://blog.csdn.net/zx1245773445/article/details/86443099

posted @   YIYUYI  阅读(826)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示