class

Sequential

extendsModule
Sequential(args: Module | OrderedDict[str, Module] = ())
source

An ordered container of modules applied one after another in sequence.

Sequential composes a pipeline of modules so that the output of each module is fed as the sole input to the next. Given modules f1,f2,,fnf_1, f_2, \dots, f_n the computation is:

output=fn(f2(f1(x)))\text{output} = f_n(\cdots f_2(f_1(x)) \cdots)

This is the most common way to build feedforward models in Lucid. Modules are stored internally in an OrderedDict and indexed either by integer position or by string key.

Parameters

*argsModule or OrderedDict[str, Module]= ()
  • If a single OrderedDict[str, Module] is passed, the modules are registered under their dict keys.
  • If multiple positional Module arguments are passed, they are registered under string-formatted integer indices '0', '1', '2', …

Attributes

_modulesOrderedDict[str, Module | None]
Internal ordered mapping from string key to child module, inherited from Module. Direct mutation is discouraged — prefer append, insert, __setitem__, and __delitem__.

Notes

  • Slicing (seq[1:3]) returns a new Sequential containing only the sliced modules — keys are preserved from the original.
  • After a deletion the internal keys are renumbered (_renumber_modules) so that indices remain contiguous integers starting at 0.
  • Sequential does not implement custom parameter grouping; every Parameter in every child module is returned by parameters().

Examples

**CNN feature extractor followed by classifier head:**
>>> import lucid.nn as nn
>>> backbone = nn.Sequential(
...     nn.Conv2d(3, 64, kernel_size=3, padding=1),
...     nn.ReLU(),
...     nn.Conv2d(64, 128, kernel_size=3, padding=1),
...     nn.ReLU(),
...     nn.AdaptiveAvgPool2d((1, 1)),
... )
>>> head = nn.Linear(128, 10)
>>> # backbone: (N, 3, H, W) -> (N, 128, 1, 1)
**Named modules via OrderedDict:**
>>> from collections import OrderedDict
>>> model = nn.Sequential(OrderedDict([
...     ("conv1", nn.Conv2d(1, 32, 3, padding=1)),
...     ("relu1", nn.ReLU()),
...     ("conv2", nn.Conv2d(32, 64, 3, padding=1)),
...     ("pool",  nn.MaxPool2d(2)),
... ]))
>>> # Access by name:
>>> conv = model["conv1"]       # __getitem__ via integer works too: model[0]
**Dynamic construction and mutation:**
>>> layers = [nn.Linear(128, 128) for _ in range(4)]
>>> mlp = nn.Sequential(*layers)
>>> mlp.append(nn.Linear(128, 10))   # add output layer
>>> mlp.insert(0, nn.Flatten())      # prepend flatten
>>> del mlp[1]                        # remove first hidden layer

Methods (9)

dunder

__init__

None
__init__(args: Module | OrderedDict[str, Module] = ())
source

Initialise the Sequential module. See the class docstring for parameter semantics.

fn

forward

Tensor
forward(x: Tensor)
source

Apply the contained modules to the input.

Parameters

xTensor
Input tensor.

Returns

Tensor

Output tensor produced by the contained modules.

fn

append

None
append(module: Module)
source

Append a module to the end of the Sequential.

fn

extend

None
extend(modules: Iterable[Module])
source

Append each module from an iterable to the Sequential.

fn

insert

None
insert(index: int, module: Module)
source

Insert a module at the given position in the Sequential.

dunder

__getitem__

Module
__getitem__(idx: int | slice)
source

Return the child module(s) at the given index or slice.

dunder

__setitem__

None
__setitem__(idx: int, module: Module)
source

Replace the child module at the given index.

dunder

__len__

int
__len__()
source

Return the number of registered child modules.

dunder

__iter__

Iterator[Module]
__iter__()
source

Iterate over the registered child modules.