log_softmax

参考:https://blog.csdn.net/qq_28418387/article/details/95918829

python版softmax:

def softmax(x, axis=1):
    # 计算每行的最大值
    row_max = x.max(axis=axis)

    # 每行元素都需要减去对应的最大值,否则求exp(x)会溢出,导致inf情况
    row_max = row_max.reshape(-1, 1)
    x = x - row_max

    # 计算e的指数次幂
    x_exp = np.exp(x)
    x_sum = np.sum(x_exp, axis=axis, keepdims=True)
    s = x_exp / x_sum
    return s

 

LogSoftmax
顾名思义,logsoftmax其实就是对softmax求出来的值再求一次log值,其计算公式如下:
LogSoftmax(xi)=log(exp(xi)∑jexp(xj)) LogSoftmax(x_i)=log(\frac{exp(x_i)}{\sum_{j}exp(x_j)})

 

Pytorch中Softmax、Log_Softmax、NLLLoss以及CrossEntropyLoss的关系与区别详解


最近看了一些Pytorch的代码,代码中使用了Log_Softmax方法,Loss函数使用了NLLLoss,作为深度学习新手,便上网查了一些资料,将相关知识总结记录以下。

本文主要参考了这篇文章,在此基础上加入了一些自己的理解。

Softmax
我们知道softmax激活函数的计算方式是对输入的每个元素值x求以自然常数e为底的指数,然后再分别除以他们的和,其计算公式如下:

​    


 

举个例子,假如是图片分类任务,输入m张图片,输出为一个m * N的Tensor,其中N为类别数。加入输入的是四张图片,类别数为3,那么输出的就是一个4 * 3的Tensor:

每一行代表一张图片,假如每一列分别代表类别为猫、狗、猪的得分,可以看出模型认为第二,第四张更有可能是狗,第一张更有可能是猫,第三张更有可能是猪。然后对每个值求softmax,得到每张图片的概率分布。求得softmax值为:

参数dim=1表示对每一行求softmax,那么每一行的值加起来都等于1。
那么我们再看看对softmax值再求log:

由于经过softmax求出来的值都在[0,1]区间,所以,再log求值之后的值域为负无穷到1。记住上面的值,我们再直接对输入值计算LogSoftmax,与上面的值对比:

看!计算出来的完全相等,这就验证了LogSoftmax等于对Softmax求log值。

NLLLoss
NLLLoss的计算方式就是将上面输出的值与对应的Label中的类别拿出来去掉负号,求均值。比如,我们现在的Target标签为[0, 2, 1, 2],分别表示第一张图片的label为猫,第二张图片的label为猪,第三章图片的label为狗,第四张图片的label为猪。那么NLLLoss的计算就是取出上面输出的第一行-0.5315,第二行-2.3351,第三行-2.6132,第四行-1.4174,取他们的绝对值求和取平均

那么我们再通过pytorch中的NLLLoss函数来计算一下:

看!计算出来的值相等。
这里说一下我自己对NLLLoss的理解,为什么NLLLoss的计算方式可以用来求损失值。经过上面的计算我们知道,Softmax计算出来的值范围在[0, 1],值的含义表示对应类别的概率,也就是说,每行(代表每张图)中最接近于1的值对应的类别,就是该图片概率最大的类别,那么经过log求值取绝对值之后,就是最接近于0的值,如果此时每行中的最小值对应的类别值与Target中的类别值相同,那么每行中的最小值求和取平均就是最小,极端的情况就是0。总结一下就是,input的预测值与Target的值越接近,NLLLoss求出来的值就越接近于0,这不正是损失值的本意所在吗,所以NLLLoss可以用来求损失值。

CrossEntropyLoss
CrossEntropyLoss很容易理解,它就是softmax+log+NLLLoss,一步到位,不需要那么多步骤去自己写,它的输入就是模型的直接输出,测试一下:

果然没错,与之前NLLLoss求出来的一样!

发布了2649 篇原创文章 · 获赞 964 · 访问量 524万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章