deeplearning4j/deeplearning4j · error · IllegalStateException
Classifier evaluation using
Error message
Classifier evaluation using ${classifierEval.getSimpleName()} class cannot be applied to output layers with activation functions that are not probabilities (in range 0 to 1). Output layer type: ${outputLayer.getClass().getSimpleName()} has activation function ${bl.getActivationFn().getClass().getSimpleName()}. This check can be disabled using MultiLayerNetwork.getLayerWiseConfigurations().setValidateOutputLayerConfig(false) or ComputationGraph.getConfiguration().setValidateOutputLayerConfig(false) What it means
This IllegalStateException is thrown when classifier evaluation (Evaluation, ROCMultiClass, etc.) is requested but the output layer's activation function can produce values outside [0,1], so its outputs are not probabilities and probability-based metrics would be invalid. Deeplearning4j inspects the layer's IActivation via OutputLayerUtil.activationExceedsZeroOneRange and rejects obviously wrong activation choices (e.g. ReLU/tanh/identity on an output layer used for classification). For non-explicitly-Output layers the check is stricter since probabilities aren't guaranteed.
Solutions
- Set the output layer activation to a probability activation: softmax for multi-class, sigmoid for multi-label/binary (e.g. .activation(Activation.SOFTMAX) on OutputLayer).
- If the mismatch is intentional, disable the check: getLayerWiseConfigurations().setValidateOutputLayerConfig(false) for MultiLayerNetwork or getConfiguration().setValidateOutputLayerConfig(false) for ComputationGraph.
- Verify the layer type is a proper output layer (OutputLayer/RnnOutputLayer/CenterLossOutputLayer); if the last layer is a DenseLayer, replace with OutputLayer.
- Choose evaluation matching the model: use regression evaluation (RegressionEvaluation) for non-probability outputs instead of classifier evaluation.
Example fix
// before
.layer(new OutputLayer.Builder(LossFunctions.LossFunction.MCXENT)
.activation(Activation.RELU) // not a probability
.nOut(numClasses).build())
...
model.evaluate(iter, new Evaluation()); // throws
// after
.layer(new OutputLayer.Builder(LossFunctions.LossFunction.MCXENT)
.activation(Activation.SOFTMAX)
.nOut(numClasses).build()) Defensive patterns
Strategy: validation
Validate before calling
BaseLayer out = (BaseLayer) net.getOutputLayer();
IActivation fn = ((org.deeplearning4j.nn.conf.layers.BaseLayer)out.conf().getLayer()).getActivationFn();
if (!(fn instanceof ActivationSoftmax || fn instanceof ActivationSigmoid)) {
throw new IllegalStateException("Output activation " + fn + " is not a probability activation; use SOFTMAX/SIGMOID for classifier evaluation");
} Type guard
boolean isProbActivation = fn instanceof org.nd4j.linalg.activations.impl.ActivationSoftmax || fn instanceof org.nd4j.linalg.activations.impl.ActivationSigmoid;
Try / catch
try {
model.evaluate(iter, new Evaluation());
} catch (IllegalStateException e) {
if (e.getMessage().contains("not probabilities")) {
// fix activation or disable validation
} else throw e;
} Prevention
- Always use SOFTMAX for multi-class output layers and SIGMOID for binary/multi-label.
- Use OutputLayer (not DenseLayer) as the final layer so the relaxed validation path applies.
- Match the loss function to the activation (MCXENT+SOFTMAX, XENT+SIGMOID).
- Treat setValidateOutputLayerConfig(false) as a last resort, never a default.
When it happens
Trigger: Calling model.evaluate(...) or passing a classifier IEvaluation class while the final layer uses an activation like ReLU, Tanh, Identity, LeakyReLU, ELU, SELU, Softsign-ish bounds violations, e.g. an OutputLayer with activation Activation.RELU and loss function suitable for regression, then evaluating as classification. Also triggered for hidden layers last in the network because the check is stricter when the layer isn't OutputLayer/RnnOutputLayer/CenterLossOutputLayer.
Common situations: Copying a regression example (identity/relu activation) and then evaluating with classification metrics; using Activation.SIGMOID vs SOFTMAX mistakes; after editing the .conf builder and leaving a wrong activation on the output layer; newer DL4J versions added this validation, so older models/code that previously 'worked' now fail with it.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Cannot apply operation
- Cannot construct RecordReaderMultiDataSetIterator with no…
- Cannot evaluate network with no output layer
- Cannot perform operation
- Classifier evaluation using
AI-assisted analysis of deeplearning4j/deeplearning4j@4c22ac5fe4 (2026-09-07).
Data as JSON: /api/errors/4b246dca8ba7b009.
Report an issue: GitHub.
Appendix: source
Thrown at deeplearning4j/deeplearning4j-nn/src/main/java/org/deeplearning4j/util/OutputLayerUtil.java:185
* This method won't catch all possible invalid cases, but should catch some common problems.
*
* @param outputLayer Output layer
* @param classifierEval Class for the classifier evaluation
*/
public static void validateOutputLayerForClassifierEvaluation(Layer outputLayer, Class<? extends IEvaluation> classifierEval){
if(outputLayer instanceof Yolo2OutputLayer){
throw new IllegalStateException("Classifier evaluation using " + classifierEval.getSimpleName() + " class cannot be applied for object" +
" detection evaluation using Yolo2OutputLayer: " + classifierEval.getSimpleName() + " class is for classifier evaluation only.");
}
//Check that the activation function provides probabilities. This can't catch everything, but should catch a few
// of the common mistakes users make
if(outputLayer instanceof BaseLayer){
BaseLayer bl = (BaseLayer)outputLayer;
boolean isOutputLayer = outputLayer instanceof OutputLayer || outputLayer instanceof RnnOutputLayer || outputLayer instanceof CenterLossOutputLayer;
if(activationExceedsZeroOneRange(bl.getActivationFn(), !isOutputLayer)){
throw new IllegalStateException("Classifier evaluation using " + classifierEval.getSimpleName() + " class cannot be applied to output" +
" layers with activation functions that are not probabilities (in range 0 to 1). Output layer type: " +
outputLayer.getClass().getSimpleName() + " has activation function " + bl.getActivationFn().getClass().getSimpleName() +
". This check can be disabled using MultiLayerNetwork.getLayerWiseConfigurations().setValidateOutputLayerConfig(false)" +
" or ComputationGraph.getConfiguration().setValidateOutputLayerConfig(false)");
}
}
}
}
View on GitHub (pinned to 4c22ac5fe4)