def forward(self, features, num_voxels, coors): # features: [concated_num_points, num_voxel_size, 3(4)] # num_voxels: [concated_num_points] # t = time.time() # torch.cuda.synchronize() points_mean = features[:, :, :3].sum(dim=1, keepdim=True) / num_voxels.type_as( features ).view(-1, 1, 1) features_relative = features[:, :, :3] - points_mean if self._with_distance: points_dist = torch.norm(features[:, :, :3], 2, 2, keepdim=True) features = torch.cat([features, features_relative, points_dist], dim=-1) else: features = torch.cat([features, features_relative], dim=-1) voxel_count = features.shape[1] mask = get_paddings_indicator(num_voxels, voxel_count, axis=0) mask = torch.unsqueeze(mask, -1).type_as(features) # mask = features.max(dim=2, keepdim=True)[0] != 0 # torch.cuda.synchronize() # print("vfe prep forward time", time.time() - t) x = self.vfe1(features) x *= mask x = self.vfe2(x) x *= mask x = self.linear(x) x = self.norm(x.permute(0, 2, 1).contiguous()).permute(0, 2, 1).contiguous() x = F.relu(x) x *= mask # x: [concated_num_points, num_voxel_size, 128] voxelwise = torch.max(x, dim=1)[0] return voxelwise
def forward(self, features, num_voxels, coors=None): # features: [concated_num_points, num_voxel_size, 3(4)] # num_voxels: [concated_num_points] points_mean = features[:, :, :3].sum(dim=1, keepdim=True) / num_voxels.type_as( features ).view(-1, 1, 1) features_relative = features[:, :, :3] - points_mean if self._with_distance: points_dist = torch.norm(features[:, :, :3], 2, 2, keepdim=True) features = torch.cat([features, features_relative, points_dist], dim=-1) else: features = torch.cat([features, features_relative], dim=-1) voxel_count = features.shape[1] mask = get_paddings_indicator(num_voxels, voxel_count, axis=0) mask = torch.unsqueeze(mask, -1).type_as(features) for vfe in self.vfe_layers: features = vfe(features) features *= mask features = self.linear(features) features = ( self.norm(features.permute(0, 2, 1).contiguous()) .permute(0, 2, 1) .contiguous() ) features = F.relu(features) features *= mask # x: [concated_num_points, num_voxel_size, 128] voxelwise = torch.max(features, dim=1)[0] return voxelwise
def get_pillar_feat(self, features, num_voxels, coors, with_unnormalized_xyz=False): device = features.device dtype = features.dtype # Find distance of x, y, and z from cluster center points_mean = features[:, :, :3].sum( dim=1, keepdim=True) / num_voxels.type_as(features).view(-1, 1, 1) f_cluster = features[:, :, :3] - points_mean if self.normalize_center_features: f_cluster[:, :, 0] = 2 * f_cluster[:, :, 0] / self.vx f_cluster[:, :, 1] = 2 * f_cluster[:, :, 1] / self.vy # Find distance of x, y, and z from pillar center # f_center = features[:, :, :2] f_center = torch.zeros_like(features[:, :, :2]) f_center[:, :, 0] = features[:, :, 0] - ( coors[:, 3].to(dtype).unsqueeze(1) * self.vx + self.x_offset) f_center[:, :, 1] = features[:, :, 1] - ( coors[:, 2].to(dtype).unsqueeze(1) * self.vy + self.y_offset) if self.normalize_center_features: f_center[:, :, 0] = 2 * f_center[:, :, 0] / self.vx f_center[:, :, 1] = 2 * f_center[:, :, 1] / self.vy # remove unnormalized dimensions features_additional = [] if self._with_elevation: r = torch.norm(features[:, :, :2], 2, 2, keepdim=True) phi = torch.atan2(r, features[:, :, 2].view_as(r)) features_additional.append(phi) if with_unnormalized_xyz: features = features[:, :, 3:] # Combine together feature decorations features_ls = [features, f_cluster, f_center] if self._with_distance: points_dist = torch.norm(features[:, :, :3], 2, 2, keepdim=True) features_additional.append(points_dist) features = torch.cat(features_ls + features_additional, dim=-1) # The feature decorations were calculated without regard to whether pillar was empty. Need to ensure that # empty pillars remain set to zeros. voxel_count = features.shape[1] mask = get_paddings_indicator(num_voxels, voxel_count, axis=0) mask = torch.unsqueeze(mask, -1).type_as(features) features *= mask return features
def forward(self, features, num_voxels, coors): if not self.export_onnx: device = features.device dtype = features.dtype # Find distance of x, y, and z from cluster center # features = features[:, :, :self.num_input] points_mean = features[:, :, :3].sum( dim=1, keepdim=True) / num_voxels.type_as(features).view( -1, 1, 1) f_cluster = features[:, :, :3] - points_mean # Find distance of x, y, and z from pillar center # f_center = features[:, :, :2] f_center = torch.zeros_like(features[:, :, :2]) f_center[:, :, 0] = features[:, :, 0] - ( coors[:, 3].to(dtype).unsqueeze(1) * self.vx + self.x_offset) f_center[:, :, 1] = features[:, :, 1] - ( coors[:, 2].to(dtype).unsqueeze(1) * self.vy + self.y_offset) # Combine together feature decorations features_ls = [features, f_cluster, f_center] if self._with_distance: points_dist = torch.norm(features[:, :, :3], 2, 2, keepdim=True) features_ls.append(points_dist) features = torch.cat(features_ls, dim=-1) # The feature decorations were calculated without regard to whether pillar was empty. Need to ensure that # empty pillars remain set to zeros. voxel_count = features.shape[1] mask = get_paddings_indicator(num_voxels, voxel_count, axis=0) mask = torch.unsqueeze(mask, -1).type_as(features) features *= mask self.features = features # Forward pass through PFNLayers for pfn in self.pfn_layers: features = pfn(features) return features.squeeze()