2023年6月21日发(作者:)
Pytorch实现数据集的加载和数据增强在这⾥介绍⼏种常⽤的的数据增强⽅法:标准的数据载⼊和数据增强以CIFAR10为例:论⽂中如下是对数据集的标准增强操作。对于训练集,padding=4为上下左右均填充 4 个 pixel,由32×32的尺⼨变为40×40,之后进⾏任意的裁剪;接着以0.5的概率进⾏⽔平翻转。将图像转化为tensor对象,并进⾏正态分布标准化。对于测试集,不进⾏增强操作,仅仅对图像转化为tensor对象,并进⾏正态分布标准化,标准化的值与训练集相同。import torchvisionimport orms as transformscifar_norm_mean = (0.49139968, 0.48215827, 0.44653124)cifar_norm_std = (0.24703233, 0.24348505, 0.26158768)transform_train = e([ Crop(32, padding=4), HorizontalFlip(), or(), ize(cifar_norm_mean, cifar_norm_std),])transform_test = e([ or(), ize(cifar_norm_mean, cifar_norm_std),])trainset = 10(root='./data', train=True, download=True, transform=transform_train)testset = 10(root='./data', train=False, download=True, transform=transform_test)trainloader = ader(trainset, batch_size=128, shuffle=True, pin_memory=(_available()))testloader = ader(testset, batch_size=100, shuffle=False, pin_memory=(_available()))数据划分使⽤分层抽样进⾏训练集的划分,划分为训练集和验证集:from _selection import StratifiedShuffleSplittrainset = 10(root='./data', train=True, download=True, transform=transform_train)validset = 10(root='./data', train=True, download=True, transform=transform_test)testset = 10(root='./data', train=False, download=True, transform=transform_test)if tion: labels = [trainset[i][1] for i in range(len(trainset))] ss = StratifiedShuffleSplit(n_splits=1, test_size=0.1, random_state=0) train_indices, valid_indices = list(((labels)[:, s], labels))[0] trainset = (trainset, train_indices) validset = (validset, valid_indices)#
使⽤pin_memory可以更快地加载到CUDA,但是内存要求更多trainloader = ader(trainset, batch_size=128, shuffle=True, pin_memory=(_available()))validloader = ader(validset, batch_size=100, shuffle=False, pin_memory=(_available()))testloader = ader(testset, batch_size=100, shuffle=False, pin_memory=(_available()))扩展的数据增强⽅法cutoutclass Cutout(object): """Randomly mask out one or more patches from an image. Args: n_holes (int): Number of patches to cut out of each image. length (int): The length (in pixels) of each square patch. """ def __init__(self, n_holes, length): self.n_holes = n_holes = length def __call__(self, img): """ Args: img (Tensor): Tensor image of size (C, H, W). Returns: Tensor: Image with n_holes of dimension length x length cut out of it. """ h = (1) w = (2) mask = ((h, w), 32) for n in range(self.n_holes): # (x,y)表⽰⽅形补丁的中⼼位置 y = t(h) x = t(w) y1 = (y - // 2, 0, h) y2 = (y + // 2, 0, h) x1 = (x - // 2, 0, w) x2 = (x + // 2, 0, w) mask[y1: y2, x1: x2] = 0. mask = _numpy(mask) mask = _as(img) img = img * mask return img主程序:transform_train = e([ Crop(32, padding=4), HorizontalFlip(), or(), ize(cifar_norm_mean, cifar_norm_std), Cutout(n_holes=1, length=16)])mixupdef mixup_data(x, y, alpha=1.0, use_cuda=True): '''Returns mixed inputs, pairs of targets, and lambda''' if alpha > 0: lam = (alpha, alpha) else: lam = 1 batch_size = ()[0] if use_cuda: index = rm(batch_size).cuda() else: index = rm(batch_size) mixed_x = lam * x + (1 - lam) * x[index, :] y_a, y_b = y, y[index] return mixed_x, y_a, y_b, lam定义误差函数:def mixup_criterion(criterion, pred, y_a, y_b, lam): return lam * criterion(pred, y_a) + (1 - lam) * criterion(pred, y_b)主函数的应⽤:for batch_idx, (inputs, targets) in enumerate(trainloader): inputs, targets = (device), (device) inputs, targets_a, targets_b, lam = mixup_data(inputs, targets, 1.) _grad() outputs = net(inputs) loss = mixup_criterion(criterion, outputs, targets_a, targets_b, lam) rd() ()对上述增强在ResNet18上进⾏实验,得到的结果如下:label-smoothing在Inception论⽂中提出,对标签label进⾏增强,作者认为one-hot编码会过拟合,因此作者在交叉熵中对错误label也分配了很⼩的权重来防⽌过拟合。作者引⼊了参数ϵ,设分类数为N,则对于某⼀个样本的label编码为:ϵϵϵϵ[N−1,...,N−1,1−ϵ,N−1,...,N−1]原先的one-hot编码是[0,...,0,1,0,...,0].作者在1000类的ImageNet上分类,使⽤ϵ=0.1获得了0.2%的提升。def CrossEntropyLoss_label_smooth(outputs, targets, num_classes=10, epsilon=0.1): N = (0) smoothed_labels = (size=(N, num_classes), fill_value=epsilon / (num_classes - 1)) smoothed_r_(dim=1, index=eze(targets, dim=1), value=1-epsilon) log_prob = _softmax(outputs, dim=1) loss = - (log_prob * smoothed_labels) / N return loss
2023年6月21日发(作者:)
Pytorch实现数据集的加载和数据增强在这⾥介绍⼏种常⽤的的数据增强⽅法:标准的数据载⼊和数据增强以CIFAR10为例:论⽂中如下是对数据集的标准增强操作。对于训练集,padding=4为上下左右均填充 4 个 pixel,由32×32的尺⼨变为40×40,之后进⾏任意的裁剪;接着以0.5的概率进⾏⽔平翻转。将图像转化为tensor对象,并进⾏正态分布标准化。对于测试集,不进⾏增强操作,仅仅对图像转化为tensor对象,并进⾏正态分布标准化,标准化的值与训练集相同。import torchvisionimport orms as transformscifar_norm_mean = (0.49139968, 0.48215827, 0.44653124)cifar_norm_std = (0.24703233, 0.24348505, 0.26158768)transform_train = e([ Crop(32, padding=4), HorizontalFlip(), or(), ize(cifar_norm_mean, cifar_norm_std),])transform_test = e([ or(), ize(cifar_norm_mean, cifar_norm_std),])trainset = 10(root='./data', train=True, download=True, transform=transform_train)testset = 10(root='./data', train=False, download=True, transform=transform_test)trainloader = ader(trainset, batch_size=128, shuffle=True, pin_memory=(_available()))testloader = ader(testset, batch_size=100, shuffle=False, pin_memory=(_available()))数据划分使⽤分层抽样进⾏训练集的划分,划分为训练集和验证集:from _selection import StratifiedShuffleSplittrainset = 10(root='./data', train=True, download=True, transform=transform_train)validset = 10(root='./data', train=True, download=True, transform=transform_test)testset = 10(root='./data', train=False, download=True, transform=transform_test)if tion: labels = [trainset[i][1] for i in range(len(trainset))] ss = StratifiedShuffleSplit(n_splits=1, test_size=0.1, random_state=0) train_indices, valid_indices = list(((labels)[:, s], labels))[0] trainset = (trainset, train_indices) validset = (validset, valid_indices)#
使⽤pin_memory可以更快地加载到CUDA,但是内存要求更多trainloader = ader(trainset, batch_size=128, shuffle=True, pin_memory=(_available()))validloader = ader(validset, batch_size=100, shuffle=False, pin_memory=(_available()))testloader = ader(testset, batch_size=100, shuffle=False, pin_memory=(_available()))扩展的数据增强⽅法cutoutclass Cutout(object): """Randomly mask out one or more patches from an image. Args: n_holes (int): Number of patches to cut out of each image. length (int): The length (in pixels) of each square patch. """ def __init__(self, n_holes, length): self.n_holes = n_holes = length def __call__(self, img): """ Args: img (Tensor): Tensor image of size (C, H, W). Returns: Tensor: Image with n_holes of dimension length x length cut out of it. """ h = (1) w = (2) mask = ((h, w), 32) for n in range(self.n_holes): # (x,y)表⽰⽅形补丁的中⼼位置 y = t(h) x = t(w) y1 = (y - // 2, 0, h) y2 = (y + // 2, 0, h) x1 = (x - // 2, 0, w) x2 = (x + // 2, 0, w) mask[y1: y2, x1: x2] = 0. mask = _numpy(mask) mask = _as(img) img = img * mask return img主程序:transform_train = e([ Crop(32, padding=4), HorizontalFlip(), or(), ize(cifar_norm_mean, cifar_norm_std), Cutout(n_holes=1, length=16)])mixupdef mixup_data(x, y, alpha=1.0, use_cuda=True): '''Returns mixed inputs, pairs of targets, and lambda''' if alpha > 0: lam = (alpha, alpha) else: lam = 1 batch_size = ()[0] if use_cuda: index = rm(batch_size).cuda() else: index = rm(batch_size) mixed_x = lam * x + (1 - lam) * x[index, :] y_a, y_b = y, y[index] return mixed_x, y_a, y_b, lam定义误差函数:def mixup_criterion(criterion, pred, y_a, y_b, lam): return lam * criterion(pred, y_a) + (1 - lam) * criterion(pred, y_b)主函数的应⽤:for batch_idx, (inputs, targets) in enumerate(trainloader): inputs, targets = (device), (device) inputs, targets_a, targets_b, lam = mixup_data(inputs, targets, 1.) _grad() outputs = net(inputs) loss = mixup_criterion(criterion, outputs, targets_a, targets_b, lam) rd() ()对上述增强在ResNet18上进⾏实验,得到的结果如下:label-smoothing在Inception论⽂中提出,对标签label进⾏增强,作者认为one-hot编码会过拟合,因此作者在交叉熵中对错误label也分配了很⼩的权重来防⽌过拟合。作者引⼊了参数ϵ,设分类数为N,则对于某⼀个样本的label编码为:ϵϵϵϵ[N−1,...,N−1,1−ϵ,N−1,...,N−1]原先的one-hot编码是[0,...,0,1,0,...,0].作者在1000类的ImageNet上分类,使⽤ϵ=0.1获得了0.2%的提升。def CrossEntropyLoss_label_smooth(outputs, targets, num_classes=10, epsilon=0.1): N = (0) smoothed_labels = (size=(N, num_classes), fill_value=epsilon / (num_classes - 1)) smoothed_r_(dim=1, index=eze(targets, dim=1), value=1-epsilon) log_prob = _softmax(outputs, dim=1) loss = - (log_prob * smoothed_labels) / N return loss
发布评论