• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bethgelab / foolbox / 8137716344

22 Jan 2024 10:53PM UTC coverage: 98.47%. Remained the same
8137716344

push

github

web-flow
Bump pillow from 10.1.0 to 10.2.0 in /tests (#718)

Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.1.0 to 10.2.0.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/10.1.0...10.2.0)

---
updated-dependencies:
- dependency-name: pillow
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

3475 of 3529 relevant lines covered (98.47%)

7.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/foolbox/attacks/dataset_attack.py
1
from typing import Union, Optional, Any, List
10✔
2
import numpy as np
10✔
3
import eagerpy as ep
10✔
4

5
from ..devutils import atleast_kd
10✔
6

7
from ..models import Model
10✔
8

9
from ..distances import Distance
10✔
10

11
from ..criteria import Criterion
10✔
12

13
from .base import FlexibleDistanceMinimizationAttack
10✔
14
from .base import T
10✔
15
from .base import get_criterion
10✔
16
from .base import raise_if_kwargs
10✔
17
from .base import verify_input_bounds
10✔
18

19

20
class DatasetAttack(FlexibleDistanceMinimizationAttack):
10✔
21
    """Draws randomly from the given dataset until adversarial examples for all
22
    inputs have been found.
23

24
    To pass data form the dataset to this attack, call :meth:`feed()`.
25
    :meth:`feed()` can be called several times and should only be called with
26
    batches that are small enough that they can be passed through the model.
27

28
    Args:
29
        distance : Distance measure for which minimal adversarial examples are searched.
30
    """
31

32
    def __init__(self, *, distance: Optional[Distance] = None):
10✔
33
        super().__init__(distance=distance)
8✔
34
        self.raw_inputs: List[ep.Tensor] = []
8✔
35
        self.raw_outputs: List[ep.Tensor] = []
8✔
36
        self.inputs: Optional[ep.Tensor] = None
8✔
37
        self.outputs: Optional[ep.Tensor] = None
8✔
38

39
    def feed(self, model: Model, inputs: Any) -> None:
10✔
40
        x = ep.astensor(inputs)
8✔
41
        del inputs
8✔
42

43
        self.raw_inputs.append(x)
8✔
44
        self.raw_outputs.append(model(x))
8✔
45

46
    def process_raw(self) -> None:
10✔
47
        raw_inputs = self.raw_inputs
8✔
48
        raw_outputs = self.raw_outputs
8✔
49
        assert len(raw_inputs) == len(raw_outputs)
8✔
50
        assert (self.inputs is None) == (self.outputs is None)
8✔
51

52
        if self.inputs is None:
8✔
53
            if len(raw_inputs) == 0:
8✔
54
                raise ValueError(
8✔
55
                    "DatasetAttack can only be called after data has been provided using 'feed()'"
56
                )
57
        elif self.inputs is not None:
8✔
58
            assert self.outputs is not None
8✔
59
            raw_inputs = [self.inputs] + raw_inputs
8✔
60
            raw_outputs = [self.outputs] + raw_outputs
8✔
61

62
        self.inputs = ep.concatenate(raw_inputs, axis=0)
8✔
63
        self.outputs = ep.concatenate(raw_outputs, axis=0)
8✔
64
        self.raw_inputs = []
8✔
65
        self.raw_outputs = []
8✔
66

67
    def run(
10✔
68
        self,
69
        model: Model,
70
        inputs: T,
71
        criterion: Union[Criterion, T],
72
        *,
73
        early_stop: Optional[float] = None,
74
        **kwargs: Any,
75
    ) -> T:
76
        raise_if_kwargs(kwargs)
8✔
77
        self.process_raw()
8✔
78
        assert self.inputs is not None
8✔
79
        assert self.outputs is not None
8✔
80
        x, restore_type = ep.astensor_(inputs)
8✔
81
        del inputs, kwargs
8✔
82

83
        verify_input_bounds(x, model)
8✔
84

85
        criterion = get_criterion(criterion)
8✔
86

87
        result = x
8✔
88
        found = criterion(x, model(x))
8✔
89

90
        batch_size = len(x)
8✔
91

92
        # for every sample try every other sample
93
        index_pools: List[List[int]] = []
8✔
94
        for i in range(batch_size):
8✔
95
            indices = list(range(batch_size))
8✔
96
            indices.remove(i)
8✔
97
            np.random.shuffle(indices)
8✔
98
            index_pools.append(indices)
8✔
99

100
        for i in range(batch_size - 1):
8✔
101
            if found.all():
8✔
102
                break
8✔
103

104
            indices_np = np.array([pool[i] for pool in index_pools])
8✔
105

106
            xp = self.inputs[indices_np]
8✔
107
            yp = self.outputs[indices_np]
8✔
108
            is_adv = criterion(xp, yp)
8✔
109

110
            new_found = ep.logical_and(is_adv, found.logical_not())
8✔
111
            result = ep.where(atleast_kd(new_found, result.ndim), xp, result)
8✔
112
            found = ep.logical_or(found, new_found)
8✔
113

114
        return restore_type(result)
8✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc