🎓 A1Learner
🔍
0 of 79 lessons completed

PyTorch Printing a Loss Curve

A printed loss curve turns each epoch's loss into a row of characters. Longer rows mean bigger losses, so learning shows as shrinking rows.

Scale a loss to a bar

A loss becomes a count of characters. Half of the top loss gives half of the full width.

top = 1.0
value = 0.5
bar = "#" * round(value / top * 20)
print(bar)
print(len(bar))

One row per epoch

A loop prints one bar per loss. The bars shrink as the losses fall.

losses = [0.9, 0.6, 0.3]
top = losses[0]
for value in losses:
    bar = "#" * max(1, round(value / top * 20))
    print(f"{value:.1f}  {bar}")

Keep the raw numbers too

The bar shows the shape at a glance. The printed number beside it keeps the exact value.

print(f"{0.3:.4f}")

Example

import torch
import torch.nn as nn

torch.manual_seed(0)
x = torch.linspace(0, 1, 40).reshape(-1, 1)
y = 3.0 * x - 2.0

model = nn.Linear(1, 1)
loss_fn = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.2)

losses = []
for epoch in range(12):
    optimizer.zero_grad()
    loss = loss_fn(model(x), y)
    loss.backward()
    optimizer.step()
    losses.append(loss.item())

top = losses[0]
for i, value in enumerate(losses, start=1):
    bar = "#" * max(1, round(value / top * 30))
    print(f"Epoch {i:2d}  {value:.4f}  {bar}")

Key points

  • Loss curve: the losses of a run, one point per epoch, in order
  • Use the first loss as the scale, so the longest bar is fixed
  • Use round(loss / top * width) to turn a loss into a bar length
  • A falling curve shows as bars that shrink epoch by epoch
  • Printing losses as bars shows the shape of learning in plain text

In this example, the model trains on 40 rows that follow the rule y = 3x - 2. The loop saves the loss of each of the 12 epochs. The first loss sets the scale for the bars. Each epoch then prints its loss and a bar of # characters. The bars shrink from 30 characters to 9, so the fall of the loss is easy to see.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Python Playground

Exercise

In this printing scheme, what does a bar half as long as the first bar mean?