Modules can also contain other Modules, allowing them to be nested in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self) -> None:
super().__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
Submodules assigned in this way will be registered, and will also have their parameters converted when you call :meth:to, etc.
.. note:: As per the example above, an __init__() call to the parent class must be made before assignment on the child.
:ivar training: Boolean represents whether this module is in training or evaluation mode. :vartype training: bool
# [bs x nvars x d_model x num_patch] x = torch.randn(4*7, 50, 256)cls = AttentiveClassifier(embed_dim=256, c_in=7, num_queries=1, num_heads=2, mlp_ratio=4.0, depth=1, norm_layer=nn.LayerNorm, init_std=0.02, qkv_bias=True, num_classes=1, complete_block=False, per_channel=False)cls(x).shape
torch.Size([28, 1, 256])
torch.Size([4, 1])
# [bs x nvars x d_model x num_patch] cls_ = AttentiveClassifier(embed_dim=768, num_queries=1, num_heads=8, mlp_ratio=4.0, depth=1, norm_layer=nn.LayerNorm, init_std=0.02, qkv_bias=True, num_classes=5, complete_block=False)sum(p.numel() for p in cls_.parameters())
2390021
# [bs x nvars x d_model x num_patch] x = torch.randn(4, 7*10, 256)cls_ = AttentiveClassifierNoMelt(embed_dim=256, num_queries=1, num_heads=2, mlp_ratio=4.0, depth=1, norm_layer=nn.LayerNorm, init_std=0.02, qkv_bias=True, num_classes=1, complete_block=True)cls_(x).shape