随笔小杂记(六)——tqdm进度条显示出现多余行
前言
自己打算搭建一个自己的分类库,方便(虽然大概率以后很难出分类的相关实验了,但是还是整理一下,主要也算复习吧)以后自己做实验。然后在整理训练代码的时候,用tqdm显示进度条时,发现进度条出现了多余行~
原因
在一个迭代过程中,如果迭代未完成就被中断,随后也没有从断点继续把剩余迭代完成,就会残存一个未能完成但参与显示的进度条,从而导致多行输出。
for epoch in range(20):
print('epoch {}'.format(epoch + 1))
# training-----------------------------
model.train()
with tqdm(train_dataloader, desc=f'Epoch {epoch + 1}/{epoch}',postfix=dict,mininterval=0.3) as pbar:
for batch_x, batch_y in train_dataloader:
.....
pbar.set_postfix(loss=loss.item(), accuracy='{:.3f}'.format(accuracy))
pbar.update(1)
## 问题出现在这里
print('\nTrain Loss: {:.6f}, Acc: {:.6f}'.format(train_loss / (len(train_datasets)), train_acc / (len(train_datasets))))
# evaluation--------------------------------
model.eval()
with tqdm(val_dataloader, desc=f'Epoch {epoch + 1}/{epoch}',postfix=dict,mininterval=0.3) as pbar:
for batch_x, batch_y in val_dataloader:
...
pbar.set_postfix(loss=loss.item(), accuracy='{:.3f}'.format(accuracy))
pbar.update(1)
print('Test Loss: {:.6f}, Acc: {:.6f}'.format(eval_loss / (len(val_datasets)), eval_acc / (len(val_datasets))))
自己后面仔细观察发现,他多余的那个进度条是上个迭代中的最后一行,最后一个残存的未能参与显示的进度条会在迭代完成前出现,而我在迭代结束前有一行print('\nTrain Loss: {:.6f}, Acc: {:.6f}'.format(train_loss / (len(train_datasets)), train_acc / (len(train_datasets))))
,导致人为在进度条显示中给了一个分割,所以就出现了多宇行,结果如下:
解决方法
思路:在你有其他输出以前,让迭代明白他已经迭代完成。
方法一:将tqdm作为对象创建,然后迭代中断时,通过t.close()
销毁对象,使用close()方法手动销毁未完成的进度条。
from tqdm import tqdm
#创建tqdm对象
t = tqdm(range(0,1000000))
#迭代
for i in t:
pass
t.close()
方法二:在做模型训练和检验时,通过使用model.train(),model.eval()让tqdm完成迭代
比如,在原因中的代码,把print('\nTrain Loss: {:.6f}, Acc: {:.6f}'.format(train_loss / (len(train_datasets)), train_acc / (len(train_datasets))))
移动到model.eval()
之后,让tqdm明白完成迭代,输出残存的最后一行,然后再进行输出。如下:
for epoch in range(20):
print('epoch {}'.format(epoch + 1))
# training-----------------------------
model.train()
with tqdm(train_dataloader, desc=f'Epoch {epoch + 1}/{epoch}',postfix=dict,mininterval=0.3) as pbar:
for batch_x, batch_y in train_dataloader:
.....
pbar.set_postfix(loss=loss.item(), accuracy='{:.3f}'.format(accuracy))
pbar.update(1)
# evaluation--------------------------------
model.eval()
## 这里
print('\nTrain Loss: {:.6f}, Acc: {:.6f}'.format(train_loss / (len(train_datasets)), train_acc / (len(train_datasets))))
with tqdm(val_dataloader, desc=f'Epoch {epoch + 1}/{epoch}',postfix=dict,mininterval=0.3) as pbar:
for batch_x, batch_y in val_dataloader:
...
pbar.set_postfix(loss=loss.item(), accuracy='{:.3f}'.format(accuracy))
pbar.update(1)
print('Test Loss: {:.6f}, Acc: {:.6f}'.format(eval_loss / (len(val_datasets)), eval_acc / (len(val_datasets))))
更改后结果如下: