【发布时间】:2020-02-03 00:13:21
【问题描述】:
我正在尝试在 keras 中针对“部分标签学习”问题实现自定义损失函数。 在我的训练集中 - 每个训练实例都分配有一组两个候选标签,只有一个 其中是正确的。 为此,我想在训练期间使用损失函数来计算每个标签的损失,并选择具有最小值的损失。 这个函数的简化版本是这样的:
def custom_loss(y_true, y_pred):
num_labels = tf.reduce_sum(y_true) # [0,1,0,0,1]
if num_labels > 1: #create 2 seperate vectors
y_true_1 = ? # [0,1,0,0,0]
y_true_2 = ? # [0,0,0,0,1]
loss_1 = K.categorical_crossentropy(y_true_1, y_pred)
loss_2 = K.categorical_crossentropy(y_true_2, y_pred)
loss = minimum(loss_1, loss_2)
else:
loss = K.categorical_crossentropy(y_true, y_pred)
return loss
我试着这样做:
y_true = tf.constant([1., 0., 0., 0., 1., 0., 0., 0., 0.])
y_pred = tf.constant([.9, .05, .05, .5, .89, .6, .05, .01, .94])
def custom_loss(y_true, y_pred):
def train_loss():
y_train_copy = tf.Variable(0, dtype=y_true.dtype)
y_train_copy = tf.assign(y_train_copy, y_true, validate_shape=False)
label_cls = tf.where(tf.equal(y_true,1))
raplace = tf.Variable([0.]) #Variable
y_true_1 = tf.compat.v1.scatter_nd_update(y_train_copy, [label_cls[0]], raplace) # [0,1,0,0,0]
y_true_2 = tf.compat.v1.scatter_nd_update(y_train_copy, [label_cls[1]], raplace) # [0,0,0,0,1]
loss_1 = K.categorical_crossentropy(y_true_1, y_pred)
loss_2 = K.categorical_crossentropy(y_true_2, y_pred)
min_loss = tf.minimum(loss_1, loss_2)
return min_loss
num_labels = tf.reduce_sum(y_true) # [0,1,0,0,1]
loss = tf.cond(num_labels > 1,
lambda: train_loss(),
lambda: K.categorical_crossentropy(y_true, y_pred)) #
return loss
loss = custom_loss(y_true, y_pred)
with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(loss))
问题是,由于某种原因,无论我如何尝试从两个损失中取最小值,我都得到 0.0,即使 loss_1 和 loss_2 绝对不是 0
知道为什么吗?或者更好的想法来实现这个功能?
【问题讨论】:
标签: tensorflow machine-learning keras deep-learning