Learning Plan
The goal is to connect Deep Learning theory with step-by-step implementation. For CNN, RNN, and LSTM, the useful path is to start from simple neural networks, type the code by hand, then map each line back to the mathematical concept.
Knowing neural-network theory is not the same as being able to implement it. If I truly understand a model, I should be able to code it from scratch and explain it to a non-expert.
Practice sequence:
- Binary classification with a simple neural network
- Binary classification with a CNN
- Backpropagation and manual parameter updates
- Tensor reshaping, batching, and projection operations
Theoretical reference:
Parameters
named_parameters() lists a model’s trainable parameters by name. It is useful for inspecting layers, debugging gradients, and deciding which parameters should be optimized.
Backpropagation
In PyTorch, loss.backward() computes gradients for all tensors in the computation graph that have requires_grad=True. This is the practical bridge between the loss function and optimization.
model = nn.Sequential(
nn.Linear(16, 8),
nn.Linear(8, 4),
nn.Linear(4, 2),
)
prediction = model(sample)
criterion = CrossEntropyLoss()
loss = criterion(prediction, target)
loss.backward()
lr = 0.001
weight = model[0].weight
weight_grad = model[0].weight.grad
weight = weight - lr * weight_grad
bias = model[0].bias
bias_grad = model[0].bias.grad
bias = bias - lr * bias_gradFor a three-layer Sequential model, gradients are available at:
model[0].weight.grad
model[0].bias.grad
model[1].weight.grad
model[1].bias.grad
model[2].weight.grad
model[2].bias.gradCommon Tensor Operations
F.one_hot()
F.one_hot() converts class indices into one-hot vectors, which is useful when a label needs to be represented as a categorical vector.
import torch
import torch.nn.functional as F
one_hot_pytorch = F.one_hot(torch.tensor(1), num_classes=3)
# tensor([0, 1, 0])torch.stack
torch.stack combines a sequence of tensors along a new dimension. It is commonly used to merge multiple batch outputs into one tensor.
view()
view() reshapes a tensor without copying memory when the tensor layout allows it.
import torch
a = torch.arange(1, 17)
a_view = a.view(4, 4)
a_view_neg_1 = a.view(4, -1)
a_view_neg_2 = a.view(-1, 4)The -1 dimension asks PyTorch to infer that dimension automatically. If the tensor has 16 elements, both view(4, -1) and view(-1, 4) produce a 4 x 4 tensor.
torch.einsum()
torch.einsum("bct,bcd->bdt", x, weights) performs a Batched Matrix Multiplication:
xhas shape(batch_size, channels, time_steps), written as(b, c, t).weightshas shape(batch_size, channels, depth), written as(b, c, d).- The output has shape
(batch_size, depth, time_steps), written as(b, d, t).
The shared c dimension is summed over. Each time step in x is projected from the channel dimension into the depth dimension.
Equivalent code without einsum:
conditioning = torch.matmul(weights.transpose(1, 2), x)
# (b, d, c) @ (b, c, t) -> (b, d, t)Example:
x = torch.rand(1, 128, 512)
weights = torch.rand(1, 128, 128)
output = torch.einsum("bct,bcd->bdt", x, weights)
output.shape == (1, 128, 512)Training Utilities
tqdm
tqdm shows progress for an iterable, which is useful during model training loops.
from tqdm import tqdm
for i in tqdm(range(10000)):
...