Skip to content

labelflipping

labelFlipping(dataset, indices, poisoned_persent=0, targeted=False, target_label=4, target_changed_label=7)

Flips the labels of a specified portion of a dataset to random values or to a specific target label.

This function modifies the labels of selected samples in the dataset based on the specified poisoning percentage. Labels can be flipped either randomly or targeted to change from a specific label to another specified label.

Parameters:

Name Type Description Default
dataset Dataset

The dataset containing training data, expected to be a PyTorch dataset with a .targets attribute.

required
indices list of int

The list of indices in the dataset to consider for label flipping.

required
poisoned_percent float

The ratio of labels to change, expressed as a fraction (0 <= poisoned_percent <= 1). Default is 0.

required
targeted bool

If True, flips only labels matching target_label to target_changed_label. Default is False.

False
target_label int

The label to change when targeted is True. Default is 4.

4
target_changed_label int

The label to which target_label will be changed. Default is 7.

7

Returns:

Name Type Description
Dataset

A deep copy of the original dataset with modified labels in .targets.

Raises:

Type Description
ValueError

If poisoned_percent is not between 0 and 1, or if flipping_percent is invalid.

Notes
  • When not in targeted mode, labels are flipped for a random selection of indices based on the specified poisoned_percent. The new label is chosen randomly from the existing classes.
  • In targeted mode, labels that match target_label are directly changed to target_changed_label.
Source code in nebula/addons/attacks/poisoning/labelflipping.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
def labelFlipping(
    dataset,
    indices,
    poisoned_persent=0,
    targeted=False,
    target_label=4,
    target_changed_label=7,
):
    """
    Flips the labels of a specified portion of a dataset to random values or to a specific target label.

    This function modifies the labels of selected samples in the dataset based on the specified
    poisoning percentage. Labels can be flipped either randomly or targeted to change from a specific
    label to another specified label.

    Args:
        dataset (Dataset): The dataset containing training data, expected to be a PyTorch dataset
                           with a `.targets` attribute.
        indices (list of int): The list of indices in the dataset to consider for label flipping.
        poisoned_percent (float, optional): The ratio of labels to change, expressed as a fraction
                                            (0 <= poisoned_percent <= 1). Default is 0.
        targeted (bool, optional): If True, flips only labels matching `target_label` to `target_changed_label`.
                                   Default is False.
        target_label (int, optional): The label to change when `targeted` is True. Default is 4.
        target_changed_label (int, optional): The label to which `target_label` will be changed. Default is 7.

    Returns:
        Dataset: A deep copy of the original dataset with modified labels in `.targets`.

    Raises:
        ValueError: If `poisoned_percent` is not between 0 and 1, or if `flipping_percent` is invalid.

    Notes:
        - When not in targeted mode, labels are flipped for a random selection of indices based on the specified
          `poisoned_percent`. The new label is chosen randomly from the existing classes.
        - In targeted mode, labels that match `target_label` are directly changed to `target_changed_label`.
    """
    new_dataset = copy.deepcopy(dataset)
    targets = new_dataset.targets.detach().clone()
    num_indices = len(indices)
    # classes = new_dataset.classes
    # class_to_idx = new_dataset.class_to_idx
    # class_list = [class_to_idx[i] for i in classes]
    class_list = set(targets.tolist())
    if not targeted:
        num_flipped = int(poisoned_persent * num_indices)
        if num_indices == 0:
            return new_dataset
        if num_flipped > num_indices:
            return new_dataset
        flipped_indice = random.sample(indices, num_flipped)

        for i in flipped_indice:
            t = targets[i]
            flipped = torch.tensor(random.sample(class_list, 1)[0])
            while t == flipped:
                flipped = torch.tensor(random.sample(class_list, 1)[0])
            targets[i] = flipped
    else:
        for i in indices:
            if int(targets[i]) == int(target_label):
                targets[i] = torch.tensor(target_changed_label)
    new_dataset.targets = targets
    return new_dataset