ResNetConfig
ModelConfigResNetConfig(num_classes: int = 1000, in_channels: int = 3, block_type: str = 'bottleneck', layers: tuple[int, ...] = (3, 4, 6, 3), stem_channels: int = 64, hidden_sizes: tuple[int, ...] = (64, 128, 256, 512), bottleneck_width_mult: int = 1, dropout: float = 0.0, zero_init_residual: bool = False)Frozen configuration dataclass for every ResNet variant.
A single ResNetConfig instance fully specifies the architecture of
any model in the ResNet family (ResNet-18/34/50/101/152, Wide ResNet,
or deeper bottleneck variants such as ResNet-200/269). The
ResNet and ResNetForImageClassification constructors
take exactly one of these objects — no extra constructor arguments
are ever needed.
Fields are immutable (frozen=True) so the same config can be
safely shared across training runs, serialised to config.json
via ModelConfig.save, and reloaded without copy-on-write
surprises. __post_init__ re-coerces layers and
hidden_sizes to tuple because JSON round-trips would
otherwise hand back list objects, breaking the
dataclasses.dataclass(frozen=True) hash contract.
Parameters
num_classesint= 1000ResNet class.in_channelsint= 33 for RGB inputs (the
original paper setting); set to 1 for grayscale or higher
for multi-spectral inputs.block_type(basic, bottleneck)= "basic""basic" selects the two-conv
_BasicBlock used in ResNet-18/34; "bottleneck"
selects the three-conv _Bottleneck used in
ResNet-50/101/152 and all wider/deeper variants.layerstuple[int, ...]= (3, 4, 6, 3)(3, 4, 6, 3) is the ResNet-50
configuration from Table 1 of He et al. (2015).stem_channelsint= 64hidden_sizestuple[int, ...]= (64, 128, 256, 512)hidden_sizes[i] * block.expansion — so the
last-stage feature map is 512 channels for BasicBlock or 2048
channels for Bottleneck.bottleneck_width_multint= 1_Bottleneck. Set to 2 for Wide ResNet-50-2 /
101-2 (Zagoruyko & Komodakis, 2016); leaves the per-stage
output width unchanged.dropoutfloat= 0.0ResNetForImageClassification.
Ignored by the backbone-only model.zero_init_residualbool= FalseTrue, initialise the final BatchNorm in every residual
branch (bn2 for BasicBlock, bn3 for Bottleneck) with
zero weights so each block starts as the identity function.
This trick, popularised by Goyal et al. ("Accurate, Large
Minibatch SGD"), can improve training stability at large batch
sizes.Attributes
model_typeClassVar[str]"resnet" — embedded in
config.json and used by directory-based from_pretrained
to dispatch to the correct registry entry.Notes
The four canonical ImageNet variants from He et al., "Deep Residual
Learning for Image Recognition", CVPR 2016 (arXiv:1512.03385,
Table 1) correspond to the following (block_type, layers)
tuples:
Always prefer the factory functions in ._pretrained (e.g.
resnet_50) over hand-rolling a config — they encode the
exact paper-cited topology and integrate with the model registry.
Examples
Construct the ResNet-50 config and inspect it:
>>> from lucid.models.vision.resnet import ResNetConfig
>>> cfg = ResNetConfig(block_type="bottleneck", layers=(3, 4, 6, 3))
>>> cfg.num_classes
1000
>>> cfg.model_type
'resnet'
Build a Wide ResNet-50-2 config (2x inner width, same output width):
>>> wide = ResNetConfig(
... block_type="bottleneck",
... layers=(3, 4, 6, 3),
... bottleneck_width_mult=2,
... )
>>> wide.bottleneck_width_mult
2
JSON round-trip (lists get coerced back to tuples):
>>> import json
>>> d = cfg.to_dict()
>>> restored = ResNetConfig.from_dict(json.loads(json.dumps(d)))
>>> isinstance(restored.layers, tuple)
TrueUsed by 3
Constructors
1__init__
→None__init__(num_classes: int = 1000, in_channels: int = 3, block_type: str = 'bottleneck', layers: tuple[int, ...] = (3, 4, 6, 3), stem_channels: int = 64, hidden_sizes: tuple[int, ...] = (64, 128, 256, 512), bottleneck_width_mult: int = 1, dropout: float = 0.0, zero_init_residual: bool = False)Initialise the module and validate the supplied config.
Parameters
configModelConfigconfig_class.Raises
TypeErrorconfig_class has not been set on the concrete subclass,
or if config is not an instance of config_class.