使用tqdm进度条时如何实时更新打印损失且不重复进度条
训练循环中tqdm进度条与实时损失打印的问题解决
问题原因
你用tqdm.write(..., end='\r')看不到输出,是因为\r会让光标回到行首,而tqdm进度条本身就是通过\r在同一行更新的,后续的进度条刷新会直接覆盖这行内容,导致损失输出被隐藏。用print则会触发换行,让tqdm重新生成新的进度条,所以出现重复的情况。
修复现有代码的方法
最简洁有效的方式是利用tqdm自带的set_description方法,把损失信息直接嵌入到进度条中,无需额外打印:
for epoch in range(start_epoch, end_epoch): print("="*70) print("EPOCH: [%d/%d]" % (epoch, end_epoch)) print("="*70) # 先初始化tqdm进度条实例 pbar = tqdm(dataloader) for i, data in enumerate(pbar, 0): # 你的计算操作 # ... # 更新进度条的描述文本,实时显示损失 pbar.set_description(f"Loss: {losses[-1]:0.5f}, MinLoss: {min_loss:0.5f}") # 其他操作 print("Loss:" , [round(i,5) for i in losses[-10:]]) print("MinLoss:", round(min_loss,5))
这样进度条会固定在一行,损失信息会实时更新在进度条前方,完全不会出现干扰或重复的问题。
其他实现方法
- 兼容print的写法
如果坚持要用print,可以添加flush=True并保留\r,但这种方式偶尔会和tqdm进度条出现交替覆盖的情况,体验不如前者:
for i, data in enumerate(tqdm(dataloader), 0): # 计算操作 # ... # 实时打印损失,强制刷新输出 print(f"\rLoss: {losses[-1]:0.5f}, MinLoss: {min_loss:0.5f}", end='', flush=True)
- 结合logging模块
如果你的项目用了logging,可以用tqdm的兼容工具重定向日志输出,避免干扰进度条:
from tqdm.contrib.logging import logging_redirect_tqdm for epoch in range(start_epoch, end_epoch): print("="*70) print("EPOCH: [%d/%d]" % (epoch, end_epoch)) print("="*70) with logging_redirect_tqdm(): pbar = tqdm(dataloader) for i, data in enumerate(pbar, 0): # 计算操作 # ... logging.info(f"Loss: {losses[-1]:0.5f}, MinLoss: {min_loss:0.5f}") # 其他操作 print("Loss:" , [round(i,5) for i in losses[-10:]]) print("MinLoss:", round(min_loss,5))
内容的提问来源于stack exchange,提问作者Aarat Satsangi
相关产品推荐
相关产品推荐

