MCPcopy Create free account
hub / github.com/Project-MONAI/MONAI / CutMix

Class CutMix

monai/transforms/regularization/array.py:102–166  ·  view source on GitHub ↗

CutMix augmentation as described in: Sangdoo Yun, Dongyoon Han, Seong Joon Oh, Sanghyuk Chun, Junsuk Choe, Youngjoon Yoo. CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features, ICCV 2019 Class derived from :py:class:`monai.transforms.M

Source from the content-addressed store, hash-verified

100
101
102class CutMix(Mixer):
103 """CutMix augmentation as described in:
104 Sangdoo Yun, Dongyoon Han, Seong Joon Oh, Sanghyuk Chun, Junsuk Choe, Youngjoon Yoo.
105 CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features,
106 ICCV 2019
107
108 Class derived from :py:class:`monai.transforms.Mixer`. See corresponding
109 documentation for details on the constructor parameters. Here, alpha not only determines
110 the mixing weight but also the size of the random rectangles used during for mixing.
111 Please refer to the paper for details.
112
113 Please note that there is a change in behavior starting from version 1.4.0. In the previous
114 implementation, the transform would generate a different label each time it was called.
115 To ensure determinism, the new implementation will now generate the same label for
116 the same input image when using the same operation.
117
118 The most common use case is something close to:
119
120 .. code-block:: python
121
122 cm = CutMix(batch_size=8, alpha=0.5)
123 for batch in loader:
124 images, labels = batch
125 augimg, auglabels = cm(images, labels)
126 output = model(augimg)
127 loss = loss_function(output, auglabels)
128 ...
129
130 """
131
132 def apply(self, data: torch.Tensor):
133 weights, perm, coords = self._params
134 nsamples, _, *dims = data.shape
135 if len(weights) != nsamples:
136 raise ValueError(f"Expected batch of size: {len(weights)}, but got {nsamples}")
137
138 mask = torch.ones_like(data)
139 for s, weight in enumerate(weights):
140 lengths = [d * sqrt(1 - weight) for d in dims]
141 idx = [slice(None)] + [slice(c, min(ceil(c + ln), d)) for c, ln, d in zip(coords, lengths, dims)]
142 mask[s][idx] = 0
143
144 return mask * data + (1 - mask) * data[perm, ...]
145
146 def apply_on_labels(self, labels: torch.Tensor):
147 weights, perm, _ = self._params
148 nsamples, *dims = labels.shape
149 if len(weights) != nsamples:
150 raise ValueError(f"Expected batch of size: {len(weights)}, but got {nsamples}")
151
152 mixweight = weights[(Ellipsis,) + (None,) * len(dims)]
153 return mixweight * labels + (1 - mixweight) * labels[perm, ...]
154
155 def __call__(self, data: torch.Tensor, labels: torch.Tensor | None = None, randomize=True):
156 data_t = convert_to_tensor(data, track_meta=get_track_meta())
157 augmented_label = None
158 if labels is not None:
159 labels_t = convert_to_tensor(labels, track_meta=get_track_meta())

Callers 2

test_cutmixMethod · 0.90
__init__Method · 0.85

Calls

no outgoing calls

Tested by 1

test_cutmixMethod · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…