Question bank — TensorBoard - Weights & Biases logging
This page is a misconception hunt. Each line below is a trap: a statement that sounds right, a piece of code that looks fine, or a "why" that people fumble. Read the left side, commit to an answer out loud, then reveal the right side. The reveals are short but they always explain the reasoning, never just "yes/no".
If any word here is unfamiliar, first read the parent note TensorBoard / W&B logging — this page assumes you already met SummaryWriter, wandb.init, scalars, histograms, event files, and the step argument.
True or false — justify
Every item: decide true or false, and say why — a bare T/F earns nothing.
TensorBoard needs your training script to be running in order to show plots.
writer.add_scalar('Loss/train', loss, step) with step left out will still plot correctly.
step is omitted it auto-increments from an internal counter, so two writers or a resumed run will collide and the curve zig-zags or overwrites.W&B stores your metrics only in the cloud, so if the network drops you lose the run.
wandb.log writes to a local wandb/ directory first and syncs; on reconnect it uploads. Offline mode (WANDB_MODE=offline) makes this explicit.TensorBoard and W&B are mutually exclusive — you pick one.
Logging every batch instead of every N batches makes the plots more accurate.
Weight histograms and loss scalars answer the same question.
wandb.config values can be edited freely mid-training to reflect changes.
config is meant to record the inputs of the run for reproducibility; treating it as a mutable scratchpad breaks the promise that config = "how this run was launched".If two runs share the same logdir subfolder, TensorBoard merges them into one clean curve.
Spot the error
Each snippet has one conceptual bug. Name it and say what it causes.
writer = SummaryWriter('runs/exp') … then the loop logs, but there is no writer.close().
close() (or flush()) the last events may never hit disk, so the tail of your curve silently disappears.Inside the batch loop: writer.add_scalar('Loss', loss.item(), epoch).
epoch for a per-batch log means every batch in an epoch writes to the same x-value, overwriting itself — use global_step = epoch * len(loader) + batch_idx.writer.add_scalar('Loss/train', loss, step) — loss is the raw tensor, not loss.item().
.item().wandb.init(project="x") is called inside the epoch loop.
init belongs once, before the loop.wandb.log({"loss": train_loss}); wandb.log({"acc": val_acc}) (two separate calls, same epoch).
log call advances W&B's internal step, so loss and acc land on different x-values and never line up. Log related metrics in one dict per step.writer.add_image('pred', img_grid) where img_grid is shape (H, W, 3).
add_image expects CHW (3, H, W) by default; passing HWC scrambles the image unless you set dataformats='HWC'.total_norm += p.grad.norm(2) then logging total_norm ** 0.5 as the gradient norm.
norm(2)**2), then take the root. Summing raw norms and rooting gives the wrong global norm.Logging wandb.Image(tensor) where tensor is un-normalized (values in [-2, 2] after standardization).
Why questions
The reveal is the reasoning, not a label.
Why are event files append-only binary logs instead of, say, a CSV you overwrite?
Why does W&B log the git commit and library versions automatically?
Why log gradient norms as a diagnostic scalar rather than trusting the loss curve?
Why does W&B exist at all if TensorBoard already plots everything?
Why is a hyperparameter sweep better tracked in W&B than by naming folders run_lr0.01_bs64?
Why should you log validation loss on epoch but training loss on global_step?
epoch is its natural x-axis; training loss updates every batch, so it needs the finer global_step to show intra-epoch dynamics.Why does smoothing in the TensorBoard SCALARS view not change your saved data?
Edge cases
The boundary and degenerate scenarios people never test until they break.
What does TensorBoard show if you log zero scalars but many histograms?
You resume training from a checkpoint at epoch 50 but restart global_step at 0. What happens?
You call wandb.log({"loss": float('nan')}). What does W&B do?
Two teammates run the same script; both call wandb.init(project="x") with no name. Do runs collide?
init mints a unique run ID, so they appear as two distinct runs even with identical (auto-generated) display names.You log an image every step for a 100k-step run. What's the failure mode?
An empty val_loader (dataset of size 0) reaches val_loss /= len(val_loader).
inf/nan and pollutes the plot. Guard degenerate loaders before logging any averaged metric.You point tensorboard --logdir=runs/ at a folder with no event files.
Recall Fast self-test (peek only after answering all four sections)
One-tool-vs-the-other ::: TensorBoard = local, decoupled event files, great histograms/graphs; W&B = cloud, sweeps, artifact versioning, collaboration.
The single most common bug on this page ::: using the wrong step variable (epoch where global_step belongs, or separate wandb.log calls) so points misalign.
The safety habit for artifacts ::: always close()/flush() the writer and log related metrics in one dict per step.