{"record":{"id":"181c42db099714be","repo":"stanfordnlp/CoreNLP","slug":"got-nan-for-prob-in-crfnonlinearlogconditionalobje","errorCode":null,"errorMessage":"Got NaN for prob in CRFNonLinearLogConditionalObjectiveFunction.calculate()","messagePattern":"Got NaN for prob in CRFNonLinearLogConditionalObjectiveFunction\\.calculate\\(\\)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/ie/crf/CRFNonLinearLogConditionalObjectiveFunction.java","lineNumber":670,"sourceCode":"                  fVal = 1.0;\n                  if (featureVal3DArr != null)\n                    fVal = featureVal3DArr[i][j][n];\n                  eWK[cliqueFeatures[n]] += deltaK * p * fVal;\n                }\n              }\n            } else { // for edge features\n              for (int cliqueFeature : cliqueFeatures) {\n                E[cliqueFeature][k] += p;\n              }\n            }\n          }\n          if (DEBUG) log.info(\" done!\");\n        }\n      }\n    }\n\n    if (Double.isNaN(prob)) { // shouldn't be the case\n      throw new RuntimeException(\"Got NaN for prob in CRFNonLinearLogConditionalObjectiveFunction.calculate()\");\n    }\n\n    value = -prob;\n    if(VERBOSE){\n      log.info(\"value is \" + value);\n    }\n\n    if (DEBUG) log.info(\"calculating derivative \");\n    // compute the partial derivative for each feature by comparing expected counts to empirical counts\n    int index = 0;\n    for (int i = 0; i < E.length; i++) {\n      for (int j = 0; j < E[i].length; j++) {\n        derivative[index++] = (E[i][j] - Ehat[i][j]);\n        if (VERBOSE) {\n          log.info(\"linearWeights deriv(\" + i + \",\" + j + \") = \" + E[i][j] + \" - \" + Ehat[i][j] + \" = \" + derivative[index - 1]);\n        }\n      }\n    }","sourceCodeStart":652,"sourceCodeEnd":688,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/ie/crf/CRFNonLinearLogConditionalObjectiveFunction.java#L652-L688","documentation":"During CRFNonLinearLogConditionalObjectiveFunction.calculate(), the accumulated log-probability of the document under the non-linear CRF model became NaN. The library treats NaN probabilities as an unrecoverable numerical failure (usually from exploding/vanishing activations, zero denominator in softmax, or inconsistent weights), so calculate() throws a RuntimeException instead of returning a NaN value to the optimizer.","triggerScenarios":"Calling calculate() (typically via a minimizer like QNMinimizer on CRFClassifier.train with useNonLinearCRF=true) when model weights passed in x contain NaN/Inf, when softmax denominators underflow to 0, or when intermediate expected counts overflow to infinity and Inf-Inf yields NaN.","commonSituations":"Training diverges after a too-large learning rate or bad initial weights; extremely large feature values scaled without normalization; useOutputLayer with degenerate softmax inputs; running many iterations on numeric-unstable data so weights drift to Inf/NaN.","solutions":["Check the weight vector x for NaN/Inf before calling calculate(); if present, restart training with lower learning rate and smaller maxQNIter/QuasiNewton parameters.","Normalize/scale input feature values so activations stay in a numerically safe range.","Try flags.softmaxOutputLayer with proper flags.sparseOutputLayer or flags.tieOutputLayer, or disable useOutputLayer to use the stable linear model.","Reduce regularization or inspect training data for pathological (huge or constant) features causing overflow."],"exampleFix":"// before\nif (Double.isNaN(prob)) { // shouldn't be the case\n  throw new RuntimeException(\"Got NaN for prob in CRFNonLinearLogConditionalObjectiveFunction.calculate()\");\n}\n// after (caller-side guard before optimization)\nfor (double w : x) {\n  if (Double.isNaN(w) || Double.isInfinite(w)) {\n    throw new IllegalArgumentException(\"non-finite parameter before calculate(): \" + w);\n  }\n}","handlingStrategy":"validation","validationCode":"// Java, before training\nfor (double w : initialWeights) {\n  if (Double.isNaN(w) || Double.isInfinite(w))\n    throw new IllegalArgumentException(\"initial weights must be finite\");\n}\n// also check input features are bounded\nassert featureValues.stream().allMatch(v -> Double.isFinite(v) && Math.abs(v) < 1e6);","typeGuard":null,"tryCatchPattern":"// wrap training\ntry {\n  classifier.train(trainingProps);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"Got NaN for prob\")) {\n    // restart with smaller learning rate / fewer iterations / rescaled features\n  } else throw e;\n}","preventionTips":["Always scale/normalize features before non-linear CRF training","Use small random initial weights within the function's own epsilon initialization","Cap iterations and monitor the objective value each iteration for divergence","Avoid exotic output-layer flag combinations in early experiments"],"tags":["crf","nan","numerical","training"],"backgroundTag":"internal-invariant-violation","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}