I am trying to implement a custom loss function that gives a weighted pixel-wise cross entropy value.
I have compiled the model with "sample_weight_mode='temporal'", and am passing different weights for each individual image. I have the following for this:
model.fit_generator(train_generator,...)
where, train_generator yields tuples of (input_image, target_label, weight) having following dimensions:
input_image -> (48, 64, 64, 1)
target_label -> (196608, 1)
weight -> (196608,)
Is it possible to implement a loss function obtaining this corresponding weight as an argument ? Could anyone please let me know if a function as shown below can be implemented ?
def pixelwise_cross_entropy(target, output, weight):
#~ target = tf.convert_to_tensor(target, dtype=tf.float32)
#~ output = tf.convert_to_tensor(output, dtype=tf.float32)
_EPSILON = 10e-8
output /= tf.reduce_sum(output, axis=len(output.get_shape()) - 1, keep_dims=True)
epsilon = tf.cast(tf.convert_to_tensor(_EPSILON), output.dtype.base_dtype)
output = tf.clip_by_value(output, epsilon, 1. - epsilon)
return - tf.reduce_sum(target * tf.log(output) * weight, axis=len(output.get_shape()) - 1)
The weight map is a morphologically eroded version of the target. I tried to creating the weight map in the custom loss function itself. As my data is 3D, I cannot use tensorflow's "tf.nn.erosion2d".
And I could not convert the tensor object to numpy array to do this operation, as it gives the following negative dimensions error.
tensorflow.python.framework.errors_impl.InvalidArgumentError: Shape [-1,-1,-1] has negative dimensions
[[Node: mask_target = Placeholder[dtype=DT_FLOAT, shape=[?,?,?], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
Could anyone please help if you have knowledge about it or have come across a similar problem ?