当前位置:   article > 正文

【Pytorch基础知识】数据的归一化和反归一化_tensor归一化

tensor归一化

一张正常的图,或者说是人眼习惯的图是这样的:

但是,为了神经网络更快收敛,我们在深度学习网络过程中通常需要将读取的图片转为tensor并归一化(此处的归一化transforms.Normalize()操作)输入到网络中进行系列操作。

如果将转成的tensor再直接转为图片,就会变成下图,和我们眼睛看到是不一样感觉。

这是因为,将图片转为tensor并归一化,tensor之中会有负值,和我们正常看到的是不一样的,如果不进行反归一化到 [0,1],就会变成下图,会觉得变扭。

我们正常看到的图片tensor是[0,255]或者[0,1]

解释transforms.Normalize()归一化后的图像,满足均值为0方差为1,被限定在一定的数值内,一般的数值为[-1,1]。

这个过程中,我们需要进行如下操作,才能把图片转为tensor操作再转为图片(人眼习惯的)这里的tensor操作是transforms系列操作。

归一化的目的:使得预处理的数据被限定在一定的范围内,从而消除奇异样本数据导致的不良影响。数据归一化处理后,可以加快梯度下降求最优解的速度,且有可能提高精度(如KNN)。

反归一化的目的:为了还原原来人眼可以识别的图。


归一化

一幅图片的格式为【批数据的数量× 通道数× 高× 宽】

在这里插入图片描述

接下来开始计算mean 和 std: 

  1. nb_samples = 0
  2. #创建3维的空列表
  3. channel_mean = torch.zeros(3)
  4. channel_std = torch.zeros(3)
  5. print(image.shape)
  6. N, C, H, W = image.shape[:4]
  7. image = image.view(N, C, -1) #将w,h维度的数据展平,为batch,channel,data,然后对三个维度上的数分别求和和标准差
  8. print(image.shape)
  9. #展平后,w,h属于第二维度,对他们求平均,sum(0)为将同一纬度的数据累加
  10. channel_mean += image.mean(2).sum(0)
  11. #展平后,w,h属于第二维度,对他们求标准差,sum(0)为将同一纬度的数据累加
  12. channel_std += image.std(2).sum(0)
  13. #获取所有batch的数据,这里为1
  14. nb_samples += N
  15. #获取同一batch的均值和标准差
  16. channel_mean /= nb_samples
  17. channel_std /= nb_samples
  18. print(channel_mean, channel_std)

然后利用transforms.Normalize 进行转换:

  1. normalizer = transforms.Normalize(mean=channel_mean, std=channel_std)
  2. # 归一化后得到可处理的值
  3. data = normalizer(image)

反归一化

根据归一化计算得到的mean和std,我们可以反推出反归一化的 mean 和 std,从而利用 transforms.Normalize 进行转换,计算方法如下:

MEAN是指归一化时计算出来的均值,de_MEAN是计算出来反归一化的均值,后面需要用。


综合上面的讲解及代码,整合最后的代码为下:

  1. # 定义一个image图像,torch.Size([1, 3, 319, 256])
  2. image = torch.rand([1,3,319,256])
  3. # 计算原图的 mean 和std
  4. nb_samples = 0
  5. #创建3维的空列表
  6. channel_mean = torch.zeros(3)
  7. channel_std = torch.zeros(3)
  8. print(image.shape)
  9. N, C, H, W = image.shape[:4]
  10. #将w,h维度的数据展平,为batch,channel,data,然后对三个维度上的数分别求和和标准差
  11. image = image.view(N, C, -1)
  12. print(image.shape)
  13. #展平后,w,h属于第二维度,对他们求平均,sum(0)为将同一纬度的数据累加
  14. channel_mean += image.mean(2).sum(0)
  15. #展平后,w,h属于第二维度,对他们求标准差,sum(0)为将同一纬度的数据累加
  16. channel_std += image.std(2).sum(0)
  17. #获取所有batch的数据,这里为1
  18. nb_samples += N
  19. #获取同一batch的均值和标准差
  20. channel_mean /= nb_samples
  21. channel_std /= nb_samples
  22. print(channel_mean, channel_std)
  23. # 这是归一化的 mean 和std
  24. channel_mean = torch.tensor([-0.5321, -0.8102, -0.5532])
  25. channel_std = torch.tensor([1.2582, 1.0009, 0.9211])
  26. # 这是反归一化的 mean 和std
  27. MEAN = [-mean/std for mean, std in zip(channel_mean, channel_std)]
  28. STD = [1/std for std in channel_std]
  29. # 归一化和反归一化生成器
  30. normalizer = transforms.Normalize(mean=channel_mean, std=channel_std)
  31. denormalizer = transforms.Normalize(mean=MEAN, std=STD)
  32. # 归一化得到可处理的值
  33. data = normalizer(image)
  34. # 反归一化得到原图
  35. image2 = denormalizer(data)

image ≈ image2

因为浮点数计算有误差,所以不会完全一样,但是问题不大~

 这样就可以得到tensor转换后的原图了。

好了,大功告成,完结撒花!

欢迎关注、点赞、收藏、评论、分享给好友,一起学习有趣的新知识!!! 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/214853?site
推荐阅读
相关标签
  

闽ICP备14008679号