【问题标题】:PyTorch: Loss remains constantPyTorch:损失保持不变
【发布时间】:2019-03-20 20:15:58
【问题描述】:

我用我自己实现的损失函数focal_loss_fixed 在 PyTorch 中编写了一个代码。但是我的损失值在每个时期之后都保持不变。看起来权重没有更新。这是我的代码 sn-p:

optimizer = optim.SGD(net.parameters(),
                          lr=lr,
                          momentum=0.9,
                          weight_decay=0.0005)


for epoch in T(range(20)):
    net.train()
    epoch_loss = 0
    for n in range(len(x_train)//batch_size):
        (imgs, true_masks) = data_gen_small(x_train, y_train, iter_num=n, batch_size=batch_size)
        temp = []
        for tt in true_masks:
            temp.append(tt.reshape(128, 128, 1))
        true_masks = np.copy(np.array(temp))
        del temp
        imgs = np.swapaxes(imgs, 1,3)
        imgs = torch.from_numpy(imgs).float().cuda()
        true_masks = torch.from_numpy(true_masks).float().cuda()
        masks_pred = net(imgs)
        masks_probs = F.sigmoid(masks_pred)
        masks_probs_flat = masks_probs.view(-1)
        true_masks_flat = true_masks.view(-1)
        print((focal_loss_fixed(tf.convert_to_tensor(true_masks_flat.data.cpu().numpy()), tf.convert_to_tensor(masks_probs_flat.data.cpu().numpy()))))
        loss = torch.from_numpy(np.array(focal_loss_fixed(tf.convert_to_tensor(true_masks_flat.data.cpu().numpy()), tf.convert_to_tensor(masks_probs_flat.data.cpu().numpy())))).float().cuda()
        loss = Variable(loss.data, requires_grad=True)
        epoch_loss *= (n/(n+1))
        epoch_loss += loss.item()*(1/(n+1))
        print('Step: {0:.2f}% --- loss: {1:.6f}'.format(n * batch_size* 100.0 / len(x_train), epoch_loss), end='\r')
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    print('Epoch finished ! Loss: {}'.format(epoch_loss))

这是我的 `focal_loss_fixed' 函数:

def focal_loss_fixed(true_data, pred_data):
    gamma=2.
    alpha=.25
    eps = 1e-7
    # print(type(y_true), type(y_pred))
    pred_data = K.clip(pred_data,eps,1-eps)
    pt_1 = tf.where(tf.equal(true_data, 1), pred_data, tf.ones_like(pred_data))
    pt_0 = tf.where(tf.equal(true_data, 0), pred_data, tf.zeros_like(pred_data))
    with tf.Session() as sess:
        return sess.run(-K.sum(alpha * K.pow(1. - pt_1, gamma) * K.log(pt_1))-K.sum((1-alpha) * K.pow( pt_0, gamma) * K.log(1. - pt_0)))

在每个 epoch 之后,损失值保持不变(5589.60328)。它有什么问题?

【问题讨论】:

    标签: python machine-learning pytorch loss-function


    【解决方案1】:

    我认为问题在于你的体重下降。

    本质上,您并没有将权重减少x,而是将权重乘以x,这意味着您瞬间只做了非常小增量,导致(看似)平稳的损失函数。

    可以在 PyTorch 论坛中找到更多解释(例如,herehere)。
    不幸的是,单独的the source for SGD 也没有告诉你太多关于它的实现。 简单地将其设置为更大的值应该会导致更好的更新。您可以从完全忽略它开始,然后迭代地减少它(来自1.0),直到获得更体面的结果。

    【讨论】:

    • dennlinger 如何在这段代码中修改weight decay?我是 PyTorch 的新手,不太了解。
    • @tahsin314 权重衰减在优化器变量 (SGD) 中。让它更小或尝试不使用它。
    • 相比之下,我认为它太小了,因为它不像你想象的那样工作。但正如@akshayk07 指出的那样,只需将部分一直翻到代码的顶部,即设置weight_decay=0.0005),然后检查您是否看到进度。
    • @dennlinger 但您在回答中提到“重量衰减”。
    • 我减少了weight decay,然后将其删除。尽管如此,我的损失没有任何变化。我猜我的代码中的反向传播可能有问题。
    【解决方案2】:

    在计算损失时,您调用focal_loss_fixed(),它使用 TensorFlow 来计算损失值。 focal_loss_fixed() 创建一个图并在会话中运行它以获取值,此时 PyTorch 不知道导致损失的操作序列,因为它们是由 TensorFlow 后端计算的。那么很可能,PyTorch 在loss 中看到的所有内容都是一个常数,就好像你写过

    loss = 3
    

    所以梯度会为零,参数永远不会更新。我建议您使用 PyTorch 操作重写您的损失函数,以便可以计算相对于其输入的梯度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 1970-01-01
      相关资源
      最近更新 更多