How to ignore part of input and output in Keras?

Viewed 1174

I'm trying to train a model that takes n values as input and output n values. The problem is that n can be from 1 to 700. So I build a network with 700 as input and 700 as output. The extra inputs and outputs are set to zero. When training the model, I don't care about if the extra outputs are accurate or not. So I tried to define my own loss function as follows:

def mse_truncate(y_true, y_pred):
    def fn(x):
        return tf.cond(x < 0.01,lambda: 0.0,lambda: 1.0)
    #Ignore the square error if y_true[i] is near zero
    sgn = tf.map_fn(fn,y_true)
    return K.mean(sgn * K.square(y_true-y_pred),axis=-1)

This function works on console. But when I compile the model, I get an error:

model.compile(optimizer='sgd',loss=mse_truncate, metrics=['accuracy'])
ValueError: Shape must be rank 0 but is rank 1 for 'loss_5/dense_2_loss/map/while/cond/Switch' (op: 'Switch') with input shapes: [?], [?].

Can someone tell me what's wrong here? Or are there better ways to handle the variable length input and output?

Note: More on the problem, the input is a sequence(length <= 700) and the output is the distance between the first element and each element in the sequence.

1 Answers

You could use tf.where and tf.gather to only take those values that you care about into consideration, e.g.:

indices = tf.where(tf.greater(y_true, 0.01)) #  or `tf.less`, `tf.equal` etc.
loss = K.mean(K.square(tf.gather(y_true, indices) - tf.gather(y_pred, indices))))
Related