More control over ProgressBar formatting
🚀 Feature - Improved contrib.handlers.tqdm_logger.ProgressBar formatting and alignment
More configurable arguments/bar formatting of the available ProgressBar class. Specifically to allow for the alignment of multiple bars (train loop, test/validation loop).
The current functionality of the ProgressBar class modifies the bar format to include the current_epoch/total_epochs when max_epochs > 1. This mostly works well for the train loop. However, format/alignment issues arise when the train loop is used with a validation loop that runs at the end of each epoch (on EpochCompleted). The validation loop should only be run once. However, this causes the epoch information to be omitted, and consequently, any format options which attempt to align the bars are void (see the screenshot below; both progress bars are set to have the same formatting). The format given below may not format as intended, but I cannot test it since I cannot remove/add the epoch information.
Ideally, control would be given over the if/how the epoch information is displayed when creating the ProgressBar. Investigating the codebase, it seems that this stuff is handled internally in the _OutputHandler class. I would very much like to align the bars to start and finish in the same place as each other, purely for aesthetics.
BAR_FMT = "{desc:<15} [{n_fmt}/{total_fmt}]|{bar}| {rate_fmt}{postfix}"
In the above image, I would love control over aligning the actual bar sections of the progress bars.
@jmg049 thanks for the suggestions! Would you like to send a draft PR with implementing that?
Hey 👋, I've just created a thread for this issue on PyTorch-Ignite Discord where you can quickly talk to the community on the topic.
🤖 This comment was automatically posted by Discuss on Discord
@jmg049 thanks for the suggestions! Would you like to send a draft PR with implementing that?
Hey, sure, it might take some time though unfortunately(if only contributing was my main work). I do already have a very hacky, massively imperfect prototype work-around for it.
But if I find some time I'll give it a shot. Definitely a niche, but fun and interesting problem.
@jmg049 I tried using the same way as you did with padding the description and seems like tqdm should strip whitespaces. Here is how I could get the alignment with another character. Basically, all mid-sized chars can work.
from ignite.engine import Engine, Events
from ignite.contrib.handlers import ProgressBar
train_data = range(10)
eval_data = range(4)
max_epochs = 5
def train_step(engine, batch):
import time
time.sleep(0.1)
trainer = Engine(train_step)
def eval_step(engine, batch):
import time
time.sleep(0.1)
evaluator = Engine(eval_step)
@trainer.on(Events.EPOCH_COMPLETED(every=2))
def run_validation():
evaluator.run(eval_data)
bformat = "{desc:▫>20}[{n_fmt:0>3}/{total_fmt:0>3}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]"
ProgressBar(
persist=True, desc="Training", bar_format=bformat,
).attach(trainer)
ProgressBar(
persist=True, desc="Validation", bar_format=bformat,
).attach(evaluator)
trainer.run(train_data, max_epochs=max_epochs)
Does this look aesthetically better?
Yes it definitely looks better. No doubt about it. I'm still not a huge fan of always having the epoch info there and more specifically that it's tied to the specific Engine.
I have something working (I think) that is quite nice, unfortunately the amount of time I have to work on it is small. Basically, I've added a custom field to the tqdm bar format, epochs, which allows you to control the formatting of the epoch information.
Then I've also added a parameter to the ProgressBar class named progress_with to allow for tying of something like and Evaluator progress bar to the Trainer progress bar.
A (rough) example:
trainer_pb = ProgressBar(...)
evaluator_pb = ProgressBar(..., progress_with=trainer_pb)
Then the evaluator progress bar displays the same epoch information as the trainer.