Reputation: 143
I've implemented a U-Net in Keras for an image-segmentation problem I'm working on. I'm finding that the output in the early epochs provides very good results albeit with low probabilities. As the training continues and the IoU score increases, I get fewer pixels in my output, but they have higher probabilities.
To be more succinct, my output misses certain features but has higher probabilities in the features it does identify.
I'm curious to know if I can rectify this by forcing pixel values to be 1 after the output layer with the sigmoid activation function. Is there a simple way to do this? I'm using binary_crossentropy as the loss function so I was hoping I could do something like:
def binary_crossentropy_thresh(y_true,y_pred):
y_pred[y_pred>=0.2] = 1
return binary_crossentropy(y_true,y_pred)
But this won't work on Tensors. Any suggestions would be greatly appreciated.
Apologies if I haven't explained my problem sufficiently.
Upvotes: 1
Views: 778
Reputation: 86610
No, you can't transform your function into a constant. It will not be differentiable (with respect to weights) and you will not be able to train.
You can do this in "custom metrics", never in the model or in the loss.
Make sure your IoU
loss is being calculated "image-wise", not "batch-wise". The more general the loss, the less it will notice tiny things. Batchwise losses may ignore whole images if these images have less area than others.
A good suggestion of a loss function that worked great for me was a Lovasz
loss.
You could also try sample weights (works best with single channel masks):
total_pixels = y_train.sum(axis=(1,2,3))
mean_pixels = total_pixels.mean(axis=0)
sample_weights = mean_pixels / total_pixels
Upvotes: 2