{"record":{"id":"caa58e0b00067ad9","repo":"rohitg00/ai-engineering-from-scratch","slug":"no-trainable-parameters-did-you-freeze-the-head-a","errorCode":null,"errorMessage":"No trainable parameters. Did you freeze the head as well?","messagePattern":"No trainable parameters\\. Did you freeze the head as well\\?","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"phases/19-capstone-projects/38-classifier-finetuning/code/main.py","lineNumber":396,"sourceCode":"\n@dataclass\nclass TrainReport:\n    losses: List[float]\n    final_loss: float\n    trainable: int\n\n\ndef train_classifier(\n    model: Classifier,\n    train_loader: DataLoader,\n    epochs: int,\n    lr: float,\n    seed: int,\n) -> TrainReport:\n    torch.manual_seed(seed)\n    params = [p for p in model.parameters() if p.requires_grad]\n    if not params:\n        raise ValueError(\"No trainable parameters. Did you freeze the head as well?\")\n    opt = torch.optim.Adam(params, lr=lr)\n    losses: List[float] = []\n    model.train()\n    for _ in range(epochs):\n        epoch_loss = 0.0\n        n_batches = 0\n        for ids, mask, y in train_loader:\n            logits = model(ids, mask)\n            loss = F.cross_entropy(logits, y)\n            opt.zero_grad()\n            loss.backward()\n            opt.step()\n            epoch_loss += float(loss.item())\n            n_batches += 1\n        losses.append(epoch_loss / max(n_batches, 1))\n    return TrainReport(losses=losses, final_loss=losses[-1], trainable=trainable_params(model))\n\n","sourceCodeStart":378,"sourceCodeEnd":414,"githubUrl":"https://github.com/rohitg00/ai-engineering-from-scratch/blob/39ea8a1c6d0b61f071226eff7ede4d4105fed820/phases/19-capstone-projects/38-classifier-finetuning/code/main.py#L378-L414","documentation":"train_classifier is a sentinel guard: it filters model.parameters() for requires_grad and finds none, meaning every parameter including the classification head was frozen, so gradient descent has nothing to update. The message itself suggests the likely cause (freezing the head along with the backbone).","triggerScenarios":"Thrown at phases/19-capstone-projects/38-classifier-finetuning/code/main.py:396 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Re-enable gradients on the head parameters with requires_grad_(True) before training","Freeze only the backbone, not the final linear layer","When using BN/dropout freezing helpers, exclude modules with trainable affine parameters"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"39ea8a1c6d0b61f071226eff7ede4d4105fed820","analyzedAt":"2026-08-26T03:13:46.626Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}