keras: Can't use auc_roc_score (or any other metric function based on numpy) as a custom metric?
#1732 says we can’t directly optimise auc as it is not differentiable. Then can’t we have it only as a metric?
I just hoped this might work (without proper understanding…), but have an error message in compilation.
from sklearn import metrics
from keras import backend as K
def auc(y_true, y_pred):
return metrics.roc_auc_score(K.eval(y_true), K.eval(y_pred))
and the error is…
File "/Users/gnu/Dropbox/codes/msd_tagging/my_keras_model_essence.py", line 66, in build_convnet_model
model.compile(loss=loss_function, optimizer=optimiser, metrics=metrics)
File "/Users/gnu/anaconda/lib/python2.7/site-packages/keras/models.py", line 343, in compile
**kwargs)
File "/Users/gnu/anaconda/lib/python2.7/site-packages/keras/engine/training.py", line 642, in compile
self.metrics.append(metric_fn(y_true, y_pred))
File "/Users/gnu/Dropbox/codes/msd_tagging/my_metrics.py", line 9, in auc
return metrics.roc_auc_score(K.eval(y_true), K.eval(y_pred))
File "/Users/gnu/anaconda/lib/python2.7/site-packages/keras/backend/theano_backend.py", line 71, in eval
return x.eval()
File "/Users/gnu/anaconda/lib/python2.7/site-packages/theano/gof/graph.py", line 520, in eval
self._fn_cache[inputs] = theano.function(inputs, self)
File "/Users/gnu/anaconda/lib/python2.7/site-packages/theano/compile/function.py", line 320, in function
output_keys=output_keys)
File "/Users/gnu/anaconda/lib/python2.7/site-packages/theano/compile/pfunc.py", line 479, in pfunc
output_keys=output_keys)
File "/Users/gnu/anaconda/lib/python2.7/site-packages/theano/compile/function_module.py", line 1776, in orig_function
output_keys=output_keys).create(
File "/Users/gnu/anaconda/lib/python2.7/site-packages/theano/compile/function_module.py", line 1428, in __init__
accept_inplace)
File "/Users/gnu/anaconda/lib/python2.7/site-packages/theano/compile/function_module.py", line 177, in std_fgraph
update_mapping=update_mapping)
File "/Users/gnu/anaconda/lib/python2.7/site-packages/theano/gof/fg.py", line 171, in __init__
self.__import_r__(output, reason="init")
File "/Users/gnu/anaconda/lib/python2.7/site-packages/theano/gof/fg.py", line 367, in __import_r__
raise MissingInputError("Undeclared input", variable)
theano.gof.fg.MissingInputError: ('Undeclared input', dense_1_target)
The error is from this line.
I would be convenient if numpy-based metric function can be used – if it is not possible now. I am computing it after each iteration, but then there is redundant predictions and I can’t take advantage of callbacks.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 1
- Comments: 36 (6 by maintainers)
Metrics functions must be symbolic functions (built with the Keras backend, or with Theano/TensorFlow).
Also ROC AUC is not a metric that be accumulated in mini-batches, it has to be computed for all the data at once.
The right thing to do is to run predictions on all of your test data at the end of an epoch, then run the sklearn function on your predictions, and display the result. You can do this in a callback.
@JoshuaC3 The way to make @jamartinh 's solution to work with fit_generator is by making these changes:
In
__init__
, you should pass in the train and val generators instead.In
on_epoch_end
, replacemodel.predict
withmodel.predict_generator
.Here’s a sketch where only the AUROC of the val dataset is calculated at the end of every epoch:
@fchollet
But its reasonable to have this metric computed on the validation set at the end of each epoch.
Correct, but the problem is that since its not in the keras metrics form, you don’t get the output to tensorboard. Am I correct?
@solensolen are you sure about the metrics method working? I’m using both the methods and the validation AUROC I get from the metrics method increases with each epoch. Towards the end of training, the metrics AUROC is way higher than the callback one (fyi my dataset is pretty imbalanced)
I thought it’s like what @isaacgerg said that it is calculated batch-by-batch and averaged which is why it is so high as some batches may not have the underpopulated class. So I decided to make my validation data the same size as my batch size so that it is calculated in one go and I am still experiencing the aforementioned phenomenon. Here is a sample from the output (batch size is 1000).
The
val_auc_roc
is calculated by passing the auc_roc function to themodel.compile
method and theAUC (from callback)
is the same as theroc_callback
class defined in an above post with only validation data AUC calculated. In epoch 1, the values are similar but by further epochs it’s way higher. Can anyone explain why is theval_auc_roc
so different from theAUC (from callback)
?@fchollet
I don’t see why this yields, “tensorflow.python.framework.errors_impl.FailedPreconditionError: Attempting to use uninitialized value auc/true_positives…”
@jamartinh - how to get this to work then
validation_data
is aflow_from_directory
generator?I get the error
https://www.kaggle.com/rspadim/gini-keras-callback-earlystopping-validation
gini = 2*auc -1
@NickYi1990 by default the batch size is 32, since the roc auc must use all the validation data to be correct, you need to give a batch size equal to the size of you validation set. In your case:
@NickYi1990 I had the same issue - I figured out that some of the thresholds had 0 true positives / false negatives. This led to a division by 0 -> return FP / N A decent solution is: return FP / N -> return FP / (N + 1)
Technically AUC ROC can be calculated on mini-batch as long as we have the y_true and y_pred. The only concern should be that too small batch size will reduce the accuracy of this metric and make it less meaningful. Am I right? @fchollet
This works: