实现一个自定义的损失函数用于目标检测

5
我刚开始接触keras和tensorflow。在目标检测时如何实现自定义损失函数,目前我有5个参数——4个用于边界框坐标,1个用于确定物体是否存在。如果物体存在,则损失函数应返回坐标差的平方;否则,应返回一个巨大的值作为损失。 这是我正在尝试的代码:
def loss_func(y_true,y_pred):
  mask = np.array([False, False, False,False,True])   # check column of the class of object
  mask1 = np.array([True, True, True,True,False])     # get the columns of the coordinates of B box
  check_class = K.mean(K.square(tf.subtract(tf.boolean_mask(y_true,mask),tf.boolean_mask(y_pred,mask))))
  mean_square = K.mean(K.square(tf.subtract(tf.boolean_mask(y_true,mask1),tf.boolean_mask(y_pred,mask1))))
  value=K.mean(tf.boolean_mask(y_pred,mask))

  return value*mean_square + check_class

我在这里掩盖其他值,以获得最后一个值,即1000->对象存在0->对象不存在。是否有其他更好的方法来做到这一点?

当我在Kaggle上运行时,损失值迅速下降,到第二个纪元时,损失变为0。


你是否使用大小为1的批次?(因为您使用了大小为5的掩码) - Dinari
批量大小不是1,我以为损失函数会针对每个图像进行计算?实际上,批量大小是16。 - Kitwradr
@Or Dinari,我把批处理大小改成了1,现在损失只有0-没有变化。 - Kitwradr
1个回答

4

首先,我建议在“图像存在”参数中使用1而不是1000。
您可以操作y_true和y_pred。

penalty = 100

def lf(y_true,y_pred):
    mean_square = tf.keras.losses.mean_squared_error(y_true[:,0:4], y_pred[:,0:4])
    check_class = tf.subtract(y_true[:,4], y_pred[:,4])
    check_class = check_class * -penalty
    check_class = tf.keras.backend.mean(check_class)
    return mean_square + check_class

以上函数首先检查前4个参数的均方误差。
然后检查“present”参数。
如果不同,它将输出-1,如果相同,则输出0。
接下来,它使用惩罚对错误参数进行惩罚。

使用某个常数作为“惩罚”可能难以训练。我建议将优化器更改为SGD,因为adam在这种情况下效果不好,并尝试调整惩罚力度直到达到满意的结果。


@Kitwradr 是的,批处理大小不重要。 - Dinari
1
@Shobhit Kumar,您可以使用任何您喜欢的损失函数,如果您喜欢其他不同于均方误差的函数。关于SGD,我只会在这种情况下使用SGD,根据我的经验,不同的优化器对于像上面那样的“惩罚”效果并不好。通常,我认为正确的解决方案是为输出设置2个头部(4个参数和“现在”),这将使您能够轻松使用不同的激活函数和损失函数。但是这取决于领域,所以可能不是最佳解决方案。 - Dinari
1
@ShobhitKumar 这是一份详尽的教程:https://www.pyimagesearch.com/2018/06/04/keras-multiple-outputs-and-multiple-losses/,这里还有一些来自stackoverflow的玩具示例:https://dev59.com/uFcP5IYBdhLWcg3wqLvA - Dinari
@ShobhitKumar 你需要让盒子头也有当前位,并为此编写自定义损失函数,你可以查看tf.cond,这可能会有所帮助。 - Dinari
1
@Or Dinari 非常感谢您的帮助。我成功地创建了我的网络。 - Shobhit Kumar
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接