Euclidean neural networks
What is e3nn
?
e3nn
is a python library based on pytorch to create equivariant neural networks for the group \(O(3)\).
Where to start?
Guide to the
e3nn.o3.Irreps
: Irreducible representationsGuide to implement a Convolution
The simplest example to start with is Tetris Polynomial Example.
Guide to implement a Transformer
Demonstration
All the functions to manipulate rotations (rotation matrices, Euler angles, quaternions, convertions, …) can be found here Parametrization of Rotations.
The irreducible representations of \(O(3)\) (more info at Irreps) are represented by the class e3nn.o3.Irrep
.
The direct sum of multiple irrep is described by an object e3nn.o3.Irreps
.
If two tensors \(x\) and \(y\) transforms as \(D_x = 2 \times 1_o\) (two vectors) and \(D_y = 0_e + 1_e\) (a scalar and a pseudovector) respectively, where the indices \(e\) and \(o\) stand for even and odd – the representation of parity,
import torch
from e3nn import o3
irreps_x = o3.Irreps('2x1o')
irreps_y = o3.Irreps('0e + 1e')
x = irreps_x.randn(-1)
y = irreps_y.randn(-1)
irreps_x.dim, irreps_y.dim
(6, 4)
their outer product is a \(6 \times 4\) matrix of two indices \(A_{ij} = x_i y_j\).
A = torch.einsum('i,j', x, y)
A
tensor([[-0.5546, -0.1096, -0.8499, -0.1005],
[-1.3905, -0.2748, -2.1309, -0.2520],
[ 0.3184, 0.0629, 0.4880, 0.0577],
[ 0.2849, 0.0563, 0.4365, 0.0516],
[-1.1635, -0.2299, -1.7831, -0.2109],
[-2.0086, -0.3969, -3.0782, -0.3640]])
If a rotation is applied to the system, this matrix will transform with the representation \(D_x \otimes D_y\) (the tensor product representation).
Which can be represented by
R = o3.rand_matrix()
D_x = irreps_x.D_from_matrix(R)
D_y = irreps_y.D_from_matrix(R)
plt.imshow(torch.kron(D_x, D_y), cmap='bwr', vmin=-1, vmax=1);
This representation is not irreducible (is reducible). It can be decomposed into irreps by a change of basis. The outerproduct followed by the change of basis is done by the class e3nn.o3.FullTensorProduct
.
tp = o3.FullTensorProduct(irreps_x, irreps_y)
print(tp)
tp(x, y)
FullTensorProduct(2x1o x 1x0e+1x1e -> 2x0o+4x1o+2x2o | 8 paths | 0 weights)
tensor([-1.2602, -1.2072, -0.5546, -1.3905, 0.3184, 0.2849, -1.1635, -2.0086,
-0.5232, 0.1156, -0.4067, 2.0275, -0.3172, 0.4713, -0.0266, -0.7953,
-1.7187, 0.1669, 0.1183, -0.2442, 0.1461, -1.3303, -2.3257, -0.2972])
As a sanity check, we can verify that the representation of the tensor prodcut is block diagonal and of the same dimension.
D = tp.irreps_out.D_from_matrix(R)
plt.imshow(D, cmap='bwr', vmin=-1, vmax=1);
e3nn.o3.FullTensorProduct
is a special case of e3nn.o3.TensorProduct
, other ones like e3nn.o3.FullyConnectedTensorProduct
can contained weights what can be learned, very useful to create neural networks.