Cutout 可以理解为 Dropout 的一种扩展操作,不同的是 Dropout 是对图像经过网络后生成的特征进行遮挡,而 Cutout 是直接对输入的图像进行遮挡,它在图像上生成一个大小为 cutout_size 的矩形区域,并将该区域内的像素值置零,相对于Dropout对噪声的鲁棒性更好。
新建如下类:
class Cutout(object):
def __init__(self, cutout_size=16):
self.cutout_size = cutout_size
def __call__(self, img):
h, w = img.shape[-2:]
mask = np.ones((h, w), np.float32)
y = np.random.randint(h)
x = np.random.randint(w)
y1 = np.clip(y - self.cutout_size // 2, 0, h)
y2 = np.clip(y + self.cutout_size // 2, 0, h)
x1 = np.clip(x - self.cutout_size // 2, 0, w)
x2 = np.clip(x + self.cutout_size // 2, 0, w)
mask[y1:y2, x1:x2] = 0.0
img = img.astype(np.float32)
img *= mask
return img
加入train的数据增强中:
# 定义训练集的数据增强流程
self.train_transforms = transforms.Compose([
transforms.Resize((224, 224)),
transforms.RandomHorizontalFlip(), # 随机水平翻转
transforms.ColorJitter(0.4, 0.4, 0.4), # 颜色抖动
transforms.BrightnessTransform(0.4), # 光照增强
Cutout(cutout_size=16),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
在实际使用中,可以根据需求调整 cutout_size 的大小。