转载于:https://blog.csdn.net/qq_42079689/article/details/102574358
参考:《动手学深度学习》(Pytorch版)
作者在这里讲解了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节样式迁移时发现有这么个运算:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 |
其中:
1 2 3 | inv_normalize = torchvision.transforms.Normalize( mean= -rgb_mean / rgb_std, std= 1/rgb_std) |
这个操作确实厉害,一时间没看懂,后来看了转载的博文,才知道怎么进行反归一化操作:
假设输入为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版)作者,感谢!