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

TFLite目标检测模型输出形状异常问题求助

问题分析与解决方案:TFLite Model Maker训练EfficientDet Lite0异常问题

问题概述

在WSL Ubuntu 20.04/22.04环境下,通过Conda创建Python3.9环境,使用tflite_model_maker训练efficientdet_lite0目标检测模型(Pascal VOC格式数据集)时,出现以下问题:

  • 训练阶段弹出警告:Node 'resample_p7/PartitionedCall'输出数与_output_shapes属性指定不符
  • 导出的TFLite模型输出形状不符合TensorFlow官方规定的4种标准输出(detection_boxes: [1, num_boxes,4]等)
  • 测试时输出张量为空,多次尝试无法解决

环境配置代码

# Install Miniconda
!apt install wget
!wget https://repo.anaconda.com/miniconda/Miniconda3-py37_4.9.2-Linux-x86_64.sh
!chmod +x Miniconda3-py37_4.9.2-Linux-x86_64.sh
!bash ./Miniconda3-py37_4.9.2-Linux-x86_64.sh -b -f -p /usr/local

# Update Conda
!conda update -n base -c defaults conda -y

# Create a Python 3.9 environment
!conda create --name py39_environment python=3.9 -y

# Initialize shell for Conda
!conda init bash

# Activate the environment and check Python version
!source activate py39_environment && python --version
!source /usr/local/etc/profile.d/conda.sh && conda activate py39_environment && pip install tflite_model_maker
!source /usr/local/etc/profile.d/conda.sh && conda activate py39_environment && pip install -q pycocotools
!source /usr/local/etc/profile.d/conda.sh && conda activate py39_environment && pip install opencv-python-headless
!source /usr/local/etc/profile.d/conda.sh && conda activate py39_environment && pip uninstall -y tensorflow && pip install -q tensorflow==2.8.0
!source /usr/local/etc/profile.d/conda.sh && conda activate py39_environment && pip install ipykernel
!source /usr/local/etc/profile.d/conda.sh && conda activate py39_environment && pip install --upgrade numba llvmlite

训练代码(train.py)

import numpy as np
import os

np.object = object
np.bool = bool
np.complex = complex

from tflite_model_maker.config import ExportFormat
from tflite_model_maker import model_spec
from tflite_model_maker import object_detector

import tensorflow as tf
assert tf.__version__.startswith('2')

tf.get_logger().setLevel('ERROR')
from absl import logging
logging.set_verbosity(logging.ERROR)

label_map = {1: 'Plastic', 2: 'Trash'} 

train_images_dir = '/trashnet-training/pascal_voc/train/images'
train_annotations_dir = '/trashnet-training/pascal_voc/train/Annotations'
val_images_dir = '/trashnet-training/pascal_voc/valid/images/'
val_annotations_dir = '/trashnet-training/pascal_voc/valid/Annotations'

train_data = object_detector.DataLoader.from_pascal_voc(
    train_images_dir, train_annotations_dir, label_map=label_map)

validation_data = object_detector.DataLoader.from_pascal_voc(
    val_images_dir, val_annotations_dir, label_map=label_map)

spec = model_spec.get('efficientdet_lite0')

model = object_detector.create(train_data=train_data, 
                               model_spec=spec, 
                               validation_data=validation_data, 
                               epochs=50, 
                               batch_size=10, 
                               train_whole_model=True)

model.evaluate(validation_data)

TFLITE_FILENAME = 'trained_model.tflite'
LABELS_FILENAME = 'model-labels.txt'

model.export(export_dir='.', tflite_filename=TFLITE_FILENAME, label_filename=LABELS_FILENAME,
             export_format=[ExportFormat.TFLITE, ExportFormat.LABEL])

测试代码(test_model.py)

import tensorflow as tf
import numpy as np


interpreter = tf.lite.Interpreter(model_path="trained_model.tflite")
interpreter.allocate_tensors()


input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

interpreter.invoke()

output_data = interpreter.get_tensor(output_details[0]['index'])
input_data = interpreter.get_tensor(input_details[0]['index'])
print(f"Input tensor: {input_data}")
print(f"Output tensor: {output_data}")


tf.lite.experimental.Analyzer.analyze(model_path="trained_model.tflite")

原因分析与修复方案

1. 版本兼容性不匹配

TensorFlow与TFLite Model Maker版本必须严格对应,直接pip install tflite_model_maker会安装最新版本,与指定的TensorFlow 2.8.0不兼容,导致模型结构转换异常。

修复:
安装与TensorFlow 2.8.0匹配的TFLite Model Maker版本,替换环境配置中的tflite_model_maker安装命令:

pip install tflite-model-maker==0.4.1

2. NumPy手动修改的潜在风险

代码中手动修改NumPy属性(np.object = object等)是为了兼容高版本NumPy,但这种修改会干扰TensorFlow内部的张量形状处理逻辑,尤其在模型导出阶段引发异常。

修复:
降级NumPy到兼容版本,避免手动修改:

pip install numpy==1.23.5

3. 训练与导出配置问题

启用train_whole_model=True会修改模型的原始结构,TFLite转换时可能无法正确识别输出节点;同时测试代码未输入有效图像数据,导致输出为空。

修复:

  • 先尝试关闭train_whole_model=True(改为False),仅训练模型头部,验证导出是否正常;
  • 修改测试代码,添加图像预处理并输入有效数据:
import tensorflow as tf
import numpy as np

def preprocess_image(image_path, input_shape):
    # 加载图像
    img = tf.io.read_file(image_path)
    img = tf.image.decode_jpeg(img, channels=3)
    # 调整尺寸匹配模型输入
    img = tf.image.resize(img, input_shape[:2])
    # 添加batch维度
    img = tf.expand_dims(img, axis=0)
    # 归一化(EfficientDet Lite通常用0-1范围)
    img = img / 255.0
    return img

interpreter = tf.lite.Interpreter(model_path="trained_model.tflite")
interpreter.allocate_tensors()

input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# 替换为你的测试图像路径
img_data = preprocess_image("test_plastic.jpg", input_details[0]['shape'])
# 设置输入张量
interpreter.set_tensor(input_details[0]['index'], img_data)
# 执行推理
interpreter.invoke()

# 获取所有输出张量
detection_boxes = interpreter.get_tensor(output_details[0]['index'])
detection_classes = interpreter.get_tensor(output_details[1]['index'])
detection_scores = interpreter.get_tensor(output_details[2]['index'])
num_detections = interpreter.get_tensor(output_details[3]['index'])

print(f"检测框:{detection_boxes[0][:int(num_detections[0])]}")
print(f"类别:{detection_classes[0][:int(num_detections[0])]}")
print(f"置信度:{detection_scores[0][:int(num_detections[0])]}")

4. 数据集标签映射一致性问题

需确认Pascal VOC标注文件中的类别ID与代码中的label_map完全匹配,若XML文件中<object>的ID不是1和2,会导致数据加载无效,模型训练无有效特征。

修复:
检查Annotations文件夹中的XML文件,查看<object>对应的类别ID,调整label_map为实际标注的ID,例如如果标注中Plastic的ID是0,则修改为:

label_map = {0: 'Plastic', 1: 'Trash'}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:10:54