Skip to content

velora.models.backbone

Documentation

Customization: Backbones

Architecture backbones for feature extraction.

BasicCNN

Bases: nn.Module

A CNN backbone from the DQN Nature paper: Human-level control through deep reinforcement learning [].

Only contains the Convolutional Network with a flattened output.

Useful for connecting with other architectures such as the LiquidNCPNetwork.

Source code in velora/models/backbone.py
Python
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
class BasicCNN(nn.Module):
    """
    A CNN backbone from the DQN Nature paper: [Human-level control through deep reinforcement learning [:material-arrow-right-bottom:]](https://www.nature.com/articles/nature14236).

    Only contains the Convolutional Network with a flattened output.

    Useful for connecting with other architectures such as the
    `LiquidNCPNetwork`.
    """

    def __init__(self, in_channels: int) -> None:
        """
        Parameters:
            in_channels (int): the number of channels in the input image. E.g.,

                - `3` for RGB
                - `1` for grayscale
        """
        super().__init__()
        self.in_channels = in_channels

        self.conv = nn.Sequential(
            nn.Conv2d(in_channels, 32, kernel_size=8, stride=4, padding=0),
            nn.ReLU(),
            nn.Conv2d(32, 64, kernel_size=4, stride=2, padding=0),
            nn.ReLU(),
            nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=0),
            nn.ReLU(),
            nn.Flatten(),
        )

    def out_size(self, dim: Tuple[int, int]) -> int:
        """
        Calculates the size of the convolution output using a dummy input.

        Often used as the `in_features` to linear layers.

        Parameters:
            dim (Tuple[int, int]): the `(height, width)` of a single image

        Returns:
            output_size (int): the number of feature maps.
        """
        if len(dim) != 2:
            raise ValueError(f"Invalid '{dim=}'. Should be '(height, width)'.")

        with torch.no_grad():
            x = torch.zeros(1, self.in_channels, *dim)
            return self.conv(x).size(1)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """
        Forward pass through the network.

        Parameters:
            x (torch.Tensor): a batch of images in the shape
                `(batch_size, in_channels, height, width)`.

                - `batch_size` - number of images in the batch
                - `in_channels` - number of colour channels
                - `height` - height of the images
                - `width` - width of the images

        Returns:
            y_pred (torch.Tensor): the flattened predicted feature maps.
        """
        if x.dim() != 4:
            raise ValueError(
                f"Invalid '{x.shape=}'. Should be `(batch_size, in_channels, height, width)`."
            )

        return self.conv(x)

__init__(in_channels)

Parameters:

Name Type Description Default
in_channels int

the number of channels in the input image. E.g.,

  • 3 for RGB
  • 1 for grayscale
required
Source code in velora/models/backbone.py
Python
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
def __init__(self, in_channels: int) -> None:
    """
    Parameters:
        in_channels (int): the number of channels in the input image. E.g.,

            - `3` for RGB
            - `1` for grayscale
    """
    super().__init__()
    self.in_channels = in_channels

    self.conv = nn.Sequential(
        nn.Conv2d(in_channels, 32, kernel_size=8, stride=4, padding=0),
        nn.ReLU(),
        nn.Conv2d(32, 64, kernel_size=4, stride=2, padding=0),
        nn.ReLU(),
        nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=0),
        nn.ReLU(),
        nn.Flatten(),
    )

forward(x)

Forward pass through the network.

Parameters:

Name Type Description Default
x torch.Tensor

a batch of images in the shape (batch_size, in_channels, height, width).

  • batch_size - number of images in the batch
  • in_channels - number of colour channels
  • height - height of the images
  • width - width of the images
required

Returns:

Name Type Description
y_pred torch.Tensor

the flattened predicted feature maps.

Source code in velora/models/backbone.py
Python
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
def forward(self, x: torch.Tensor) -> torch.Tensor:
    """
    Forward pass through the network.

    Parameters:
        x (torch.Tensor): a batch of images in the shape
            `(batch_size, in_channels, height, width)`.

            - `batch_size` - number of images in the batch
            - `in_channels` - number of colour channels
            - `height` - height of the images
            - `width` - width of the images

    Returns:
        y_pred (torch.Tensor): the flattened predicted feature maps.
    """
    if x.dim() != 4:
        raise ValueError(
            f"Invalid '{x.shape=}'. Should be `(batch_size, in_channels, height, width)`."
        )

    return self.conv(x)

out_size(dim)

Calculates the size of the convolution output using a dummy input.

Often used as the in_features to linear layers.

Parameters:

Name Type Description Default
dim Tuple[int, int]

the (height, width) of a single image

required

Returns:

Name Type Description
output_size int

the number of feature maps.

Source code in velora/models/backbone.py
Python
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
def out_size(self, dim: Tuple[int, int]) -> int:
    """
    Calculates the size of the convolution output using a dummy input.

    Often used as the `in_features` to linear layers.

    Parameters:
        dim (Tuple[int, int]): the `(height, width)` of a single image

    Returns:
        output_size (int): the number of feature maps.
    """
    if len(dim) != 2:
        raise ValueError(f"Invalid '{dim=}'. Should be '(height, width)'.")

    with torch.no_grad():
        x = torch.zeros(1, self.in_channels, *dim)
        return self.conv(x).size(1)

MLP

Bases: nn.Module

A dynamic multi-layer perceptron architecture for feature extraction.

Warning

The network output (y_pred) is not passed through an activation function.

This must be applied manually (if required).

Source code in velora/models/backbone.py
Python
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
class MLP(nn.Module):
    """
    A dynamic multi-layer perceptron architecture for feature extraction.

    !!! warning

        The network output (`y_pred`) is not passed through an activation function.

        This must be applied manually (if required).
    """

    def __init__(
        self,
        in_features: int,
        n_hidden: List[int] | int,
        out_features: int,
        *,
        activation: ActivationTypeLiteral = "relu",
        dropout_p: float = 0.0,
    ) -> None:
        """
        Parameters:
            in_features (int): the number of input features
            n_hidden (List[int] | int): a `list` of hidden node sizes or
                a `single` hidden node size. Dynamically creates `nn.Linear`
                layers based on sizes
            out_features (int): the number of output features
            activation (str, optional): the type of activation function used
                between layers
            dropout_p (float, optional): the dropout probability rate used between
                layers
        """
        super().__init__()

        self.dropout_p = dropout_p
        n_hidden = [n_hidden] if isinstance(n_hidden, int) else n_hidden

        input = nn.Linear(in_features, n_hidden[0])
        h_layers = self._set_hidden_layers(n_hidden, activation)
        output = nn.Linear(n_hidden[-1], out_features)

        self.fc = nn.Sequential(
            input,
            ActivationEnum.get(activation),
            *h_layers,
            output,
        )

    def _set_hidden_layers(self, n_hidden: List[int], activation: str) -> nn.ModuleList:
        """
        Helper method. Dynamically creates the hidden layers with
        activation functions and dropout layers.

        Parameters:
            n_hidden (List[int]): a list of hidden node sizes
            activation (str): the name of the activation function

        Returns:
            mlp (nn.ModuleList): a list of `nn.Linear` layers.
        """
        h_layers = nn.ModuleList()

        for i in range(len(n_hidden) - 1):
            layers = [
                nn.Linear(n_hidden[i], n_hidden[i + 1]),
                ActivationEnum.get(activation),
            ]

            if self.dropout_p > 0.0:
                layers.append(nn.Dropout(self.dropout_p))

            h_layers.extend(layers)

        return h_layers

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """
        Performs a forward pass through the network.

        Parameters:
            x (torch.Tensor): the input tensor

        Returns:
            y_pred (torch.Tensor): network predictions.
        """
        return self.fc(x)

__init__(in_features, n_hidden, out_features, *, activation='relu', dropout_p=0.0)

Parameters:

Name Type Description Default
in_features int

the number of input features

required
n_hidden List[int] | int

a list of hidden node sizes or a single hidden node size. Dynamically creates nn.Linear layers based on sizes

required
out_features int

the number of output features

required
activation str

the type of activation function used between layers

'relu'
dropout_p float

the dropout probability rate used between layers

0.0
Source code in velora/models/backbone.py
Python
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def __init__(
    self,
    in_features: int,
    n_hidden: List[int] | int,
    out_features: int,
    *,
    activation: ActivationTypeLiteral = "relu",
    dropout_p: float = 0.0,
) -> None:
    """
    Parameters:
        in_features (int): the number of input features
        n_hidden (List[int] | int): a `list` of hidden node sizes or
            a `single` hidden node size. Dynamically creates `nn.Linear`
            layers based on sizes
        out_features (int): the number of output features
        activation (str, optional): the type of activation function used
            between layers
        dropout_p (float, optional): the dropout probability rate used between
            layers
    """
    super().__init__()

    self.dropout_p = dropout_p
    n_hidden = [n_hidden] if isinstance(n_hidden, int) else n_hidden

    input = nn.Linear(in_features, n_hidden[0])
    h_layers = self._set_hidden_layers(n_hidden, activation)
    output = nn.Linear(n_hidden[-1], out_features)

    self.fc = nn.Sequential(
        input,
        ActivationEnum.get(activation),
        *h_layers,
        output,
    )

forward(x)

Performs a forward pass through the network.

Parameters:

Name Type Description Default
x torch.Tensor

the input tensor

required

Returns:

Name Type Description
y_pred torch.Tensor

network predictions.

Source code in velora/models/backbone.py
Python
84
85
86
87
88
89
90
91
92
93
94
def forward(self, x: torch.Tensor) -> torch.Tensor:
    """
    Performs a forward pass through the network.

    Parameters:
        x (torch.Tensor): the input tensor

    Returns:
        y_pred (torch.Tensor): network predictions.
    """
    return self.fc(x)