{"record":{"id":"b94cd1766f06a066","repo":"huggingface/pytorch-image-models","slug":"you-have-provided-a-batch-norm-layer-as-the-root","errorCode":null,"errorMessage":"You have provided a batch norm layer as the `root module`. Please use `timm.utils.model.freeze_batch_norm_2d` or `timm.utils.model.unfreeze_batch_norm_2d` instead.","messagePattern":"You have provided a batch norm layer as the `root module`\\. Please use `timm\\.utils\\.model\\.freeze_batch_norm_2d` or `timm\\.utils\\.model\\.unfreeze_batch_norm_2d` instead\\.","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"timm/utils/model.py","lineNumber":134,"sourceCode":"    Args:\n        root_module (nn.Module, optional): Root module relative to which the `submodules` are referenced.\n        submodules (list[str]): List of modules for which the parameters will be (un)frozen. They are to be provided as\n            named modules relative to the root module (accessible via `root_module.named_modules()`). An empty list\n            means that the whole root module will be (un)frozen. Defaults to []\n        include_bn_running_stats (bool): Whether to also (un)freeze the running statistics of batch norm 2d layers.\n            Defaults to `True`.\n        mode (bool): Whether to freeze (\"freeze\") or unfreeze (\"unfreeze\"). Defaults to `\"freeze\"`.\n    \"\"\"\n    assert mode in [\"freeze\", \"unfreeze\"], '`mode` must be one of \"freeze\" or \"unfreeze\"'\n\n    if isinstance(root_module, (\n            torch.nn.modules.batchnorm.BatchNorm2d,\n            torch.nn.modules.batchnorm.SyncBatchNorm,\n            BatchNormAct2d,\n            SyncBatchNormAct,\n    )):\n        # Raise assertion here because we can't convert it in place\n        raise AssertionError(\n            \"You have provided a batch norm layer as the `root module`. Please use \"\n            \"`timm.utils.model.freeze_batch_norm_2d` or `timm.utils.model.unfreeze_batch_norm_2d` instead.\")\n\n    if isinstance(submodules, str):\n        submodules = [submodules]\n\n    named_modules = submodules\n    submodules = [root_module.get_submodule(m) for m in submodules]\n\n    if not len(submodules):\n        named_modules, submodules = list(zip(*root_module.named_children()))\n\n    for n, m in zip(named_modules, submodules):\n        # (Un)freeze parameters\n        for p in m.parameters():\n            p.requires_grad = False if mode == 'freeze' else True\n        if include_bn_running_stats:\n            # Helper to add submodule specified as a named_module","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/huggingface/pytorch-image-models/blob/9a5261e31b3b5128526eb2658333b4c0a54464ae/timm/utils/model.py#L116-L152","documentation":"freeze_/unfreeze_ in timm.utils.model refuse to operate when the root module passed is itself a BatchNorm layer (or timm's BatchNormAct2d variants), because in-place conversion is impossible and the operation would silently do the wrong thing. AssertionError is raised with a pointer to freeze_batch_norm_2d/unfreeze_batch_norm_2d which handle single BN layers.","triggerScenarios":"Calling freeze_(model.bn1) or unfreeze_(some_bn_module) where the argument is an nn.BatchNorm2d/BatchNormAct2d/SyncBatchNorm(Sync)Act instance instead of a container model.","commonSituations":"User grabbed a BN submodule from named_modules() to freeze just that layer; passing model.get_submodule('bn1') instead of the parent model.","solutions":["Use timm.utils.model.freeze_batch_norm_2d(bn_module) or unfreeze_batch_norm_2d(bn_module) for a single BN layer","Pass the parent model (or a container submodule) to freeze_/unfreeze_ with a submodules filter to select BN layers"],"exampleFix":"# before\nfrom timm.utils.model import freeze_\nfreeze_(model.bn1)  # AssertionError\n# after\nfrom timm.utils.model import freeze_batch_norm_2d\nfreeze_batch_norm_2d(model.bn1)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"import torch.nn as nn\\nfrom timm.layers.norm import BatchNormAct2d\\n\\ndef is_bn(m):\\n    return isinstance(m, (nn.modules.batchnorm._BatchNorm, BatchNormAct2d))\\n\\n# route:\\nfreeze_batch_norm_2d(m) if is_bn(m) else freeze_(m, 'bn')","tryCatchPattern":null,"preventionTips":["Branch on module type before freezing","Use freeze_(model, submodules=[...]) for bulk BN freezing"],"tags":["batchnorm","freezing","fine-tuning","timm"],"backgroundTag":"unsupported-argument-type","analyzedSha":"9a5261e31b3b5128526eb2658333b4c0a54464ae","analyzedAt":"2026-08-27T02:34:25.417Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}