TensorFlow 2.2中YOLOv4训练时的形状不匹配问题求助
YOLOv4训练时形状不匹配错误(从DarkNet cfg加载模型)
我给自己的YOLOv3实现新增了直接从DarkNet cfg文件加载模型的功能,目的是提升使用便利性。测试后发现YOLOv3和YOLOv4配置都能正常运行,但YOLOv4训练时会触发形状不匹配错误,恳请社区帮忙排查解决这个问题,相关资源我可以提供。
复现代码
if __name__ == '__main__': tr = Trainer((608, 608, 3), '../Config/yolo4.cfg', '../Config/beverly_hills.txt', 1344, 756, score_threshold=0.1, train_tf_record='../Data/TFRecords/beverly_hills_train.tfrecord', valid_tf_record='../Data/TFRecords/beverly_hills_test.tfrecord') tr.train( 100, 8, 1e-3, dataset_name='beverly_hills', merge_evaluation=False, n_epoch_eval=10, clear_outputs=True )
相关文件
- bh_labels.csv (794 Kb)
- beverly_hills.txt (162 B)
- beverly_hills_train.tfrecord (509 Mb)
- beverly_hills_test.tfrecord (89 Mb)
错误信息
batch_size=4时:
Traceback (most recent call last): File "trainer.py", line 629, in <module> clear_outputs=True File "../Helpers/utils.py", line 62, in wrapper result = func(*args, **kwargs) File "trainer.py", line 490, in train validation_data=valid_dataset, File "/root/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 108, in _method_wrapper return method(self, *args, **kwargs) File "/root/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 1090, in fit tmp_logs = train_function(iterator) File "/root/.local/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py", line 766, in __call__ result = self._call(*args, **kwds) File "/root/.local/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py", line 826, in _call return self._stateless_fn(*args, **kwds) File "/root/.local/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 2811, in __call__ return graph_function._filtered_call(args, kwargs) # pylint: disable=protected-access File "/root/.local/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 1838, in _filtered_call cancellation_manager=cancellation_manager) File "/root/.local/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 1914, in _call_flat ctx, args, cancellation_manager=cancellation_manager)) File "/root/.local/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 549, in call ctx=ctx) File "/root/.local/lib/python3.6/site-packages/tensorflow/python/eager/execute.py", line 60, in quick_execute inputs, attrs, num_outputs) tensorflow.python.framework.errors_impl.InvalidArgumentError: Incompatible shapes: [4,76,76,3,1] vs. [4,19,19,3,1] [[node yolo_loss/logistic_loss/mul (defined at ../Helpers/utils.py:260) ]] [Op:__inference_train_function_38735] Errors may have originated from an input operation. Input Source operations connected to node yolo_loss/logistic_loss/mul: yolo_loss/split_1 (defined at ../Helpers/utils.py:222) yolo_loss/split (defined at ../Helpers/utils.py:196) Function call stack: train_function
batch_size=8时:
Traceback (most recent call last): File "/Users/emadboctor/Desktop/Code/yolov3-keras-tf2/Main/trainer.py", line 693, in <module> clear_outputs=True, File "/Users/emadboctor/Desktop/Code/yolov3-keras-tf2/Helpers/utils.py", line 62, in wrapper result = func(*args, **kwargs) File "/Users/emadboctor/Desktop/Code/yolov3-keras-tf2/Main/trainer.py", line 526, in train validation_data=valid_dataset, File "/usr/local/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 66, in _method_wrapper return method(self, *args, **kwargs) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 848, in fit tmp_logs = train_function(iterator) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 580, in __call__ result = self._call(*args, **kwds) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 644, in _call return self._stateless_fn(*args, **kwds) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 2420, in __call__ return graph_function._filtered_call(args, kwargs) # pylint: disable=protected-access File "/usr/local/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 1665, in _filtered_call self.captured_inputs) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 1746, in _call_flat ctx, args, cancellation_manager=cancellation_manager)) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 598, in call ctx=ctx) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/eager/execute.py", line 60, in quick_execute inputs, attrs, num_outputs) tensorflow.python.framework.errors_impl.InvalidArgumentError: Incompatible shapes: [8,13,13,3,2] vs. [8,52,52,3,2] [[node gradient_tape/yolo_loss/sub_5/BroadcastGradientArgs (defined at Users/emadboctor/Desktop/Code/yolov3-keras-tf2/Main/trainer.py:526) ]] [Op:__inference_train_function_42744] Function call stack: train_function
问题分析 & 可能的解决方案
从错误信息来看,核心问题是YOLOv4的输出特征层尺寸和损失计算时的目标框标签尺寸不匹配。YOLOv4相比YOLOv3在骨干网络(CSPDarknet53)和颈部结构(SPP+PAN)上有差异,输出的三个特征层尺寸虽然还是19x19、38x38、76x76(对应输入608x608),但你的损失计算逻辑可能还是沿用了YOLOv3的标签处理方式,或者在从cfg文件加载模型时,特征层的顺序、锚框的对应关系搞反了。
这里有几个可以排查的方向:
- 锚框与特征层的对应关系:
YOLOv4的cfg文件中定义的锚框顺序是否和你的损失计算代码中对应特征层的顺序一致?比如,YOLOv3通常是大锚框对应小特征图(19x19),中锚框对应38x38,小锚框对应76x76;检查你加载cfg时是否正确解析了锚框,并将它们分配到了正确的特征层上。 - 标签预处理逻辑:
训练时生成的标签张量,每个特征层对应的网格尺寸是否和模型输出的特征层尺寸匹配?比如,错误中出现的[4,76,76,3,1]和[4,19,19,3,1],说明损失计算时把本该对应76x76层的标签和19x19层的输出做了运算,大概率是标签生成时的网格划分出错了,或者特征层顺序搞反了。 - 模型输出层的解析:
检查从cfg文件加载模型时,是否正确识别了YOLOv4的三个输出层,并且输出的顺序是否和损失计算代码预期的一致。YOLOv4的输出层在cfg中的位置可能和YOLOv3不同,导致你加载时把输出层的顺序搞反了,进而导致损失计算时尺寸不匹配。 - 输入尺寸与特征层的计算:
确认输入尺寸608x608对应的特征层尺寸是否正确:608/32=19,608/16=38,608/8=76。如果你的代码中在计算特征层尺寸时出现了错误(比如误用了YOLOv3的其他倍数),也会导致这个问题。
建议先重点检查锚框分配和特征层输出顺序这两个点,这是YOLOv3到YOLOv4迁移时最容易出错的地方。如果需要进一步排查,可以提供utils.py中损失计算部分的代码,以及cfg文件加载时解析输出层和锚框的逻辑。
内容的提问来源于stack exchange,提问作者user12690225
相关产品推荐
相关产品推荐

