在域自适应变化中,或者在处理数据集的时候,经常需要对于图像 或者数据集 的均值和方差进行分析
通过分析均值、方差,可以比较高效地获得数据分布情况 特别是大数据集
因此,在这里记录并且介绍一下图片均值、方差的获取方法,通过一些简单的实验来说明算法和结果。
1、基本背景
1) 图片的均值、方差
一张三通道RGB图片可以表示为 RC*H*W 的一个空间,其中:
C 表示通道 ;H 表示图片的长度 ;W 表示图片的宽度
可以用一个大小为 I = [C, H, W] 的矩阵来表示这张图片
均值 2)均值、方差和数据集的数据分布的关系 1) 输入初始化 结果 2) 获取方差 结果 实例个数N和通道C保持不变,对于高度H和宽度W的维度,通过 view() 函数变成一维向量,求方差; 3) 获取标准差和均值 结果 4)完整代码 出处:amazon-research/crossnorm-selfnorm > models > cnsn.py 算法原理和代码都很简单,但是数据分布是图像处理和数据集处理中非常重要的一部分,应用分布可以做到 风格迁移、域变换 等多种SOTA应用,需要加以关注!
公式:
μ
=
1
H
∗
W
∑
0
<
i
≤
H
,
0
<
j
≤
W
I
i
,
j
mu=frac{1}{H*W}sum_{{0
参考文章:CSDN > 如何进行数据分析统计_对您不了解的数据集进行统计分析
正态性检查:数据集是否遵循正态分布;
分类变量:数据集中的点是否均匀分布;
数据关联:确定变量之间的关系并清除高度相关的数据;
2、代码与实验
import torch
# 初始化一个矩阵
# a : [N, C, H, W]
a = torch.ones([2,2,3,3])
a[:,:,:,2] *= 4
tensor([[[[1., 1., 4.],
[1., 1., 4.],
[1., 1., 4.]],
......
[[1., 1., 4.],
[1., 1., 4.],
[1., 1., 4.]]]])
x = a ; eps = 1e-5
size = x.size()
assert (len(size) == 4) # if size!=4 break
N, C = size[:2]
tmp_var = x.contiguous().view(N, C, -1)
var = x.contiguous().view(N, C, -1).var(dim=2) + eps
# 记录中间数据tmp_var
print("tmp_var : {}, {}".format(tmp_var, tmp_var.size()))
# 记录方差var
print("tmp_var : {}, {}".format(var, var.size()))
tmp_var : tensor([[[1., 1., 4., 1., 1., 4., 1., 1., 4.],
[1., 1., 4., 1., 1., 4., 1., 1., 4.]],
[[1., 1., 4., 1., 1., 4., 1., 1., 4.],
[1., 1., 4., 1., 1., 4., 1., 1., 4.]]]), torch.Size([2, 2, 9])
tmp_var : tensor([[2.2500, 2.2500],
[2.2500, 2.2500]]), torch.Size([2, 2])
# contiguous() : make the x's memory space contiguous
# the view() can be only used on contiguous memory space
std = var.sqrt().view(N, C, 1, 1)
mean = x.contiguous().view(N, C, -1).mean(dim=2).view(N, C, 1, 1)
# 记录标准差std
print("std : {}, {}".format(std, std.size()))
# 记录均值mean
print("mean : {}, {}".format(mean, mean.size()))
std : tensor([[[[1.5000]],
[[1.5000]]],
[[[1.5000]],
[[1.5000]]]]), torch.Size([2, 2, 1, 1])
mean : tensor([[[[2.]],
[[2.]]],
[[[2.]],
[[2.]]]]), torch.Size([2, 2, 1, 1])
def calc_ins_mean_std(x, eps=1e-5):
"""extract feature map statistics"""
# eps is a small value added to the variance to avoid divide-by-zero.
size = x.size()
assert (len(size) == 4) # if size!=4 break
N, C = size[:2]
var = x.contiguous().view(N, C, -1).var(dim=2) + eps
# contiguous() : make the x's memory space contiguous
# the view() can be only used on contiguous memory space
std = var.sqrt().view(N, C, 1, 1)
mean = x.contiguous().view(N, C, -1).mean(dim=2).view(N, C, 1, 1)
return mean, std
3、总结



