【问题标题】:How to implement an upper bound JSD loss in Pytorch?如何在 Pytorch 中实现 JSD 损失上限?
【发布时间】:2018-01-01 02:04:52
【问题描述】:

我正在尝试使用 pytorch “复制”TextGAN,而且我是 pytorch 的新手。我目前关心的是复制 L_G(eq. 7 page 3),这是我当前的代码:

class JSDLoss(nn.Module):

    def __init__(self):
        super(JSDLoss,self).__init__()

    def forward(self, batch_size, f_real, f_synt):
        assert f_real.size()[1] == f_synt.size()[1]

        f_num_features = f_real.size()[1]
        identity = autograd.Variable(torch.eye(f_num_features)*0.1, requires_grad=False)

        if use_cuda:
            identity = identity.cuda(gpu)

        f_real_mean = torch.mean(f_real, 0, keepdim=True)
        f_synt_mean = torch.mean(f_synt, 0, keepdim=True)

        dev_f_real = f_real - f_real_mean.expand(batch_size,f_num_features)
        dev_f_synt = f_synt - f_synt_mean.expand(batch_size,f_num_features)

        f_real_xx = torch.mm(torch.t(dev_f_real), dev_f_real)
        f_synt_xx = torch.mm(torch.t(dev_f_synt), dev_f_synt)

        cov_mat_f_real = (f_real_xx / batch_size) - torch.mm(f_real_mean, torch.t(f_real_mean)) + identity
        cov_mat_f_synt = (f_synt_xx / batch_size) - torch.mm(f_synt_mean, torch.t(f_synt_mean)) + identity

        cov_mat_f_real_inv = torch.inverse(cov_mat_f_real)
        cov_mat_f_synt_inv = torch.inverse(cov_mat_f_synt)

        temp1 = torch.trace(torch.add(torch.mm(cov_mat_f_synt_inv, cov_mat_f_real), torch.mm(cov_mat_f_real_inv, cov_mat_f_synt)))
        temp1 = temp1.view(1,1)
        temp2 = torch.mm(torch.mm((f_synt_mean - f_real_mean), (cov_mat_f_synt_inv + cov_mat_f_real_inv)), torch.t(f_synt_mean - f_real_mean))
        loss_g = torch.add(temp1, temp2).mean()

        return loss_g

它有效。但是,我怀疑这不是创建自定义损失的方法。任何形式的帮助都非常感谢!在此先感谢:)

【问题讨论】:

    标签: python deep-learning pytorch


    【解决方案1】:

    如何在 Pytorch 中创建自定义损失

    这就是您在 Pytorch 中创建自定义损失的方式。您需要满足以下要求:

    • 损失函数最终返回的值必须是标量值。不是向量/张量。
    • 返回的值必须是变量。这样它就可以用来更新模型中的参数。最好的方法 只是确保传入的 x 和 y 都是变量。 这样,两者的任何函数也将是一个变量。
    • 定义__init__forward 方法

    您可以在 Pytorch 源代码中找到几个可以用作示例的损失模块:https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/loss.py

    如果您将小批量张量传递给损失函数,则无需将小批量大小传递给 forward 函数,因为大小可以在 forward 函数中计算。

    如何使用自定义损失

    一旦你实现了你的损失函数,你可以如下使用它,例如:

    loss = YourLoss()
    input = autograd.Variable(torch.randn(3, 5), requires_grad=True)
    target = autograd.Variable(torch.randn(3, 5))
    output = loss(input, target)
    output.backward()
    

    loss.backward() 为网络中具有requires_grad=True 的每个参数x 计算dloss/dx。对于每个参数x,这些累积到x.grad。在伪代码中:

    x.grad += dloss/dx
    

    optimizer.step 使用梯度x.grad 更新x 的值。例如,SGD 优化器执行:

    x += -lr * x.grad
    

    optimizer.zero_grad() 为优化器中的每个参数 x 清除 x.grad。在loss.backward() 之前调用它很重要,否则你会累积多次传递的梯度。

    【讨论】:

    • 非常感谢@JMA 的评论。我几乎已经知道如何制作损失函数等等,我的问题实际上更多地集中在我是否使用正确的方程或反映论文的方程。如果你能帮助我,这将意味着整个世界:)
    • 您还需要帮助验证吗?
    • 是的,如果您想将讨论移至电子邮件,我也可以
    猜你喜欢
    • 2020-08-06
    • 2020-06-21
    • 2020-12-08
    • 2019-05-28
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    相关资源
    最近更新 更多