You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中TFLite情感识别模型无法输出正确结果求助

问题排查与修复方案

核心问题分析

你看到的日志输出是对象引用而非预期的数值数组,原因是直接调用了TensorBuffer和模型输出对象的toString()方法,默认只会打印对象内存地址,不会输出内部数据。另外,预处理流程可能和模型训练时的输入格式不匹配,导致输出结果异常。

具体修复步骤

1. 获取模型的实际输出数组

替换原日志和文本显示代码,直接读取TensorBuffer的floatArray属性获取数值数组:

// 原错误代码
// tvOutput.text = outputFeature0.toString()
// Log.d("TAG", outputs.toString())
// Log.d("TAG", outputFeature0.toString())

// 修复后代码
val resultArray = outputFeature0.floatArray
val resultString = resultArray.contentToString()
tvOutput.text = resultString
Log.d("TAG", "输出数组: $resultString")

2. 修正图像预处理流程

确保图像预处理和模型训练时的输入格式完全一致(FER2013数据集为48x48灰度图,需注意像素值范围):

private fun outputGenerator(bitmap: Bitmap){
    val model = MoodDetector.newInstance(this)
    
    // 缩放图像到模型要求的48x48尺寸
    val newBitmap = Bitmap.createScaledBitmap(bitmap, 48, 48, true)
    
    // 手动转换为灰度图并匹配训练时的像素值范围(此处假设训练用0-1归一化,若用0-255则去掉/255.0f)
    val grayscaleArray = convertToGrayscale(newBitmap)
    
    // 创建符合模型输入要求的TensorBuffer
    val inputFeature0 = TensorBuffer.createFixedSize(intArrayOf(1, 48, 48, 1), DataType.FLOAT32)
    inputFeature0.loadArray(grayscaleArray)
    
    // 运行推理
    val outputs = model.process(inputFeature0)
    val outputFeature0 = outputs.outputFeature0AsTensorBuffer
    
    // 获取并显示结果
    val resultArray = outputFeature0.floatArray
    val resultString = resultArray.contentToString()
    tvOutput.text = resultString
    Log.d("TAG", "输出数组: $resultString")
    
    // 可选:识别概率最高的情绪
    val emotions = arrayOf("愤怒", "厌恶", "恐惧", "开心", "悲伤", "惊讶", "中性")
    val maxIndex = resultArray.indices.maxByOrNull { resultArray[it] } ?: -1
    if(maxIndex != -1){
        tvOutput.text = "主导情绪: ${emotions[maxIndex]}\n$resultString"
    }
    
    model.close()
}

// 自定义灰度转换函数,确保和训练预处理一致
private fun convertToGrayscale(bitmap: Bitmap): FloatArray {
    val width = bitmap.width
    val height = bitmap.height
    val pixels = IntArray(width * height)
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height)
    
    return pixels.map { pixel ->
        val r = (pixel shr 16 and 0xFF) / 255.0f
        val g = (pixel shr 8 and 0xFF) / 255.0f
        val b = (pixel and 0xFF) / 255.0f
        // 使用标准灰度转换公式
        0.299f * r + 0.587f * g + 0.114f * b
    }.toFloatArray()
}

3. 额外检查点

  • 确认TFLite模型的输入形状为(1,48,48,1),输出形状为(1,7)(对应FER2013的7种情绪)
  • 若模型训练时使用的是0-255像素值而非归一化值,需修改convertToGrayscale函数去掉/255.0f
  • 确保TFLite模型未被量化,或量化后有对应的解量化处理逻辑

内容的提问来源于stack exchange,提问作者user19706673

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:17:03