PyTorch:损失保持不变

时间:2018-10-16 10:09:21

标签: python machine-learning pytorch loss-function

我已经使用自己实现的损失函数focal_loss_fixed在PyTorch中编写了代码。但是我的损失价值在每个时期都保持不变。权重似乎没有被更新。这是我的代码段:

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)))

在每个时期之后,损耗值保持恒定(5589.60328)。怎么了?

2 个答案:

答案 0 :(得分:1)

我认为问题出在您体重的下降。

从本质上讲,您不是将权重降低x ,而是将权重乘以x ,这意味着您是瞬时只做很小的增量,导致(看似)平稳损失函数。

有关此问题的更多说明,请访问PyTorch论坛(例如herehere)。
不幸的是,仅the source for SGD并不能告诉您有关其实现的更多信息。 只需将其设置为较大的值,即可获得更好的更新。您可以先将其完全丢弃,然后迭代地减少它(从1.0开始),直到获得更好的结果为止。

答案 1 :(得分:1)

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

loss = 3

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