💈

pythonのtqdm(プログレスバー)メモ

2024/09/16に公開

プログレスバーはPCが行っている作業の進捗や残り時間・見積を可視化してくれるヤツ。

機械学習や深層学習を行う場合は、学習に長時間かかることもあることから、あとどれくらいで学習が終了するのかどれくらい学習に時間がかかったのかを可視化できると、終了時間の目安がわかる上に実際に終了した時間もわかるので非常に便利。

例えばpytorchでセグメンテーションを行う場合、以下の様に実装できる。(autocastやgradscalerなどを含めている)

progress_bar = tqdm.tqdm(train_set, desc=f'Epoch {e}')
for process, (images, masks) in enumerate(progress_bar):
    images, masks = images.to(device), masks.to(device)
    with torch.autocast(enabled=GS, device_type=device_name, dtype=torch.bfloat16):
        if GS:
            images, masks = images.half(), masks.half()
        outputs = input_model(images)
        loss = input_criterion(outputs, masks)
        train_loss.append(loss.item())
        #
        if accu_step > 1:
            loss = loss/accu_step
        scaler.scale(loss).backward()
        if ((process+1)%accu_step == 0) or (process==len(train_set)):
            scaler.step(input_optimizer)
            scaler.update()
            input_optimizer.zero_grad()
        
        progress_bar.set_description(desc="EPOCH{} train_loss: {:.4f}".format(e, np.mean(train_loss))

プログレスバーには以下のような使えそうな設定があったので少し確認したものをメモしていく。

  • desc="EPOCH{} train_loss: {:.4f}".format(e, np.mean(train_loss))とすると、プログレスバーの以下の{}部分に表示がdescで定義されたものに変わる。progress_bar.set_descriptionと併用するとlossの変動の記載などに便利。

{EPOCH1 train_loss: 0.8725}: 100%|██████████| 10/10 [00:44<00:00, 4.46s/it]

  • postfix, set_postfix("テキスト"): プログレスバーの以下の{}部分に表示がpostfixで定義されたものに変わる。

100%|██████████| 100/100 [00:10<00:00, 9.78it/s, {postfix=EPOCH 0, 99}]

  • leave: Falseにするとプログレスバーが消される。プログレスバーの表示が煩わしい時に便利そうだが、ipynb形式だと中途半端に赤枠が残るので使いどころは選ぶ。

  • mininterval, maxinterval: プログレスバーの進捗の更新頻度を変更できる。mininterval=1の時は、1秒ごとに更新。

  • colour: プログレスバーの色を変更可能。

  • initial: プログレスバーのスタート地点を指定する。

  • smoothing: 進捗速度推定のための係数を指定できる。(指数移動平均スムージング係数)
    範囲は0から1。0は平均の進捗速度、1は処理段階での速度を出力する。

その他(上手くいかなかったもの)

  • file プログレスバーのファイルを出力できるらしい?

標準エラー出力sys.stderrに指定すると、標準出力に干渉したくないエラーを出力させないようにして視認性が上がる?(試していない)

以下のような形式で、プログレスバーをテキストファイルに保存することも出来る。

with open('progress_log.txt', 'w') as f:
    for i in tqdm(range(10), file=f):
        time.sleep(0.1)

コード上では何も表示されないが、深層学習の実験管理には便利かもだが、出力が変化するごとにtxtファイルに保存するのであんまり意味ないかも。

  • position: プログレスバーの表示位置を指定する。複数のプロセスをプログレスバーで可視化したいときに便利。(手元ではバーが進むごとに改行してテキストを出力したので上手く使いこなせていないのかもしれない)

Discussion