| 56 | |
| 57 | |
| 58 | class VNNewLeakyReLU(nn.Module): |
| 59 | def __init__(self, in_channels, share_nonlinearity=False, negative_slope=0.2): |
| 60 | super(VNNewLeakyReLU, self).__init__() |
| 61 | if share_nonlinearity == True: |
| 62 | self.map_to_dir = nn.Linear(in_channels, 1, bias=False) |
| 63 | else: |
| 64 | self.map_to_dir = nn.Linear(in_channels, in_channels, bias=False) |
| 65 | self.negative_slope = negative_slope |
| 66 | |
| 67 | def forward(self, x): |
| 68 | ''' |
| 69 | x: point features of shape [B, N_feat, 3, N_samples, ...] |
| 70 | ''' |
| 71 | d = self.map_to_dir(x.transpose(1, -1)).transpose(1, -1) |
| 72 | dotprod = (x * d) |
| 73 | mask = (dotprod >= 0).float() |
| 74 | d_norm_sq = (d * d) |
| 75 | x_out = self.negative_slope * x + (1 - self.negative_slope) * ( |
| 76 | mask * x + (1 - mask) * (x - (d / (d_norm_sq + EPS)) * d)) |
| 77 | return x_out |
| 78 | |
| 79 | |
| 80 | class VNLinearLeakyReLU(nn.Module): |