MolecularDiffusion.modules.layers.vn.vn_layers¶
Vector Neuron (VN) equivariant building blocks.
Ported from DiffSMol (source/models/shape_vn_layers.py), which in turn
derives from Deng et al., “Vector Neurons: A General Framework for SO(3)-
Equivariant Networks” (ICCV 2021).
A VN feature is a tensor of shape [B, C, 3, N, ...] – C channels of
3-vectors. Every op here commutes with a global rotation applied to the
3 axis, so a stack of them is exactly SO(3)-equivariant. That is what
makes the DiffSMol shape latent a (128, 3) equivariant embedding
rather than an invariant descriptor.
Note these blocks are NOT translation-equivariant: get_graph_feature_cross
concatenates the raw coordinate x as a channel, so the caller is
responsible for centering its input first.
Classes¶
Plain (non-VN) fully connected ResNet block, used by the decoder that |
|
BatchNorm on the per-channel vector norms, leaving directions |
|
Equivariant leaky ReLU: reflect the component of |
|
Channel-mixing linear map; acts on the channel axis only. |
|
|
|
Max-pool over the last axis, selecting by projection onto a learned |
|
Fully connected VN ResNet block. |
|
Project VN features onto a learned equivariant frame, producing an |
Functions¶
|
Build a kNN edge feature tensor from VN features. |
|
k-nearest-neighbour indices for |
|
Module Contents¶
- class MolecularDiffusion.modules.layers.vn.vn_layers.ResnetBlockFC(size_in: int, size_out: int | None = None, size_h: int | None = None)¶
Bases:
torch.nn.ModulePlain (non-VN) fully connected ResNet block, used by the decoder that consumes the invariant features produced from VN latents.
- forward(x: torch.Tensor) torch.Tensor¶
- actvn¶
- fc_0¶
- fc_1¶
- shortcut = None¶
- class MolecularDiffusion.modules.layers.vn.vn_layers.VNBatchNorm(num_features: int, dim: int)¶
Bases:
torch.nn.ModuleBatchNorm on the per-channel vector norms, leaving directions untouched (and therefore equivariance intact).
- forward(x: torch.Tensor) torch.Tensor¶
- dim¶
- class MolecularDiffusion.modules.layers.vn.vn_layers.VNLeakyReLU(in_channels: int, share_nonlinearity: bool = False, negative_slope: float = 0.2)¶
Bases:
torch.nn.ModuleEquivariant leaky ReLU: reflect the component of
xthat lies on the negative side of a learned directiond.- forward(x: torch.Tensor) torch.Tensor¶
- map_to_dir¶
- negative_slope = 0.2¶
- class MolecularDiffusion.modules.layers.vn.vn_layers.VNLinear(in_channels: int, out_channels: int)¶
Bases:
torch.nn.ModuleChannel-mixing linear map; acts on the channel axis only.
- forward(x: torch.Tensor) torch.Tensor¶
x:
[B, C_in, 3, N, ...]->[B, C_out, 3, N, ...].
- map_to_feat¶
- class MolecularDiffusion.modules.layers.vn.vn_layers.VNLinearLeakyReLU(in_channels: int, out_channels: int, dim: int = 5, share_nonlinearity: bool = False, negative_slope: float = 0.2, use_batchnorm: bool = True)¶
Bases:
torch.nn.ModuleVNLinear-> optionalVNBatchNorm-> equivariant leaky ReLU.- forward(x: torch.Tensor) torch.Tensor¶
- dim = 5¶
- map_to_dir¶
- map_to_feat¶
- negative_slope = 0.2¶
- use_batchnorm = True¶
- class MolecularDiffusion.modules.layers.vn.vn_layers.VNMaxPool(in_channels: int)¶
Bases:
torch.nn.ModuleMax-pool over the last axis, selecting by projection onto a learned direction (an argmax over a scalar, hence equivariant).
- forward(x: torch.Tensor) torch.Tensor¶
- map_to_dir¶
- class MolecularDiffusion.modules.layers.vn.vn_layers.VNResnetBlockFC(size_in: int, size_out: int | None = None, size_h: int | None = None)¶
Bases:
torch.nn.ModuleFully connected VN ResNet block.
- forward(x: torch.Tensor) torch.Tensor¶
- actvn_0¶
- actvn_1¶
- fc_0¶
- fc_1¶
- shortcut = None¶
- class MolecularDiffusion.modules.layers.vn.vn_layers.VNStdFeature(in_channels: int, dim: int = 4, normalize_frame: bool = False, share_nonlinearity: bool = False, negative_slope: float = 0.2)¶
Bases:
torch.nn.ModuleProject VN features onto a learned equivariant frame, producing an invariant descriptor plus the frame itself.
- forward(x: torch.Tensor)¶
- dim = 4¶
- normalize_frame = False¶
- vn1¶
- vn2¶
- vn_lin¶
- MolecularDiffusion.modules.layers.vn.vn_layers.get_graph_feature_cross(x: torch.Tensor, k: int = 20, idx: torch.Tensor | None = None, if_cross: bool = False) torch.Tensor¶
Build a kNN edge feature tensor from VN features.
x:[B, C, 3, N]->[B, 2C (or 3C), 3, N, k].The raw
xis concatenated as a channel, so this is rotation- but NOT translation-equivariant: center the point cloud before calling.
- MolecularDiffusion.modules.layers.vn.vn_layers.knn(x: torch.Tensor, k: int) torch.Tensor¶
k-nearest-neighbour indices for
xof shape[B, C, N].
- MolecularDiffusion.modules.layers.vn.vn_layers.mean_pool(x: torch.Tensor, dim: int = -1, keepdim: bool = False) torch.Tensor¶