MCPcopy Create free account
hub / github.com/TEA-Lab/TwoByTwo / VNInFeature

Class VNInFeature

src/shape_assembly/models/encoder/vn_layers.py:240–297  ·  view source on GitHub ↗

VN-Invariant layer.

Source from the content-addressed store, hash-verified

238
239
240class VNInFeature(nn.Module):
241 """VN-Invariant layer."""
242
243 def __init__(
244 self,
245 in_channels,
246 dim=4,
247 share_nonlinearity=False,
248 negative_slope=0.2,
249 use_rmat=False,
250 ):
251 super().__init__()
252
253 self.dim = dim
254 self.use_rmat = use_rmat
255 self.vn1 = VNLinearBNLeakyReLU(
256 in_channels,
257 in_channels // 2,
258 dim=dim,
259 share_nonlinearity=share_nonlinearity,
260 negative_slope=negative_slope,
261 )
262 self.vn2 = VNLinearBNLeakyReLU(
263 in_channels // 2,
264 in_channels // 4,
265 dim=dim,
266 share_nonlinearity=share_nonlinearity,
267 negative_slope=negative_slope,
268 )
269 self.vn_lin = conv1x1(
270 in_channels // 4, 2 if self.use_rmat else 3, dim=dim)
271
272 def forward(self, x):
273 """
274 Args:
275 x: point features of shape [B, C, 3, N, ...]
276 Returns:
277 rotation invariant features of the same shape
278 """
279 z = self.vn1(x)
280 z = self.vn2(z)
281 z = self.vn_lin(z) # [B, 3, 3, N] or [B, 2, 3, N]
282 if self.use_rmat:
283 z = z.flatten(1, 2).transpose(1, 2).contiguous() # [B, N, 6]
284 z = rot6d_to_matrix(z) # [B, N, 3, 3]
285 z = z.permute(0, 2, 3, 1) # [B, 3, 3, N]
286 z = z.transpose(1, 2).contiguous()
287
288 if self.dim == 4:
289 x_in = torch.einsum('bijm,bjkm->bikm', x, z)
290 elif self.dim == 3:
291 x_in = torch.einsum('bij,bjk->bik', x, z)
292 elif self.dim == 5:
293 x_in = torch.einsum('bijmn,bjkmn->bikmn', x, z)
294 else:
295 raise NotImplementedError(f'dim={self.dim} is not supported')
296
297 return x_in

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected