def testNeighborhoodIndicesWithUniformSampling(self): points = tf.constant([[[1, 1], [2, 2], [4, 4], [5, 5]]], dtype=tf.float32) query_points = tf.constant([[ [2, 2], [5, 5], ]], dtype=tf.float32) padding = tf.constant([[1, 0, 1, 0]]) # With max_distance=1.1, only the nearest point will be returned (and # repeated). expected_3nn = np.array([[[1, 1, 1], [3, 3, 3]]], dtype=np.int32) expected_paddings = np.array([[[0, 1, 1], [0, 1, 1]]], dtype=np.float32) with self.session(): output_3nn, paddings = self.evaluate( car_lib.NeighborhoodIndices(points, query_points, 3, padding, max_distance=1.1, sample_neighbors_uniformly=True)) self.assertAllEqual(output_3nn, expected_3nn) self.assertAllEqual(paddings, expected_paddings)
def testNeighborhoodIndicesWithUniformSamplingRaisesIfNoMaxDistance(self): points = tf.constant([[[1, 1], [2, 2], [4, 4], [5, 5]]], dtype=tf.float32) query_points = tf.constant([[ [1, 1], [4, 4], ]], dtype=tf.float32) padding = tf.constant([[1, 0, 1, 0]]) with self.assertRaisesRegex( ValueError, r'.*Uniform sampling requires specifying max_distance.*'): car_lib.NeighborhoodIndices( points, query_points, 1, padding, sample_neighbors_uniformly=True)
def testKnnIndices(self): points = tf.constant([[[1, 1], [2, 2], [4, 4], [5, 5]]], dtype=tf.float32) query_points = tf.constant([[ [1, 1], [4, 4], ]], dtype=tf.float32) # Case 1: when all points are valid. valid_num = tf.constant([4], dtype=tf.int32) expected_1nn = np.array([[[0], [2]]], dtype=np.int32) expected_2nn = np.array([[[0, 1], [2, 3]]], dtype=np.int32) expected_3nn = np.array([[[0, 1, 2], [2, 3, 1]]], dtype=np.int32) with self.session() as sess: output_1nn, _ = sess.run( car_lib.KnnIndices(points, query_points, 1, valid_num)) self.assertAllEqual(output_1nn, expected_1nn) output_2nn, _ = sess.run( car_lib.KnnIndices(points, query_points, 2, valid_num)) self.assertAllEqual(output_2nn, expected_2nn) output_3nn, _ = sess.run( car_lib.KnnIndices(points, query_points, 3, valid_num)) self.assertAllEqual(output_3nn, expected_3nn) # Case 2: not all points are valid. valid_num = tf.constant([2], dtype=tf.int32) expected_1nn = np.array([[[0], [1]]], dtype=np.int32) expected_1nn_padding = np.array([[[0], [0]]], dtype=np.float32) expected_2nn = np.array([[[0, 1], [1, 0]]], dtype=np.int32) expected_2nn_padding = np.array([[[0, 0], [0, 0]]], dtype=np.float32) expected_3nn = np.array([[[0, 1, 2], [1, 0, 2]]], dtype=np.int32) expected_3nn_padding = np.array([[[0, 0, 1], [0, 0, 1]]], dtype=np.float32) with self.session() as sess: output_1nn, output_1nn_padding = sess.run( car_lib.KnnIndices(points, query_points, 1, valid_num)) self.assertAllEqual(output_1nn, expected_1nn) self.assertAllEqual(output_1nn_padding, expected_1nn_padding) output_2nn, output_2nn_padding = sess.run( car_lib.KnnIndices(points, query_points, 2, valid_num)) self.assertAllEqual(output_2nn, expected_2nn) self.assertAllEqual(output_2nn_padding, expected_2nn_padding) output_3nn, output_3nn_padding = sess.run( car_lib.KnnIndices(points, query_points, 3, valid_num)) self.assertAllEqual(output_3nn, expected_3nn) self.assertAllEqual(output_3nn_padding, expected_3nn_padding) # Case 3: explicit padding. padding = tf.constant([[1, 0, 1, 0]]) expected_1nn = np.array([[[1], [3]]], dtype=np.int32) expected_1nn_padding = np.array([[[0], [0]]], dtype=np.float32) expected_2nn = np.array([[[1, 3], [3, 1]]], dtype=np.int32) expected_2nn_padding = np.array([[[0, 0], [0, 0]]], dtype=np.float32) expected_3nn = np.array([[[1, 3, 0], [3, 1, 2]]], dtype=np.int32) expected_3nn_padding = np.array([[[0, 0, 1], [0, 0, 1]]], dtype=np.float32) with self.session() as sess: output_1nn, output_1nn_padding = sess.run( car_lib.NeighborhoodIndices(points, query_points, 1, padding)) self.assertAllEqual(output_1nn, expected_1nn) self.assertAllEqual(output_1nn_padding, expected_1nn_padding) output_2nn, output_2nn_padding = sess.run( car_lib.NeighborhoodIndices(points, query_points, 2, padding)) self.assertAllEqual(output_2nn, expected_2nn) self.assertAllEqual(output_2nn_padding, expected_2nn_padding) output_3nn, output_3nn_padding = sess.run( car_lib.NeighborhoodIndices(points, query_points, 3, padding)) self.assertAllEqual(output_3nn, expected_3nn) self.assertAllEqual(output_3nn_padding, expected_3nn_padding)
def FProp(self, theta, input_data): """Apply projection to inputs. Args: theta: A NestedMap object containing weights' values of this layer and its children layers. input_data: A NestedMap object containing 'points', 'features', 'padding' Tensors, all of type tf.float32. 'points': Shape [N, P1, 3] 'features': Shape [N, P1, F] 'padding': Shape [N, P1] where 0 indicates real, 1 indicates padded. Returns: A NestedMap consisting of the following two NestedMaps, grouped_points: consists of the grouped points, features and padding. query_points: consists of the sampled points and padding. """ p = self.params features = input_data.features n, p1, c = py_utils.GetShape(features) points = py_utils.HasShape(input_data.points, [n, p1, 3]) padding = py_utils.HasShape(input_data.padding, [n, p1]) # Sampling sampled_idx, _ = car_lib.FarthestPointSampler( points, padding, num_sampled_points=p.num_samples) query_points = car_lib.MatmulGather(points, tf.expand_dims(sampled_idx, -1)) query_points = tf.squeeze(query_points, -2) # Grouping grouped_idx, grouped_padding = car_lib.NeighborhoodIndices( points, query_points, p.group_size, points_padding=padding, max_distance=p.ball_radius, sample_neighbors_uniformly=p.sample_neighbors_uniformly) grouped_points = car_lib.MatmulGather(points, grouped_idx) # Normalize the grouped points based on the location of the query point. grouped_points -= tf.expand_dims(query_points, -2) grouped_features = car_lib.MatmulGather(features, grouped_idx) # Get the padding for the query points. query_padding = tf.batch_gather(padding, sampled_idx) # Verify the shapes of output tensors. query_points = py_utils.HasShape(query_points, [n, p.num_samples, 3]) query_padding = py_utils.HasShape(query_padding, [n, p.num_samples]) grouped_features = py_utils.HasShape( grouped_features, [n, p.num_samples, p.group_size, c]) grouped_padding = py_utils.HasShape(grouped_padding, [n, p.num_samples, p.group_size]) output_grouped_points = py_utils.NestedMap(points=grouped_points, features=grouped_features, padding=grouped_padding) output_query = py_utils.NestedMap(points=query_points, padding=query_padding) output_map = py_utils.NestedMap({ 'grouped_points': output_grouped_points, 'query_points': output_query }) return output_map