我的问题是,如果y_true
取某些值,我不希望调整权重。由于我要使用的RNN的性质,我不想简单地从训练数据中删除这些示例。
是否可以通过这种行为在Keras中编写条件损失函数?
例如:如果y_true
为负,则应用零梯度,以使模型中的参数不变,如果y_true
为正loss = losses.mean_squared_error(y_true, y_pred)
。
答案 0 :(得分:1)
由于y
是成批的,因此您需要从定制损失函数中从批次中选择非零的那些
def myloss(y_true, y_pred):
idx = tf.not_equal(y_true, 0)
y_true = tf.boolean_mask(y_true, idx)
y_pred = tf.boolean_mask(y_pred, idx)
return losses.mean_squared_error(y_true, y_pred)
然后可以这样使用:
model = keras.Sequential([Dense(32, input_shape=(2,)), Dense(1)])
model.compile('adam', loss=myloss)
x = np.random.randn(2, 2)
y = np.array([1, 0])
model.fit(x, y)
但是,如果批次中的所有y_true
均为零,则损失函数中可能需要额外的逻辑,在这种情况下,loss
函数可以进行如下修改:
def myloss2(y_true, y_pred):
idx = tf.not_equal(y_true, 0)
y_true = tf.boolean_mask(y_true, idx)
y_pred = tf.boolean_mask(y_pred, idx)
loss = tf.cond(tf.equal(tf.shape(y_pred)[0], 0), lambda: tf.constant(0, dtype=tf.float32), lambda: losses.mean_squared_error(y_true, y_pred))
return loss
答案 1 :(得分:0)
您可以定义自定义损失函数,只需使用K.switch
有条件地获得零损失:
from keras import backend as K
from keras import losses
def custom_loss(y_true, y_pred):
loss = losses.mean_squared_error(y_true, y_pred)
return K.switch(K.flatten(K.equal(y_true, 0.)), K.zeros_like(loss), loss)
测试:
from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(1, input_shape=(1,)))
model.compile(loss=custom_loss, optimizer='adam')
weights, bias = model.layers[0].get_weights()
x = np.array([1, 2, 3])
y = np.array([0, 0, 0])
model.train_on_batch(x, y)
# check if the parameters has not changed after training on the batch
>>> (weights == model.layers[0].get_weights()[0]).all()
True
>>> (bias == model.layers[0].get_weights()[1]).all()
True