torchvision中给出的归一化方法transforms.Normalize()的形参理解与坑—拓展:反归一化

torchvision中给出的归一化方法transforms.Normalize()的形参理解与坑—拓展:反归一化

参考:
1、
《动手学深度学习》(Pytorch版)
2、torchvision中给出的归一化方法transforms.Normalize()的形参理解与坑

参考链接2博客作者在这里讲解了transforms.Normalize()的原理:transforms.Normalize( mean = (0.5,0.5,0.5), std = (0.5,0.5,0.5) )并不是指将张量的均值和标准差设为0.5,而是做这么一个运算:输入的每个channel做 ( [0, 1] - mean(0.5) )/ std(0.5)= [-1, 1] 的运算,所以这一句的实际结果是将[0,1]的张量归一化到[-1, 1]上。
而《动手学深度学习》(Pytorch)版第9章9.11节样式迁移时发现有这么个计算:

def preprocess(PIL_img, image_shape):
    process = torchvision.transforms.Compose([
        torchvision.transforms.Resize(image_shape),
        torchvision.transforms.ToTensor(),
        torchvision.transforms.Normalize(mean=rgb_mean, std=rgb_std)])
        # input[channel] = (input[channel] - mean[channel]) / std[channel]
    return process(PIL_img).unsqueeze(dim = 0) # (batch_size, 3, H, W)

def postprocess(img_tensor):
    inv_normalize = torchvision.transforms.Normalize(
        mean= -rgb_mean / rgb_std,
        std= 1/rgb_std)
    #参考 https://blog.csdn.net/qq_42079689/article/details/102574358 倒推得到
    to_PIL_image = torchvision.transforms.ToPILImage()
    #这里不用再调整size了,因为后处理是处理生成的图片,只有一张
    return to_PIL_image(inv_normalize(img_tensor[0].cpu()).clamp(0, 1))
           # 使用clamp函数对小于0和大于1的值分别取0和1

其中:

inv_normalize = torchvision.transforms.Normalize(
        mean= -rgb_mean / rgb_std,
        std= 1/rgb_std)

这个操作确实厉害,一时间没看懂,后来看了参考博文2,才知道怎么进行的反归一化操作:
假设输入为X,归一化操作:(X - Mean)/ Std = Y,那么X = Y × Std + Mean ,化简: X = (Y - Mean / Std)× Std = [Y - ( -Mean / Std)] × Std
于是:反归一化则只需令Mean = -Mean / Std,Std = 1 / Std,即可实现。
特别感谢: 风雪夜归人o,《动手学深度学习》(Pytorch版)作者,感谢!

你可能感兴趣的:(Pytorch,pytorch,深度学习,人工智能)