1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【dlprog】機械学習でlossと一緒に進捗バーを表示するPythonライブラリの紹介

Last updated at Posted at 2023-12-13

機械学習・深層学習モデルの実装で、学習時にlossと一緒に進捗バーを表示するライブラリを作りました。

dlprog

ループ中の進捗バーを表示するライブラリです。ループごとに出力される値を集計し、その平均値を共に表示します。深層学習モデルの学習時に役立ちます。進捗バーと一緒にlossなどをリアルタイムに表示できます。

demo_dl.gif

導入

pip install dlprog

初めにProgressオブジェクトを生成しておきます。

from dlprog import Progress
prog = Progress()

基本的な使い方

ループの初めにstart()メソッドを呼び出し、ループ数n_iterを指定します。ループ内ではupdate()メソッドを呼び出し、値を渡します。

import random
import time

n_iter = 30

prog.start(n_iter=n_iter)
for _ in range(n_iter):
    time.sleep(0.05)
    value = random.random()
    prog.update(value)

demo_basic.gif

2重ループで使用することもできます。その際はn_epochsを指定すると良いです。また、値のラベルlabelを指定することもできます。

n_iter = 30
n_epochs = 3

prog.start(n_iter=n_iter, n_epochs=n_epochs, label="value")
for _ in range(n_epochs):
    for _ in range(n_iter):
        time.sleep(0.05)
        value = random.random()
        prog.update(value)

demo_basic_option.gif

深層学習での使用例

深層学習モデルの実装で使ってみましょう。PyTorchを使った例です。

n_epochs = 3
n_iter = len(train_loader)

prog.start(n_epochs=n_epochs, n_iter=n_iter, label="loss")
for _ in range(n_epochs):
    for x, label in train_loader:
        optimizer.zero_grad()
        y = model(x)
        loss = loss_fn(y, label)
        loss.backward()
        optimizer.step()
        prog.update(loss.item())

demo_dl.gif

オプション

より細かい使い方の説明です。

width

バーの幅を指定する引数です。デフォルトは40です。

n_iter = 10
prog.start(n_iter=n_iter, width=10)
for _ in range(n_iter):
    time.sleep(0.1)
    value = random.random()
    prog.update(value)
1: ########## 100% [00:00:01.05] 0.58703

leave_freq

ログを残す頻度を指定する引数です。デフォルトは1なので全てのログを残します。

n_epochs = 3
n_iter = 10
prog.start(n_epochs=n_epochs, n_iter=n_iter, leave_freq=4)
for _ in range(n_epochs):
    for _ in range(n_iter):
        time.sleep(0.1)
        value = random.random()
        prog.update(value)
 4/12: ######################################## 100% [00:00:01.06] 0.34203 
 8/12: ######################################## 100% [00:00:01.05] 0.47886 
12/12: ######################################## 100% [00:00:01.05] 0.40241 

unit

エポックの単位を指定する引数です。複数のエポックをまとめられます。

n_epochs = 3
n_iter = 10
prog.start(n_epochs=n_epochs, n_iter=n_iter, leave_freq=4)
for _ in range(n_epochs):
    for _ in range(n_iter):
        time.sleep(0.1)
        value = random.random()
        prog.update(value)
  1-4/12: ######################################## 100% [00:00:04.21] 0.49179 
  5-8/12: ######################################## 100% [00:00:04.20] 0.51518 
 9-12/12: ######################################## 100% [00:00:04.18] 0.54546 

n_values

管理する値の数を指定する引数です。デフォルトは1です。複数の値を指定した場合、update()には値のリストを渡します。

n_iter = 10
prog.start(n_iter=n_iter, n_values=2)
for _ in range(n_iter):
    time.sleep(0.1)
    value1 = random.random()
    value2 = random.random() * 10
    prog.update([value1, value2])
1: ######################################## 100% [00:00:01.05] 0.47956, 4.96049 

n_valuesの代わりにlabelを複数指定することもできます。

n_iter = 10
prog.start(n_iter=n_iter, label=['value1', 'value2'], width=20)
for _ in range(n_iter):
    time.sleep(0.1)
    value1 = random.random()
    value2 = random.random() * 10
    prog.update([value1, value2])
1: #################### 100% [00:00:01.04] value1: 0.65758, value2: 4.09566 

note

バーに表示するメモなどの文字列を指定するする引数です。

n_iter = 10
prog.start(n_iter=n_iter, note='This is a note')
for _ in range(n_iter):
    time.sleep(0.1)
    value = random.random()
    prog.update(value)
1: ######################################## 100% [00:00:01.05] 0.58703, This is a note 

memo()

バーに表示するメモなどの文字列を指定するメソッドです。noteと違い、ループ中に変更できます。
defer=Trueとすると、イテレーションの最後に呼び出すことができるようになります。

n_epochs = 3
prog.start(
    n_epochs=n_epochs,
    n_iter=len(trainloader),
    label='train_loss',
    defer=True,
    width=20,
)
for _ in range(n_epochs):
    for x, label in train_loader:
        optimizer.zero_grad()
        y = model(x)
        loss = loss_fn(y, label)
        loss.backward()
        optimizer.step()
        prog.update(loss.item())
    test_loss = eval_model(model)
    prog.memo(f'test_loss: {test_loss:.5f}')
1/3: #################### 100% [00:00:02.83] train_loss: 0.34094, test_loss: 0.18194 
2/3: #################### 100% [00:00:02.70] train_loss: 0.15433, test_loss: 0.12987 
3/3: #################### 100% [00:00:02.79] train_loss: 0.10651, test_loss: 0.09783 

この進捗バーは、n_iter回目のupdate()呼び出されたタイミングで次のエポックに進むため、イテレーションの最後(のupdate()の後)にmemo()を呼び出すとその文字列は次のエポックのバーに表示されます。defer=Trueとすることで、エポックが進むタイミングがmemo()の呼び出し時に変更されるため、その文字列表示されてからエポックが進みます。

オワリ

おわりです。その他細かい使い方はAPI referenceを参照してください。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?