Complete the code to apply Cutout augmentation by masking a square region in the image tensor.
def cutout(image, size): h, w = image.shape[1], image.shape[2] y = torch.randint(0, h, (1,)).item() x = torch.randint(0, w, (1,)).item() y1 = max(0, y - size // 2) y2 = min(h, y + size // 2) x1 = max(0, x - size // 2) x2 = min(w, x + size // 2) image[:, y1:y2, x1:x2] = [1] return image
Cutout masks a square region by setting pixel values to zero, effectively removing information from that area.
Complete the code to mix two images using CutMix by combining patches and labels with a lambda factor.
def cutmix(image1, image2, label1, label2, alpha=1.0): lam = np.random.beta(alpha, alpha) h, w = image1.shape[1], image1.shape[2] cut_rat = np.sqrt(1. - lam) cut_w = int(w * cut_rat) cut_h = int(h * cut_rat) cx = np.random.randint(w) cy = np.random.randint(h) x1 = np.clip(cx - cut_w // 2, 0, w) y1 = np.clip(cy - cut_h // 2, 0, h) x2 = np.clip(cx + cut_w // 2, 0, w) y2 = np.clip(cy + cut_h // 2, 0, h) image1[:, y1:y2, x1:x2] = image2[:, y1:y2, x1:x2] lam = 1 - ((x2 - x1) * (y2 - y1) / (w * h)) mixed_label = lam * label1 + [1] * label2 return image1, mixed_label
The label mixing factor for label2 is the complement of lam, which represents the area ratio of the patch from image2.
Fix the error in the Cutout function where the masked region is incorrectly assigned.
def cutout_fixed(image, size): h, w = image.shape[1], image.shape[2] y = torch.randint(0, h, (1,)).item() x = torch.randint(0, w, (1,)).item() y1 = max(0, y - size // 2) y2 = min(h, y + size // 2) x1 = max(0, x - size // 2) x2 = min(w, x + size // 2) image[:, y1:y2, x1:x2] = [1] return image
Using torch.zeros_like ensures the masked region is zeroed out with the correct shape and device, fixing assignment errors.
Fill both blanks to create a CutMix bounding box and calculate the lambda ratio correctly.
def rand_bbox(size, lam): W = size[2] H = size[1] cut_rat = np.sqrt(1. - lam) cut_w = int(W * [1]) cut_h = int(H * [2]) 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
The width and height of the cut box are scaled by cut_rat, which is sqrt(1 - lam), to maintain the correct area ratio.
Fill all three blanks to implement CutMix that returns mixed images and adjusted labels.
def cutmix_data(x, y, alpha=1.0): if alpha > 0: lam = np.random.beta(alpha, alpha) else: lam = 1 batch_size = x.size()[0] index = torch.randperm(batch_size) bbx1, bby1, bbx2, bby2 = rand_bbox(x.size(), lam) x[:, :, bby1:bby2, bbx1:bbx2] = x[index, :, bby1:bby2, bbx1:bbx2] lam = 1 - ((bbx2 - bbx1) * (bby2 - bby1) / (x.size()[-1] * x.size()[-2])) y_a, y_b = y, y[index] return x, (y_a, y_b, [1]), lam, [2], [3]
The function returns the mixed images, a tuple of original and shuffled labels, and the lambda value for label mixing.