图像处理tips

图像归一化和逆归一化

在使用torch实现图像分类任务时,通常需要对图像进行归一化处理。在对抗样本生成任务中,处理完的图片有时候需要保存下来,因此涉及逆归一化的操作。

图像归一化

与图像分类任务不同,在生成对抗样本任务中,即需要用归一化来保证原始图像的分类准确率,又不能直接在归一化图的基础上添加扰动,因此一种做法是将归一化由数据加载时的transform变换中,改编成网络模型的一部分。具体见以下代码:

# 分类任务中常见的做法
transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224) ,
    transforms.ToTensor()
    transforms.Normalize(mean=[0.485, 0.456, 0.406],
                         std=[0.229, 0.224, 0.225])
])

# 对抗样本生成任务中的做法
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                     std=[0.229, 0.224, 0.225])
model = torchvision.models.resnet50(pretrained=True)
model = nn.Sequential(normalize, model)
model.eval()
model = model.to(device)

图像逆归一化

通常在生成对抗样本(或扰动)后,需要将对抗样本保存,因而需要逆归一化的过程,否则保存的图片将存在失真。具体代码见下

# 第一种做法
mean = torch.tensor([1, 2, 3], dtype=torch.float32)
std = torch.tensor([2, 2, 2], dtype=torch.float32)

normalize = T.Normalize(mean.tolist(), std.tolist())

unnormalize = T.Normalize((-mean / std).tolist(), (1.0 / std).tolist())

# 第二种做法
inv_normalize = transforms.Normalize(
    mean=[-0.485/0.229, -0.456/0.224, -0.406/0.255],
    std=[1/0.229, 1/0.224, 1/0.255]
)
inv_tensor = inv_normalize(tensor)

参考资料:

  1. https://discuss.pytorch.org/t/simple-way-to-inverse-transform-normalization/4821/4

  2. https://github.com/pytorch/vision/issues/528

Table of Contents