时间:2023年1月9日
一.问题描述
在做目标检测时,以DETR模型为例,在加载数据集时会用到metic_logger.log_every() 函数,来记录训练时间、损失大小等日志信息,代码段如图所示:
# 节选自deformable_detr/engine.py/train_one_epoch()
for _ in metric_logger.log_every(range(len(data_loader)), print_freq, header):
outputs = model(samples)
loss_dict = criterion(outputs, targets)
自己重构代码时,出现了一个关于metic_logger的BUG:
Traceback (most recent call last):
File "", line 199, in <module>
for _ in metric_logger.log_every(range(len(data_loader_train)), print_freq, header):
File "/Deformable_DETR/util/misc.py", line 272, in log_every
meters=str(self),
File "/Deformable_DETR/util/misc.py", line 222, in __str__
"{}: {}".format(name, str(meter))
File "/Deformable_DETR/util/misc.py", line 121, in __str__
median=self.median,
File "/Deformable_DETR/util/misc.py", line 96, in median
return d.median().item()
RuntimeError: median cannot be called with empty tensor
Process finished with exit code 1
二、原因及解决方法
解决方法:
如果在metic_logger.log_every() 函数前面调用了metric_logger.add_meter()函数,那么就要在metic_logger.log_every() 函数后面用metric_logger.update()及时更新add_meter()中声明的超参数,每一个超参数都要更新。
或者直接不用metric_logger.add_meter()。
伪代码示例说明:
metric_logger = utils.MetricLogger(delimiter=" ")
metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))
metric_logger.add_meter('class_error', utils.SmoothedValue(window_size=1, fmt='{value:.2f}'))
metric_logger.add_meter('grad_norm', utils.SmoothedValue(window_size=1, fmt='{value:.2f}'))
for _ in metric_logger.log_every(range(len(data_loader)), print_freq, header):
metric_logger.update(class_error=loss_dict_reduced['class_error'])
metric_logger.update(lr=optimizer.param_groups[0]["lr"])
metric_logger.update(grad_norm=grad_total_norm)