class_center_sample¶
- paddle.nn.functional. class_center_sample ( label, num_classes, num_samples, group=None ) [source]
-
Class center sample method is proposed from the paper PartialFC that only sample a subset of the class centers. The process of sampling subset class centers is straightforward:
First select the positive class centers;
Then randomly sample negative class centers.
Specifically, given a label tensor, shape [batch_size], select all the positive class centers and randomly sample negative class centers, then remap the input label tensor using the sampled class centers.
For more information, Partial FC: Training 10 Million Identities on a Single Machine arxiv: https://arxiv.org/abs/2010.05222
Note
If the number of the positive class centers is greater than the input num_samples, it keeps all the positive class centers and the shape of sampled_class_center will be [num_positive_class_centers].
The API supports CPU, single GPU and multi GPU.
For data parallel mode, set
group=False
.For model parallel mode, set
group=None
or the group instance return by paddle.distributed.new_group.- Parameters
-
label (Tensor) – 1-D tensor with shape [N], each label in [0, num_classes)
num_classes (int) – A positive integer to specify the number of classes at local rank. Note that num_classes of each GPU can be different.
num_samples (int) – A positive integer to specify the number of class center to sample.
group (Group, optional) – The group instance return by paddle.distributed.new_group or
None
for global default group orFalse
for data parallel (do not communication cross ranks). Default isNone
.
- Returns
-
(remapped_label, sampled_class_center), remapped label using sampled class center, sampled class center from [0, num_classes).
- Return type
-
Tuple of two
Tensor
Examples:
>>> # CPU or single GPU >>> import paddle >>> num_classes = 20 >>> batch_size = 10 >>> num_samples = 6 >>> paddle.seed(2023) >>> label = paddle.randint(low=0, high=num_classes, shape=[batch_size], dtype='int64') >>> remapped_label, sampled_class_index = paddle.nn.functional.class_center_sample(label, num_classes, num_samples) >>> print(label) Tensor(shape=[10], dtype=int64, place=Place(cpu), stop_gradient=True, [17, 10, 5 , 18, 8 , 8 , 19, 14, 10, 14]) >>> print(remapped_label) Tensor(shape=[10], dtype=int64, place=Place(cpu), stop_gradient=True, [4, 2, 0, 5, 1, 1, 6, 3, 2, 3]) >>> print(sampled_class_index) Tensor(shape=[7], dtype=int64, place=Place(cpu), stop_gradient=True, [5 , 8 , 10, 14, 17, 18, 19])
>>> >>> # required: distributed >>> # Multi GPU, test_class_center_sample.py >>> import paddle >>> import paddle.distributed as dist >>> strategy = dist.fleet.DistributedStrategy() >>> dist.fleet.init(is_collective=True, strategy=strategy) >>> batch_size = 10 >>> num_samples = 6 >>> rank_id = dist.get_rank() >>> # num_classes of each GPU can be different, e.g num_classes_list = [10, 8] >>> num_classes_list = [10, 10] >>> num_classes = paddle.sum(paddle.to_tensor(num_classes_list)) >>> label = paddle.randint(low=0, high=num_classes.item(), shape=[batch_size], dtype='int64') >>> label_list = [] >>> dist.all_gather(label_list, label) >>> label = paddle.concat(label_list, axis=0) >>> remapped_label, sampled_class_index = paddle.nn.functional.class_center_sample(label, num_classes_list[rank_id], num_samples) >>> print(label) >>> print(remapped_label) >>> print(sampled_class_index) >>> #python -m paddle.distributed.launch --gpus=0,1 test_class_center_sample.py >>> # rank 0 output: Tensor(shape=[20], dtype=int64, place=CUDAPlace(0), stop_gradient=True, [10, 17, 15, 11, 9 , 12, 18, 18, 17, 18, 19, 2 , 8 , 13, 11, 13, 9 , 10, 0 , 4 ]) Tensor(shape=[20], dtype=int64, place=CUDAPlace(0), stop_gradient=True, [6 , 11, 10, 7 , 4 , 8 , 12, 12, 11, 12, 13, 1 , 3 , 9 , 7 , 9 , 4 , 6 , 0 , 2 ]) Tensor(shape=[6], dtype=int64, place=CUDAPlace(0), stop_gradient=True, [0, 2, 4, 8, 9, 3]) >>> # rank 1 output: Tensor(shape=[20], dtype=int64, place=CUDAPlace(1), stop_gradient=True, [10, 17, 15, 11, 9 , 12, 18, 18, 17, 18, 19, 2 , 8 , 13, 11, 13, 9 , 10, 0 , 4 ]) Tensor(shape=[20], dtype=int64, place=CUDAPlace(1), stop_gradient=True, [6 , 11, 10, 7 , 4 , 8 , 12, 12, 11, 12, 13, 1 , 3 , 9 , 7 , 9 , 4 , 6 , 0 , 2 ]) Tensor(shape=[7], dtype=int64, place=CUDAPlace(1), stop_gradient=True, [0, 1, 2, 3, 5, 7, 8])