(详细全面)softmax和log |
您所在的位置:网站首页 › log函数范围 › (详细全面)softmax和log |
文章目录
1.softmax2.log_softmax3.softmax和log_softmax4.NLLLOSS和CrossEntropyLoss
1.softmax
![]() 作用:实现了将n维向量变成n维全为正数,且和为1的向量,在深度学习中可以解释为这个输入属于n个类别的概率。 例子: import torch.nn.functional as F inp1=torch.Tensor([1,3,6]) print(inp1) print(F.softmax(inp1,dim=0)) print("#############") inp2=torch.Tensor([2,2,2]) print(inp2) print(F.softmax(inp2,dim=0))可以看到,如果n维向量每一个分量是一样的,那么概率1平分给3个类别,表示属于三个类别的概率是相等的。 以inp1为例我们可以验证一下(即用numpy实现softmax()): import numpy as np inp1=np.array(inp1)#inp1=[1,3,6] inp1_pow=np.power(np.e,inp1) inp1_pow/np.sum(inp1_pow)#对应上述开头的那个公式
![]()
softmax的作用不言而喻,每一项代表概率,我们发现去了Log之后并不是概率了,有什么用呢? 官网解释:https://pytorch.org/docs/stable/generated/torch.nn.functional.log_softmax.html?highlight=log_sof#torch.nn.functional.log_softmax Applies a softmax followed by a logarithm. While(尽管) mathematically equivalent to log(softmax(x)), doing these two operations separately is slower, and numerically unstable. This function uses an alternative formulation to compute the output and gradient correctly. 大概意思就是说,虽然可以用log(softmax(x))来代替log_softmax(),但是前者太慢了。需要进行n次指数,n次除法,n次log(忽略加减法)。后者只需要n次指数,1次log。 而做softmax需要n次指数,n次除法。这样看来,似乎Log_softmax()似乎最好。 注意到: log e x e x + e y = x − l o g ( e x + e y ) \log \frac{e^x}{e^x+e^y}=x-log(e^x+e^y) logex+eyex=x−log(ex+ey) 所以两次指数,一次对数,这个算好了可以保存起来,下一次还是继续用。 不过,实际操作中还会有一个使得数值计算更加稳定的算法,因为我们要考虑这种情况,如果(x,y)=(1000,1001)。那么 e 1000 e^{1000} e1000将会发生上溢。与之对应有 e − 1000 e^{-1000} e−1000会发生下溢。 从而我们有了如下更加稳定的办法:即取 M = max ( x , y ) M=\max(x,y) M=max(x,y)。有: log e x e x + e y = log e x / e M e x / e M + e y / e M = x − M − l o g ( e x − M + e y − M ) \log \frac{e^x}{e^x+e^y}=\log \frac{e^x/e^M}{e^x/e^M+e^y/e^M}=x-M-log(e^{x-M}+e^{y-M}) logex+eyex=logex/eM+ey/eMex/eM=x−M−log(ex−M+ey−M) 当然了,有人杠, (x,y)=(0,1000),这个方法没用,对,但是这个方法有的时候有用啊。也有人说(x,y)=(-10,10),反而会计算 e − 20 e^{-20} e−20,岂不是比原来的 e − 10 e^{-10} e−10更加下溢,这个分析也对,但是要记住,上溢是最难受的,下溢还好,我们要更加避免上溢。所以,这也是一个权衡之术。 4.NLLLOSS和CrossEntropyLossNLLLOSS:The negative(负的) log likelihood loss. CrossEntropyLoss: ![]() 联系: It is useful to train a classification problem with C classes. 即共同点是对于分类问题是非常好的两种损失函数。 过渡: 但是严格来说,NLLLOSS并不是一个损失函数,后者才是,前者是基于后者的,但是节省了计算量(区别提前剧透了)。 区别: Obtaining log-probabilities in a neural network is easily achieved by adding a LogSoftmax layer in the last layer of your network. You may use CrossEntropyLoss instead, if you prefer not to add an extra layer. 即:我们以前在做分类任务的时候,例如手写数字识别,最后一层有两种习惯: 使用softmax层,转化为各个类别概率,这种情况,你应该紧接着使用CrossEntropyLoss损失函数。使用log_softmax层,那么使用NLLLOSS最好而且最直接。解释: 在情况1中,根据CrossEntropyLoss公式,加上这是分类问题,所以标签中只有一个类别(设为z)分量为1,其他类别全为0,我们代入公式,即求和之后只剩下一项。 − log q z \quad \quad \quad \quad \qquad \qquad-\log q_z −logqz 其中 q z q_z qz表示我们的模型对该输入,属于类别z的概率的预测。 所以情况1计算CrossEntropyLoss的步骤就是取log,再取反。 在情况2中,我们模型的输出直接就是 log q z \log q_z logqz(log_softmax层后),所以计算NLLLOSS的步骤只需要取反,十分快速。这就是为什么叫做The negative log likelihood loss. 官网地址:https://pytorch.org/docs/stable/generated/torch.nn.NLLLoss.html#torch.nn.NLLLoss。 补充:CrossEntropyLoss大家肯定都已经用过,NLLLOSS使用语法是一样的,伪代码大致是这样。 import torch.nn as nn import torch.nn.functional as F class CNN(nn.Module): def __init__(self): super(CNN,self).__init__() * * * def forward(self,x): #x:1*28*28 x=F.relu(self.conv1(x)) * * * x=self.fc2(x) #shape=(1,10) return F.log_softmax(x,dim=1) pred=model(x) loss=F.nll_loss(pred,target) |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |