TFLite推理出现置信度全为负值的问题求助
TFLite模型输出负值问题的排查与解决
核心问题定位
你遇到的模型输出全为负值的情况,主要由以下几个明确的错误和不匹配导致:
1. 预处理函数的低级错误
你的preprocess函数中,已经完成了图像的归一化操作,但最终返回的是未处理的原始图像,而非归一化后的结果:
def preprocess(image): *** some image cropping, just as for training data *** image = cv2.resize(image, (224, 224)) new_img = image.astype(np.float32) new_img /= 255.0 return image # ❌ 这里应该返回new_img
这会导致模型输入的是0-255范围的uint8图像,和训练时的0-1浮点型输入完全不匹配,直接引发输出异常。
2. 图像通道顺序不匹配
OpenCV默认读取图像为BGR通道顺序,而绝大多数迁移学习预训练模型的训练输入是RGB顺序。通道顺序不匹配会导致模型提取的特征完全错误,进而输出异常数值。
3. 模型输出为Logits而非置信度
你的TFLite模型导出时大概率没有包含Softmax层,此时输出的是未归一化的logits(原始预测值),这类数值本身可以是正或负,不能直接当作0-1范围的置信度使用。
修复步骤
步骤1:修正预处理函数
修改preprocess函数,确保返回归一化后的图像,并转换通道顺序:
def preprocess(image): # 执行和训练时完全一致的裁剪操作 *** some image cropping, just as for training data *** # 转换通道:BGR -> RGB image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 调整尺寸到模型要求的224x224 image = cv2.resize(image, (224, 224)) # 类型转换与归一化 new_img = image.astype(np.float32) new_img /= 255.0 # 若训练时用了均值方差归一化,需添加以下代码(替换为训练时的均值方差) # mean = np.array([0.485, 0.456, 0.406], dtype=np.float32) # std = np.array([0.229, 0.224, 0.225], dtype=np.float32) # new_img = (new_img - mean) / std return new_img
步骤2:对输出应用Softmax转换
在推理代码中,将模型输出的logits转换为0-1范围的置信度:
# 替换原输出处理逻辑 interpreter.invoke() # 注意:output_details不需要每次循环都获取,放在循环外更高效 output_data = interpreter.get_tensor(output_details[0]["index"]) pred_logits = np.squeeze(output_data) # 计算置信度 confidences = np.exp(pred_logits) / np.sum(np.exp(pred_logits)) classi = np.argmax(confidences) # 现在可以用confidences做阈值判断,比如: if confidences[classi] < 0.5: # 置信度不足,标记为不确定 label_text = "Unknown" else: label_text = labels[classi]
步骤3:优化推理效率
将output_details = interpreter.get_output_details()移到循环外部,避免每次推理重复获取,提升视频流处理速度:
# 放在初始化部分,循环外 input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() input_shape = input_details[0]["shape"] vid_file = "/path/to/video.mp4" cap = cv2.VideoCapture(vid_file) while cap.isOpened(): _, frame = cap.read() # ... 后续代码 ...
内容的提问来源于stack exchange,提问作者André
相关产品推荐
相关产品推荐

