두 개의 이미지를 박스 형태로 자르고(Cut) 합쳐서(Mix) 새로운 이미지를 만드는데, 이 때, ground truth label 역시 같은 비율로 합쳐서 새로운 (Image, Label) 훈련데이터를 생성한다.

두 (image, label) pair를 섞는 비율 $λ$은 대칭적인 $β$-분포로부터 샘플링한다.
https://github.com/clovaai/CutMix-PyTorch/blob/master/train.py#L220
for i, (input, target) inenumerate(train_loader):
# measure data loading time
data_time.update(time.time() - end)
input =input.cuda()
target = target.cuda()
r = np.random.rand(1)
if args.beta > 0 and r < args.cutmix_prob:
# generate mixed sample
lam = np.random.beta(args.beta, args.beta)
rand_index = torch.randperm(input.size()[0]).cuda()
target_a = target
target_b = target[rand_index]
bbx1, bby1, bbx2, bby2 = rand_bbox(input.size(), lam)
input[:, :, bbx1:bbx2, bby1:bby2] =input[rand_index, :, bbx1:bbx2, bby1:bby2]
# adjust lambda to exactly match pixel ratio
lam = 1 - ((bbx2 - bbx1) * (bby2 - bby1) / (input.size()[-1] *input.size()[-2]))
# compute output
output = model(input)
loss = criterion(output, target_a) * lam + criterion(output, target_b) * (1. - lam)
else:
# compute output
output = model(input)
loss = criterion(output, target)
https://github.com/clovaai/CutMix-PyTorch/blob/master/train.py#L279
def rand_bbox(size, lam):
W = size[2]
H = size[3]
cut_rat = np.sqrt(1. - lam)
cut_w = np.int(W * cut_rat)
cut_h = np.int(H * cut_rat)
# uniform
cx = np.random.randint(W)
cy = np.random.randint(H)
bbx1 = np.clip(cx - cut_w // 2, 0, W)
bby1 = np.clip(cy - cut_h // 2, 0, H)
bbx2 = np.clip(cx + cut_w // 2, 0, W)
bby2 = np.clip(cy + cut_h // 2, 0, H)
return bbx1, bby1, bbx2, bby2
논문에서 CIFAR-100에 대해서 PyramidNet에 대해 실험하였으며, 정확한 설정은 https://github.com/clovaai/CutMix-PyTorch#train-examples 에서 확인 가능하다. 기존 Baseline model에 CutMix를 적용할 경우, Top-1 error가 16.45%에서 14.23%로 약 2%의 성능향상을 보인다.