TensorFlow Object Detection生成tfrecord时遇TypeError问题求助
解决TensorFlow Object Detection生成TFRecord时的TypeError: None has type NoneType问题
这个错误的核心原因很明确:你的generate_tfrecord.py脚本在把类别名称转换为整数ID时,出现了None值——也就是某个标注的类别没有被正确映射到对应的整数,导致在调用int64_list_feature时传入了无效的None类型数据。结合你用labelImg标注、xml_to_csv.py转CSV的流程,下面是具体的排查和解决步骤:
1. 检查generate_tfrecord.py中的类别映射函数
几乎所有版本的generate_tfrecord.py里都会有一个class_text_to_int函数,用来把CSV里的类别字符串转成模型需要的整数ID。比如常见的写法:
def class_text_to_int(row_label): if row_label == 'cat': return 1 elif row_label == 'dog': return 2 else: return None # 问题往往出在这里!
- 可能的问题:CSV里存在这个函数未覆盖的类别(比如你标了
bird但函数里没写),或者类别名称大小写/拼写不匹配(比如你标了Cat但函数里是cat,或者多了空格dog),导致函数返回None。 - 解决方法:
- 先把CSV里所有出现的类别列列出来(比如用Excel筛选
class列的唯一值)。 - 把这些类别全部添加到映射函数里,并且严格匹配大小写、拼写和空格。
- 把
else分支改成抛出异常,这样能快速定位未匹配的类别,而不是返回None:def class_text_to_int(row_label): label_mapping = { 'cat': 1, 'dog': 2, 'bird': 3 # 把你所有的类别都加在这里 } if row_label not in label_mapping: raise ValueError(f"发现未定义的类别:{row_label},请检查标注和映射函数!") return label_mapping[row_label]
- 先把CSV里所有出现的类别列列出来(比如用Excel筛选
2. 检查CSV文件中的类别列
打开train_labels.csv,重点看class列:
- 有没有空单元格?如果某个XML里的
<name>标签是空的,xml_to_csv.py转成CSV后就会出现空值,导致row_label是空字符串,映射函数返回None。 - 有没有拼写错误?比如把
dog写成dgo,或者不小心输入了特殊字符。 - 有没有前后空格?比如
dog(注意前后的空格),这种情况下映射函数里的'dog'是匹配不上的。 - 解决方法:清理CSV里的空值、错误拼写和多余空格,确保所有类别名称和映射函数里的完全一致。
3. 检查原始XML标注文件
虽然是用labelImg生成的,但偶尔也会出现异常标注:
- 有没有某个XML里的
<object>标签下的<name>是空的?比如:<object> <name></name> <!-- 空的类别名称 --> <bndbox> <xmin>100</xmin> <ymin>200</ymin> <xmax>300</xmax> <ymax>400</ymax> </bndbox> </object> - 有没有不小心选了labelImg里的默认类别(比如
_background_)或者其他你不需要的类别? - 解决方法:可以写个简单的Python脚本遍历所有XML文件,找出
<name>为空或不符合预期的文件,然后重新标注这些异常的文件。
4. 检查xml_to_csv.py的转换逻辑
有些版本的xml_to_csv.py可能在提取类别时依赖XML标签的顺序,导致提取错误:
比如旧的写法可能用member[0].text来提取类别,但如果XML里<object>下的标签顺序变了(比如先写了pose再写name),就会提取到错误的内容。
- 解决方法:把提取类别代码改成通过标签名查找,更可靠:
这样不管标签顺序如何,都能正确提取# 替换原来的member[0].text member.find('name').text<name>标签的内容。
按照上面的步骤排查,你应该能快速找到导致None值的根源,解决这个TypeError问题。
内容的提问来源于stack exchange,提问作者Pais
相关产品推荐
相关产品推荐

