You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It is my understanding that an EquiformerV2 network should be equivariant, that is to say if one rotates the atomic positions of the input (x), the node features (y) should transform according to their irreps. If the rotation operator is R, and the equivariant network M, the following should hold: M(R(x)) = R(M(x))
I tested this for the water molecule and a minimal EquiformerV2Backbone model:
#!/usr/bin/env pythonimporttorchimportase.buildfrome3nnimporto3importnumpyfromfairchem.core.datasetsimportdata_list_collaterfromfairchem.core.models.equiformer_v2.equiformer_v2importEquiformerV2Backbonefromfairchem.core.preprocessingimportAtomsToGraphsdeftest_equivariance():
lmax=2# Define modeltorch.manual_seed(100) # fix network initializationbackbone=EquiformerV2Backbone(
use_pbc=False,
num_layers=2,
sphere_channels=2,
attn_hidden_channels=2,
num_sphere_samples=64,
edge_channels=2,
lmax_list= [lmax]
)
# Disable drop out in evaluation modebackbone.eval()
assertnotbackbone.training# convert ASE atoms object to grapha2g=AtomsToGraphs(r_pbc=False)
defmodel(atoms):
inp=data_list_collater([a2g.convert(atoms)])
out=backbone(inp)
node_features=out["node_embedding"].embeddingnode_features_aggr=torch.sum(node_features, dim=[0,2])
returnnode_features_aggr# angles of rotation in 3Dalpha, beta, gamma=torch.tensor(0.1), torch.tensor(0.5), torch.tensor(0.8)
# rotation matrixrotation=o3.angles_to_matrix(alpha, beta, gamma)
# Wigner D matrices for rotating node featuresirreps_strings= []
forlinrange(0, lmax+1):
irreps_strings.append(f"1x{l}e")
irreps=o3.Irreps("+".join(irreps_strings))
wigner_D=irreps.D_from_angles(alpha, beta, gamma)
# Water molecule in very large unit cellatoms=ase.build.molecule('H2O')
atoms.translate(numpy.array([10.0, 10.0, 10.0]))
atoms.set_cell(3*[1000.0])
atoms.pbc=True#print("Atoms before rotation")#print(atoms)#print(atoms.get_positions())# Evaluate model on atom in the original orientation, y = M(x)prediction_Mx=model(atoms)
# Rotate atom coordinates x' = R.x and lattice vectors of unit cell.atoms.positions=numpy.einsum('ij,aj->ai', rotation, atoms.positions)
atoms.cell=numpy.einsum('ij,ja->ia', rotation, atoms.cell)
#print("Atoms after rotation")#print(atoms)#print(atoms.get_positions())# Evaluate model on rotated atoms, y' = M(x')prediction_MRx=model(atoms)
# Rotate the output tensor.# y'' = R(y) = R(M(x)) = M(R(x)) = M(x') = y'prediction_RMx=torch.einsum('...ij,...j->...i', wigner_D, prediction_Mx)
print("M(x)")
print(prediction_Mx)
print("M(R(x))")
print(prediction_MRx)
print("R(M(x))")
print(prediction_RMx)
error=torch.linalg.norm(prediction_MRx-prediction_RMx)
print(f"equivariance error |M(R(x)) - R(M(x))|= {error}")
if__name__=="__main__":
test_equivariance()
If I increase the number of layers, channels, lmax etc., the error gets much larger. Is there something wrong with my settings? How can I ensure that the network is equivariant to numerical precision?
Thank you for your time and help.
Best regards,
Alexander
The text was updated successfully, but these errors were encountered:
Hi @humeniuka, EquiformerV2 breaks exact equivariance due to (1) max-neighbor limit (2) grid discretization. For (1) you should be able to further reduce the error by setting enforce_max_neighbors_strictly=False. more details on this in #823.
Our recent preprint discuss design aspects to achieve exact equivariance and energy conservation: https://arxiv.org/abs/2502.12147
What would you like to report?
Hello,
It is my understanding that an EquiformerV2 network should be equivariant, that is to say if one rotates the atomic positions of the input (x), the node features (y) should transform according to their irreps. If the rotation operator is R, and the equivariant network M, the following should hold:
M(R(x)) = R(M(x))
I tested this for the water molecule and a minimal EquiformerV2Backbone model:
Equivariance is only approximately fulfilled,
and the error is surprisingly large
If I increase the number of layers, channels, lmax etc., the error gets much larger. Is there something wrong with my settings? How can I ensure that the network is equivariant to numerical precision?
Thank you for your time and help.
Best regards,
Alexander
The text was updated successfully, but these errors were encountered: