大家好,又见面了,我是你们的朋友全栈君。
主要内容
- softmax和交叉熵公式
- 单个样本求解损失
- 多个样本求解损失
softmax和交叉熵公式
- softmax
先来看公式,softmax的作用是将样本对应的输出向量,转换成对应的类别概率值。这里使用以e为底的指数函数,将向量值归一化为0-1的概率值;
使用numpy的代码实现也很简单,但是当数值过大时会发生溢出,此时会将向量中的其他值减去最大值,数值平移到0附近。会避免溢出现象。ps:这里暂时不考虑这种情况
- softmax交叉熵 交叉熵是用来衡量分布p和q之间的相似度,越相似交叉熵越小。其中 p ( x ) p(x) p(x)是真实标签的one_hot编码, q ( x ) q(x) q(x)是预测值。需要注意的是这里的 q ( x ) q(x) q(x)必须是经过softmax的概率值。
单个样本求解损失
代码语言:javascript复制#conding=utf-8
from torch import nn
import torch
import numpy as np
def MySoftmax(vector):
return np.exp(vector)/np.exp(vector).sum()
def LossFunc(target,output):
output = MySoftmax(output)
one_hot = np.zeros_like(output)
one_hot[:,target] = 1
# print(one_hot)
loss = (-np.log(output)*one_hot).sum()
return loss
target = np.array([1])
output = np.array([[8,-3.,10]])
softmax_out = MySoftmax(output)
np.set_printoptions(suppress=True)
print(softmax_out)
# torch自带的softmax实现
print(nn.Softmax()(torch.Tensor(output)))
print(LossFunc(target,output))
print(nn.CrossEntropyLoss(reduction="sum")(torch.Tensor(output),torch.Tensor(target).long()))
需要注意的是现有的框架中基本都会在损失函数内部进行softmax转换。我这里设置的loss值没有求平均,所以reduction=“sum”
多个样本求解损失
代码语言:javascript复制#conding=utf-8
from torch import nn
import torch
import numpy as np
# def MySoftmax(vector):
# return np.exp(vector)/np.exp(vector).sum()
#
# def LossFunc(target,output):
# output = MySoftmax(output)
# one_hot = np.zeros_like(output)
# one_hot[:,target] = 1
# # print(one_hot)
# loss = (-np.log(output)*one_hot).sum()
# return loss
# target = np.array([1])
# output = np.array([[8,-3.,10]])
# softmax_out = MySoftmax(output)
# np.set_printoptions(suppress=True)
# print(softmax_out)
#
# # torch自带的softmax实现
# print(nn.Softmax()(torch.Tensor(output)))
#
# print(LossFunc(target,output))
# print(nn.CrossEntropyLoss(reduction="sum")(torch.Tensor(output),torch.Tensor(target).long()))
def loss_func(output,target):
one_hot = torch.zeros_like(output)
for i in range(target.size(0)):
one_hot[i,target[i]]=1
softmax_out = torch.exp(output)/( torch.unsqueeze(torch.exp(output).sum(dim=1),dim=1))
# 确保每一个样本维度的概率之和为1
print(softmax_out.sum(dim=1))
loss = (-torch.log(softmax_out) * one_hot).sum()
return loss
target = torch.Tensor([1,1,1]).long()
output = torch.Tensor([[10.,-5,5],[5,2,-1],[4,-9,5]])
softmax = nn.Softmax(dim=1)
criterion = nn.CrossEntropyLoss(reduction="sum")
print(criterion(output,target))
print(loss_func(output,target))
我这里使用的是torch的计算,主要原因是想使用label smoothing技巧,torch版在项目中应用更方便。 只是将numpy换成torch的形式,基本的公式都没有改变的。需要注意的是在多个样本求解softmax值是在样本的维度求概率。
喜欢的童鞋点个赞哦!大家有什么要了解的请留言,老汤尽量满足
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/153145.html原文链接:https://javaforall.cn