我已经使用自己实现的损失函数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
)。怎么了?
答案 0 :(得分:1)
我认为问题出在您体重的下降。
从本质上讲,您不是将权重降低x
,而是将权重乘以x
,这意味着您是瞬时只做很小的增量,导致(看似)平稳损失函数。
有关此问题的更多说明,请访问PyTorch论坛(例如here或here)。
不幸的是,仅the source for SGD并不能告诉您有关其实现的更多信息。
只需将其设置为较大的值,即可获得更好的更新。您可以先将其完全丢弃,然后迭代地减少它(从1.0
开始),直到获得更好的结果为止。
答案 1 :(得分:1)
计算损失时,您调用focal_loss_fixed()
,它使用TensorFlow计算损失值。 focal_loss_fixed()
创建一个图形并在一个会话中运行它以获取值,而此时PyTorch不知道导致丢失的操作顺序,因为它们是由TensorFlow后端计算的。那么,PyTorch在loss
中看到的所有内容可能都是常量,就好像您已经写过
loss = 3
因此,梯度将为零,并且永远不会更新参数。我建议您使用PyTorch操作重写损失函数,以便可以计算相对于其输入的梯度。