You need to enable JavaScript to run this app. 猫狗分类模型在Jupyter Notebook可运行,导入Android推理时触发数组越界崩溃
优惠活动
大模型
产品
解决方案
定价
更多

猫狗分类模型在Jupyter Notebook可运行,导入Android推理时触发数组越界崩溃

崩溃根因定位

报错的逻辑链完全清晰:你在代码里默认模型输出张量转成float数组后长度为2,分别对应猫、狗两个类别的预测概率,但实际运行时这个数组的真实长度仅为1,当代码尝试访问下标为1的元素时,直接触发数组越界崩溃。

匹配这个现象的常见诱因主要有两类:

  • 模型输出层配置不匹配:你在Jupyter里训练的猫狗二分类模型,最后一层用的是单神经元+Sigmoid激活的配置,这是二分类任务的常规写法。这种结构下输出张量形状是[1,1],经TensorBuffer转换后的float数组自然只有1个元素,根本不存在第二个值。你在Jupyter中能正常跑通,是因为推理逻辑本身就是读取这唯一的概率值做阈值判断,没意识到导出的模型输出结构和Android端代码的预期存在偏差。
  • 模型导出的维度处理错误:就算你最后层是双神经元Softmax输出,导出tflite时如果错误压缩了维度,把原本[1,2]形状的输出压成了长度1的向量,也会出现同样的越界问题。
对应解决方案
  1. 先确认实际输出结构:别硬编码访问数组下标,在推理逻辑里加日志打印数组真实长度,摸清楚输出形状再做解析:
    float[] outputArr = outputFeature0.getFloatArray();
    Log.d("ModelCheck", "输出数组实际长度: " + outputArr.length);
    
  2. 验证后如果确实是Sigmoid单输出的二分类模型(也就是看到数组长度为1),不需要回头重新训练模型,直接调整结果解析逻辑就行:数组里的唯一值,就是你训练时约定的某一类(比如“狗”)的预测概率,另一类的概率直接用1减去这个值就能算出来,把原来的TextView赋值逻辑替换掉:
    float dogProb = outputFeature0.getFloatArray()[0];
    float catProb = 1 - dogProb;
    textView.setText(String.format("猫的预测概率: %.2f\n狗的预测概率: %.2f", catProb, dogProb));
    
  3. 如果你希望模型输出是两个维度的Softmax概率(和你最初的代码预期一致),就回到训练环节把输出层从单神经元Sigmoid改成2神经元Softmax,重新导出tflite模型替换Android端assets目录下的旧模型,此时输出数组长度就会变成2,原来的下标访问逻辑就不会触发越界。
  • 附带优化建议:你现在的写法是每次点预测就新建一次Model实例、推理完立刻关闭,这会带来不必要的IO开销,建议把Model实例的初始化放到Activity的onCreate里全局创建,只在onDestroy回调里调用model.close()释放资源,减少预测过程的卡顿。

内容的提问来源于stack exchange,提问作者Sy.Moh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 11:15:03