{"record":{"id":"aeae9f6b315253e9","repo":"babalae/better-genshin-impact","slug":"logits-logits-length-elements-e","errorCode":null,"errorMessage":"角色头像模型元素输出数量异常：logits={logits.Length}, elements={elementTypes.Length}","messagePattern":"角色头像模型元素输出数量异常：logits=(.+?), elements=(.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/Common/Job/AvatarGridIconRecognizer.cs","lineNumber":127,"sourceCode":"            .Select(group => group.OrderByDescending(candidate => candidate.Score).First())\n            .OrderByDescending(candidate => candidate.Score)\n            .FirstOrDefault() ?? AvatarGridIconCandidate.Empty;\n\n        if (!recognizeElementType || candidate == AvatarGridIconCandidate.Empty)\n        {\n            return candidate;\n        }\n\n        var logits = results.First(result => result.Name == \"element_logits\").AsEnumerable<float>().ToArray();\n        var elementTypes = _prototypes\n            .Select(prototype => prototype.ElementType)\n            .Where(elementType => !string.IsNullOrWhiteSpace(elementType))\n            .Distinct(StringComparer.Ordinal)\n            .OrderBy(elementType => elementType, StringComparer.Ordinal)\n            .ToArray();\n        if (logits.Length != elementTypes.Length || logits.Length == 0)\n        {\n            throw new InvalidOperationException(\n                $\"角色头像模型元素输出数量异常：logits={logits.Length}, elements={elementTypes.Length}\");\n        }\n\n        var predictedElementType = elementTypes[Array.IndexOf(logits, logits.Max())];\n        return candidate with { ElementType = predictedElementType };\n    }\n\n    /// <summary>\n    /// 按模型训练协议生成头像和元素图标两个输入张量。\n    /// </summary>\n    /// <remarks>\n    /// 完整头像缩放为 115x115；元素输入必须从该图左上角裁剪 48x48 后再缩放为 64x64。\n    /// 两个输入均执行 BGR→RGB 及 [-1,1] 归一化，不能用完整头像代替元素输入。\n    /// </remarks>\n    internal static (DenseTensor<float> Image, DenseTensor<float> ElementImage) CreateInputTensors(Mat mat)\n    {\n        using Mat resized = mat.Resize(new Size(InputSize, InputSize));\n        using Mat elementRoi = resized.SubMat(0, ElementRoiSize, 0, ElementRoiSize);","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Job/AvatarGridIconRecognizer.cs#L109-L145","documentation":"Thrown as InvalidOperationException by AvatarGridIconRecognizer when the ONNX model's 'element_logits' output tensor length does not match the count of distinct element types derived from avatar.csv prototypes. The recognizer maps each logit index to a sorted distinct element type; a mismatch means the model and the CSV are out of sync (different training-time class count vs. prototype data).","triggerScenarios":"Calling Recognize(avatarMat, elementMat, recognizeElementType: true) when the avatar.onnx model was updated/retrained with a different number of element classes than the distinct element_type values present in avatar.csv.","commonSituations":"The ONNX model file (avatar.onnx) was replaced with a newer version that has more/fewer element output nodes, but avatar.csv was not regenerated to match. The prototype CSV has blank element_type values that change the distinct count. A partial update of the AvatarGridIcon asset bundle.","solutions":["Ensure avatar.onnx and avatar.csv are from the same release/training run so element class counts align.","Regenerate avatar.csv from the same training data used to export the ONNX model.","If the model is intentionally updated, update the CSV and re-test element recognition."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"// After loading prototypes, verify element count matches model output metadata\nvar distinctElements = prototypes.Select(p => p.ElementType).Where(e => !string.IsNullOrWhiteSpace(e)).Distinct().Count();\n// Compare against model metadata: _session.ModelMetadata or output node shape","typeGuard":"null","tryCatchPattern":"try { recognizer.Recognize(avatar, element, true); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"元素输出数量异常\")) { /* model/CSV mismatch — update assets */ }","preventionTips":["Always ship avatar.onnx and avatar.csv as a matched pair from the same training run.","Add a startup self-test that verifies the model's element output dimension matches the CSV."],"tags":["onnx","avatar-recognition","model-mismatch","csv-data"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}