Fictional practice · Reference code executed locally · The supplied local reference was executed against the included fixture. This does not verify a production service or the learner’s own environment.
Represent data as tensors with explicit shape
Represent data as tensors with explicit shape
PyTorch tensors carry shape, dtype and device. The synthetic example uses a 40×2 float feature matrix and a 40×1 target column. Shape compatibility is part of correctness: broadcasting a target vector against a prediction matrix can compute an unintended loss. Keep targets aligned with rows and choose dtype deliberately. PyTorch is the primary framework because the course can show tensors, autograd, model definitions and training loops directly in a small local CPU example. No GPU, cloud account, downloaded pretrained weights or paid API is required.
Follow a concrete example
Write shape annotations at every boundary: input[N,2], hidden[N,4], logits[N,1] and targets[N,1]. A target shaped[N] can broadcast unexpectedly against[N,1]. Trace the dimensions on a two-row batch before training. Keep device and dtype explicit, and do not describe a CPU teaching run as a GPU benchmark.
Further reading: PyTorch basics, NumPy 2.2 reference. The case and exercises are authored for DataCareerHub.
Your task
Inspect tensor shapes and partition the first 24 rows for training, next eight for validation and last eight for final testing.
Use learner_worksheet.txt and the provided source/code files. Save your own artifact and compare the separate solution after attempting the task.
Worked solution
Features are float32 with two columns; targets are float32 column vectors. The training loop uses only the first 24 rows. Eight final rows remain unscored in this reference; their existence is not permission to tune on them.
Implement forward, backward and optimizer steps
Implement forward, backward and optimizer steps
The reference defines Linear(2,4), Tanh and Linear(4,1). BCEWithLogitsLoss expects logits, so do not insert a sigmoid before that loss. Each training iteration clears gradients, computes the forward loss, calls backward and steps SGD. Omitting zero_grad accumulates gradients across iterations unless deliberately intended. Keep the optimizer attached to the actual model parameters. The example pins PyTorch 2.6.0 and uses one CPU thread with fixed seeds for a reproducible teaching baseline; it is not a promise of bit-identical output on every platform.
Follow a concrete example
The loop follows zero_grad→forward→loss→backward→step. The optimizer stores references to model parameters; changing the model object without updating that optimizer would break the intended relationship. BCEWithLogitsLoss consumes untransformed logits. For a displayed probability after evaluation, a sigmoid is appropriate, but it is not inserted a second time inside this loss.
Inspect the reference implementation
Language: Python 3.12. The complete downloadable file includes the named helpers and the fresh-output command-line runner. Trace the source, transformation and result against this lesson’s contract before running it locally.
def dl_torch(source,out):
import numpy as np
import torch
torch.set_num_threads(1);torch.manual_seed(7);x,y=dl_arrays();x=torch.tensor(x,dtype=torch.float32);y=torch.tensor(y[:,None],dtype=torch.float32)
model=torch.nn.Sequential(torch.nn.Linear(2,4),torch.nn.Tanh(),torch.nn.Linear(4,1));optim=torch.optim.SGD(model.parameters(),lr=.1);loss_fn=torch.nn.BCEWithLogitsLoss()
for _ in range(100):
model.train();optim.zero_grad();loss=loss_fn(model(x[:24]),y[:24]);loss.backward();optim.step()
model.eval()
with torch.no_grad():validation=float(((model(x[24:32])>=0)==(y[24:32]>=.5)).float().mean());final_loss=float(loss_fn(model(x[:24]),y[:24]))
return {'torch_version':torch.__version__,'train_rows':24,'validation_rows':8,'test_rows_reserved':8,'training_loss':final_loss,'validation_accuracy':validation,'test_scored':False,'warning':'Tiny synthetic exercise, not evidence of real-world generalisation.'}
Further reading: PyTorch basics, NumPy 2.2 reference. The case and exercises are authored for DataCareerHub.
Your task
Trace one training iteration and explain each of zero_grad, forward loss, backward and step. Run the worked script locally.
Use learner_worksheet.txt and the provided source/code files. Save your own artifact and compare the separate solution after attempting the task.
Worked solution
zero_grad clears prior accumulated gradients; backward computes current derivatives; step updates parameters. The reference reports actual training loss and validation accuracy. No model download or external call occurs.
Evaluate without changing the model
Evaluate without changing the model
model.eval() changes behaviours of layers such as dropout and batch normalization; no_grad disables gradient recording for the evaluation calculation. They serve different purposes and are often used together. The tiny network here has neither dropout nor batch normalization, but establishing the pattern matters for later models. A binary logit threshold zero corresponds to sigmoid probability 0.5. Report the small validation denominator and leave the reserved test untouched. Saving a model artifact is a separate responsibility from evaluating it.
Follow a concrete example
Freeze model parameters during validation and report the eight-row denominator. eval changes applicable layer behaviour; no_grad prevents building a derivative graph. Neither is an authorisation boundary or an instruction to refit on validation data. Preserve the final eight observations and write down what changes would require a new evaluation protocol.
Further reading: PyTorch basics, NumPy 2.2 reference. The case and exercises are authored for DataCareerHub.
Your task
Explain eval versus no_grad and calculate the validation correct-count denominator. Record what the script does not score.
Use learner_worksheet.txt and the provided source/code files. Save your own artifact and compare the separate solution after attempting the task.
Worked solution
Validation uses eight rows with frozen training parameters. The final eight rows remain unscored. eval is not an access-control setting and no_grad does not itself switch layer behaviour. A small synthetic score is a mechanics demonstration.