Reputation: 814
I am trying to write a RMSE function in Keras that only runs the RMSE over array values that are not zero. I have two arrays arr1 and arr2. Both arrays have zeros in exactly the same places (thus they contribute zero to the RMSE value). However, I need to change the number I am dividing by to the number of non zero values in arr1 (or arr2)
def root_mean_squared_error(y_true, y_pred):
nonzero = tf.count_nonzero(y_pred)
num_zeros=tf.reduce_sum(tf.where(tf.not_equal(y_pred,0),tf.ones_like(y_pred),tf.zeros_like(y_pred)))
return K.sqrt((K.sum(K.square(y_pred - y_true))/tf.cast(nonzero, tf.float32)))
mc = keras.callbacks.ModelCheckpoint('modelsPerEpoch/weights{epoch:06d}.hdf5',
save_weights_only=False,
period=1)
decay_learner = ValidationLearningRateScheduler()
main_input = Input(shape=(None, 2, 100, 100), dtype='float32', name='input')
mask=Input(shape=(1, 100, 100), dtype='float32', name='mask')
hidden = ConvLSTM2D(filters=16,
kernel_size=(5, 5),
padding='same',
return_sequences=False,
data_format='channels_first')(main_input)
output = Conv2D(filters=1,
kernel_size=(1, 1),
padding='same',
activation='sigmoid',
kernel_initializer='glorot_uniform',
data_format='channels_first',
name='output')(hidden)
output_with_mask=Multiply()([output, mask])
sgd = SGD(lr=0.002, momentum=0.0, decay=0.0, nesterov=False)
model = Model(inputs=[main_input, mask], outputs=output_with_mask)
model.compile(optimizer=sgd,
loss=root_mean_squared_error,
metrics=[metrics.mse, root_mean_squared_error])
However, when I run this, I get an "inf" returned in the command line. How can I fix this?
Upvotes: 1
Views: 1083
Reputation: 6166
y_true
and y_pred
have zeros in exactly the same places is not valid according to your code. You get inf
in the command line because the non-zero number in y_pred
is 0, that is nonzero
= 0 in your code. You should count the correct non-zero numbers and avoid dividing by 0 by the following code.
def root_mean_squared_error(y_true, y_pred):
nonzero = tf.count_nonzero(y_true)
...
return K.switch(K.equal(nonzero,0)
, K.constant(value=0.)
, K.sqrt((K.sum(K.square(y_pred - y_true))/tf.cast(nonzero, tf.float32))))
Upvotes: 1