04 Β· Inspecting Models π
A model isn't a black box. Learn to look inside it β its parameters, its state, its mode, its device β and Modules 04β06 will feel effortless.
1. The 'Why'
Once you've built a model, you need to interact with it in ways that go beyond calling forward. You'll hand its parameters to an optimizer so they can be trained. You'll move the whole thing onto a GPU so it runs fast. You'll flip it between training and evaluation mode so layers like Dropout behave correctly. And eventually you'll save it to disk and load it back. Every one of these tasks depends on being able to inspect and control the model's internals β and nn.Module exposes a small, consistent set of tools for exactly that. This sub-module is short but it's the connective tissue that makes the rest of the course click.
Think of it as learning the dashboard of the car you built. .parameters() is the list of everything that can be trained β precisely what the optimizer in Module 05 needs. The state_dict is a plain dictionary of all the model's learned values β precisely what you save and reload in Module 06. .to(device) moves the entire model in one line, closing the loop with device placement from Module 01. And .train() / .eval() toggles the training-only behaviors you met in sub-module 02. Master this dashboard and you'll move confidently into training, saving, and deploying real models.
2. Core Concepts
.parameters() and .named_parameters(). Iterate over every trainable tensor in the model. You pass model.parameters() straight to an optimizer. The named_ variant also gives you each parameter's name, handy for inspection and debugging.
state_dict. An ordered dictionary mapping every parameter and buffer name to its tensor. It is the model's learned knowledge, and it's what you save and load (Module 06). Note: state_dict holds values, not the architecture β you still need the class definition to rebuild the model.
.to(device) on a model. Moves all parameters and buffers to a device in place (unlike tensors, where .to() returns a copy). One call migrates the whole model to CPU, CUDA, or MPS.
.train() vs. .eval(). Flips a mode flag that layers like Dropout and BatchNorm read. .train() enables training behavior; .eval() switches to inference behavior. This is separate from torch.no_grad() (Module 02) β real evaluation uses both.
3. Code in Action
Inspecting parameters
import torch.nn as nn
model = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 3))
# What the optimizer will train:
for name, p in model.named_parameters():
print(name, tuple(p.shape), "trainable:", p.requires_grad)
# 0.weight (8, 4) ... / 0.bias (8,) ... / 2.weight (3, 8) ... / 2.bias (3,) ...
total = sum(p.numel() for p in model.parameters()) # count every value
print("Total parameters:", total)
The state_dict
import torch.nn as nn
model = nn.Linear(4, 2)
sd = model.state_dict() # an OrderedDict of the model's learned tensors
print(sd.keys()) # odict_keys(['weight', 'bias'])
print(sd['weight'].shape) # torch.Size([2, 4])
# This dict is exactly what you'll torch.save / load in Module 06.
Moving to a device and switching modes
import torch
import torch.nn as nn
device = "cuda" if torch.cuda.is_available() else "cpu"
model = nn.Sequential(nn.Linear(4, 8), nn.Dropout(0.5), nn.Linear(8, 3))
model.to(device) # moves ALL parameters in place (no reassignment needed)
print(next(model.parameters()).device) # reflects the target device
model.train() # training mode: Dropout is active
model.eval() # evaluation mode: Dropout is a pass-through
# Canonical evaluation combines eval() with no_grad():
model.eval()
with torch.no_grad():
preds = model(torch.randn(5, 4).to(device)) # fast, deterministic inference
4. Common Pitfalls
Pitfall 1 β Reassigning the result of model.to(device). For a model, .to() moves parameters in place, so model.to(device) alone is enough. (Contrast with a tensor, where you must write x = x.to(device).) Writing model = model.to(device) is harmless but reflects the wrong mental model β and forgetting to move the data to the same device is the real, common error.
Pitfall 2 β Assuming state_dict saves the architecture. It only stores the values (weights and buffers). To reload, you must first re-create the model from its class, then load the state_dict into it. Saving the whole object instead is fragile β more in Module 06.
Pitfall 3 β Forgetting to switch modes. Training with the model in eval() mode disables Dropout/BatchNorm updates; evaluating in train() mode gives noisy, non-reproducible metrics. Make model.train() and model.eval() explicit steps in your loops.
5. Further Reading & Watch List
- π Deep Learning with PyTorch, Ch. 6β8 β parameters, devices, and training setup
- π Learn PyTorch β Model parameters and device-agnostic code
- π οΈ
nn.Moduleβparameters,state_dict,to,train/evalΒ· What is astate_dict?
β¬ οΈ Prev: 03 Β· Building a Network Β· π Module complete! Back to the module index or on to Module 04 β Data Handling.