单通道Yolov4-tiny转TensorFlow后性能骤降问题排查与解决
摘要
单通道TensorFlow模型与三通道模型表现不同。两者均成功从Darknet转换为TensorFlow,但单通道模型转换后性能下降明显。
任务说明
我拥有两个训练完成的Yolov4-tiny Darknet权重文件(.weights),一个为灰度输入(1通道),另一个为彩色输入(3通道)。使用某开源仓库将两者转换为TensorFlow checkpoint格式。两种模型均基于灰度图像训练并运行,三通道模型的输入为灰度图像转换后的三通道数据。
- Python版本:3.10.11
- TF版本:2.10.1
问题描述
彩色输入权重文件转换后,通过tf.keras.Models.load_model(X)加载使用正常;但灰度输入权重文件转换后,TensorFlow加载的模型性能骤降,在彩色模型能完美检测的场景中,检测效果极差甚至无检测。值得注意的是,偶尔检测到的框位置大致正确,但宽高可能存在偏差。
我已了解该仓库的常见问题(如硬编码内容等),并针对转换/模型加载修改了相应参数,转换和加载过程均无报错。
已确认输入层
- 灰度模型:
(None,640,640,1) - 彩色模型:
(None,640,640,3)
测试图像通过opencv-python加载,已验证其有效性,若输入维度错误会触发报错。
经model.summary()确认,除输入层外两者架构一致。但发现多年前用旧TF版本转换的三通道模型架构与新转换的模型存在差异,部分tile层缺失,部分TensorFlow操作名称不同(可能因TF版本差异导致)。
旧彩色模型:
tf_op_layer_Sigmoid (TensorFlo (None, 40, 40, 3, 2 0 ['tf_op_layer_split_3[0][0]'] wOpLayer) ) tf_op_layer_Tile/multiples (Te (5,) 0 ['tf_op_layer_strided_slice[0][0] nsorFlowOpLayer) '] tf_op_layer_Sigmoid_3 (TensorF (None, 20, 20, 3, 2 0 ['tf_op_layer_split_4[0][0]'] lowOpLayer) ) )
新灰度模型:
tf.math.sigmoid (TFOpLambda) (None, 40, 40, 3, 2 0 ['tf.split_3[0][0]'] ) ---tile layer missing here--- tf.math.sigmoid_3 (TFOpLambda) (None, 20, 20, 3, 2 0 ['tf.split_4[0][0]'] )
目前我陷入困境,寻求帮助。
已尝试的操作
- 调整Yolov4-tiny Head解码模块 -> 即使模型能正常加载(解码维度错误会触发报错),也无任何变化
- 前文提及的旧三通道模型(多年前已完成Darknet转TensorFlow),以相同方式加载后运行正常
解决方法
我在C++中打印了模型层的形状(该环境下模型运行正常),发现形状完全不同。第一个卷积层完全没有下采样。检查Darknet用于解析模型的.cfg文件,发现第一个卷积层有一行“size=3stride=2”,size被正确解析,但stride未被解析,默认设为1,导致第一个卷积层形状为(640,640,32),而非预期的正确形状(320,320,32)。将权重加载到错误架构中自然性能极差,而三通道模型训练时使用的.cfg文件无此错误,因此运行正常。
内容的提问来源于stack exchange,提问作者Kuski

