2021SC@SDUSC
#训练损失函数,用在训练时
train_criterion = SemiLoss()
#交叉熵损失, 用在验证集和测试集, 是模型训完完成后的,使用交叉熵进行计算损失
criterion = nn.CrossEntropyLoss()
根据前几篇博客对损失函数的介绍,在半监督文本分类该项目的代码中,其主要公式:
使用SemiLoss计算损失
class SemiLoss(object)
def __call__(self, outputs_x, targets_x, outputs_u, targets_u, outputs_u_2, epoch, mixed=1)
半监督损失函数
param outputs_x 模型输出的x
param targets_x 真实的x
param outputs_u 模型输出的无标签的x
param targets_u 真实的无标签的x
param outputs_u_2 模型输出的无标签x_2
param epoch 迭代次数
param mixed 是否是混合过的输出
return if args.mix_method == 0 or args.mix_method == 1
#有监督的x的损失
Lx = - \
torch.mean(torch.sum(F.log_softmax(
outputs_x, dim=1) * targets_x, dim=1))
#无监督的x输出的概率值
probs_u = torch.softmax(outputs_u, dim=1)
#论文中公式显示的kl散度, batch mean 批次均值作为统计计算KL散度
Lu = F.kl_div(probs_u.log(), targets_u, None, None, 'batchmean')
#计算hinge Loss 折页损失 max(0,1-(wTxi +b)yi)
Lu2 = torch.mean(torch.clamp(torch.sum(-F.softmax(outputs_u, dim=1)
* F.log_softmax(outputs_u, dim=1), dim=1) - args.margin, min=0))
elif args.mix_method == 2:
if mixed == 0:
Lx = - \
torch.mean(torch.sum(F.logsigmoid(
outputs_x) * targets_x, dim=1))
probs_u = torch.softmax(outputs_u, dim=1)
Lu = F.kl_div(probs_u.log(), targets_u,
None, None, 'batchmean')
Lu2 = torch.mean(torch.clamp(args.margin - torch.sum(
F.softmax(outputs_u_2, dim=1) * F.softmax(outputs_u_2, dim=1), dim=1), min=0))
else:
Lx = - \
torch.mean(torch.sum(F.log_softmax(
outputs_x, dim=1) * targets_x, dim=1))
probs_u = torch.softmax(outputs_u, dim=1)
Lu = F.kl_div(probs_u.log(), targets_u,
None, None, 'batchmean')
Lu2 = torch.mean(torch.clamp(args.margin - torch.sum(
F.softmax(outputs_u, dim=1) * F.softmax(outputs_u, dim=1), dim=1), min=0))
return Lx, Lu, args.lambda_u * linear_rampup(epoch), Lu2, args.lambda_u_hinge * linear_rampup(epoch)