[问题记录]手动计算损失函数中遇到RuntimeError: grad can be implicitly created only for scalar outputs

原代码

import torch
import torch.nn.functional as F
from torch import nn

logloss = nn.BCEWithLogitsLoss()

def cosine_loss(a, v, y):
    d = nn.functional.cosine_similarity(a, v)
    loss = logloss(d.unsqueeze(1), y)
    return loss

手动调整了loss的计算方式

def weighted_logloss(pred, target, pos_weight=1.01, neg_weight=0.99):
    pos_mask = (target == 1).float()
    neg_mask = (target == 0).float()
    pos_loss = -pos_mask * torch.log(pred) * pos_weight
    neg_loss = -neg_mask * torch.log(1 - pred) * neg_weight
    return pos_loss + neg_loss

def cosine_loss(a, v, y, pos_weight=1.01, neg_weight=0.99):
    d = F.cosine_similarity(a, v)
    d = d.unsqueeze(1)
    loss = weighted_logloss(d, y, pos_weight, neg_weight)
    return loss

报错

RuntimeError: grad can be implicitly created only for scalar outputs

原因

第一个 cosine_loss 函数

  • cosine_similarity(a, v) 计算得到一个形状为 [batch_size] 的张量 d。
  • d.unsqueeze(1) 将 d 的形状从 [batch_size] 变为 [batch_size, 1]。
  • logloss(d.unsqueeze(1), y) 使用二值交叉熵损失(带logits)来计算损失,这个损失的形状是一个标量,即 [1]。
  • 返回的 loss 是一个标量。

第二个 cosine_loss 函数

  • cosine_similarity(a, v) 计算得到一个形状为 [batch_size] 的张量 d。
  • d.unsqueeze(1) 将 d 的形状从 [batch_size] 变为 [batch_size, 1]。
  • weighted_logloss(d, y, pos_weight, neg_weight) 计算损失,这个损失的形状为 [batch_size, 1]。
  • 返回的 loss 的形状为 [batch_size, 1]。

解决方式

在第二个损失函数返回时使用.mean()使其变成标量

def cosine_loss(a, v, y, pos_weight=1.01, neg_weight=0.99):
    d = F.cosine_similarity(a, v)
    d = d.unsqueeze(1)
    loss = weighted_logloss(d, y, pos_weight, neg_weight)
    return loss.mean()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值