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
相关产品推荐
相关产品推荐

