Android端TFLite模型输出值过多,如何归一化得到220类结果?
解决TFLite模型输出维度不符与归一化问题
第一步:修正输出维度,得到220个类别对应值
你现在得到大量输出值,大概率是模型输出的是特征图张量(比如形状为[1, 7, 7, 220]这类多维结构),而非直接的220个类别logits/概率值。先通过代码确认输出形状:
val outputFeature0 = outputs.outputFeature0AsTensorBuffer Log.d("TFLiteDebug", "输出形状: ${outputFeature0.shape.contentToString()}")
如果输出形状是[1, H, W, 220](H、W是特征图的高宽),需要对每个类别通道做全局平均池化,把多维特征压缩成220个值:
val outputArray = outputFeature0.floatArray val outputShape = outputFeature0.shape val numClasses = outputShape[3] // 这里应该是220 val featureSize = outputShape[1] * outputShape[2] val classValues = FloatArray(numClasses) { 0f } // 遍历所有元素,按类别通道累加后取平均 for (i in outputArray.indices) { val classIdx = i % numClasses classValues[classIdx] += outputArray[i] } // 得到每个类别的平均输出值(共220个) val classLogits = classValues.map { it / featureSize }.toFloatArray()
如果输出形状是其他多维结构(比如[1, 220, 7, 7]),只需要调整索引计算逻辑,确保最终提取出220个类别对应的聚合值即可。
第二步:对220个值做归一化处理
分类场景下最常用的归一化方式是Softmax,它会将输出转换为0~1之间的概率值,且所有类别概率总和为1,代码实现如下:
fun softmax(logits: FloatArray): FloatArray { // 先计算每个logit的指数值,减去最大值避免数值溢出 val maxLogit = logits.maxOrNull() ?: 0f val expValues = logits.map { Math.exp((it - maxLogit).toDouble()).toFloat() } val sumExp = expValues.sum() // 每个指数值除以总和得到概率 return expValues.map { it / sumExp }.toFloatArray() } // 用上面得到的220个logit值生成归一化后的概率 val normalizedProbabilities = softmax(classLogits)
如果你的原模型在训练时最后一层已经加了Softmax激活,那TFLite的输出本身就是概率值,不需要再做Softmax,直接调整维度得到220个值即可。
内容的提问来源于stack exchange,提问作者özgür değirmen
相关产品推荐
相关产品推荐

