如何绘制/显示数据集或图像分布?

数据挖掘 Python 分配 matplotlib 图片
2021-10-04 14:30:22

我想查看特定图像或数据集的分布,看看它们是否不同。
只是写类似的东西:

# mydataset.shape = (50k,32,32,3)
plt.hist(mydataset.reshape(-1))

做这个把戏?还是我应该做其他事情?例如在 cifar10 上这样做给了我这个情节: 在此处输入图像描述

但是,它看起来不正确,有 50K 训练图像,我不知道如何解释这一点,或者即使它是正确的做法!

如果我做 :

#dataset shape is (50k, 3072)
plt.hist(mydataset.reshape(-1,32*32*3))
#and testset which is (10K,3072)
plt.hist(mytestset.reshape(-1,32*32*3))

这就是我得到的:
在此处输入图像描述 在此处输入图像描述

所以这对我来说非常令人费解,我不知道该怎么做!由于有 10 个垃圾箱,它是否给了我每个类的分布(cifar10 为 10 个类)?如果是这样,为什么当我尝试获取单个图像的分布时会得到相同的形状?
我的意思是当我尝试这样做时:

#image is of shape (1,3072)
plt.hist(mytestset[0])

这就是我得到的: 在此处输入图像描述

有趣的是,整个测试集的直方图如下所示:

#dataset shape is (10k,32,32,3)
plt.hist(mytestset.reshape(-1,32*32*3))

在此处输入图像描述 为什么我也会为单个图像获得十个 bin?
那么每个轴是什么意思呢?
在图像/数据集分发方面我应该寻找什么?
它只是整个数据集的原始值吗?
还是每个类的原始值?甚至每个图像?

1个回答

我想查看特定图像或数据集的分布,看看它们是否不同。这行得通吗?

这取决于您想了解或了解您的数据的内容。

那么每个轴是什么意思呢?

在您的所有绘图中,x 轴的范围为0-255,这是因为在所有绘图中,您正在创建图像的各个像素值的直方图。单个像素由三个值的向量(元组)组成:(red, green, blue). 这三种颜色中的每一种都可以取一个值0255通常是一个无符号的 8 位整数)因此,通过在图像上创建直方图,您实际上是在计算每个可能值出现的次数。

因此,这些图可以告诉您有关平均颜色分布的信息。每个图的峰值似乎在 100 左右,所以我猜有很多混合颜色 - 颜色的 RGB 值在 100 - 150 范围内。所以更少的像素是纯粹的 reg、绿色或蓝色,例如(0 , 0, 255) 将是纯蓝色。

您还可以使用 OpenCV library 计算/可视化颜色的直方图,它具有很好的功能来完成这种事情(并且运行速度比matplotlib直方图方法快,因为 OpenCV 使用 C++ 后端库)。看看这个很棒的演练


为什么我也会为单个图像获得十个 bin?

您的所有直方图都有 10 个 bin 的原因是因为您没有为 的bins参数plt.hist指定值,因此默认值取自 的基本配置matplotlib,您可以通过运行以下命令查看:

print(plt.rcParams["hist.bins"])    # will print 10 by default

这两个图上的 y 轴确实有意义。与 10k 数据集相比,具有 50k 图像的数据集的每个像素值的计数更高。


在图像/数据集分发方面我应该寻找什么?

它只是整个数据集的原始值吗?还是每个类的原始值?甚至每个图像?

对于您使用的任何数据集,每个图仅显示原始值的分布。您使用mtdatasetandmytestset作为输入,因此在每种情况下,您当然只能看到这些图像的分布。例如,任何地方都没有包含实际标签,因此您不会将分布分解为目标类。只考虑原始像素值。


在图像/数据集分发方面我应该寻找什么?

这是特定于问题的。

您可能希望看到确实存在 RGB 值的分布,作为一个健全的检查,您没有一些真正倾斜的彩色图像集,例如大部分是黑色或白色的。您可以将训练集和测试集的分布相互比较,以确保它们相似——这意味着训练集确实代表了测试集。如果不是这种情况,您可能在特定任务上训练的任何模型都可能会偏向训练集并且在测试集上表现不佳(如果分布非常不同,它不会看到与测试集相似的图像!)

对于使用图像训练神经网络,通常将像素值的分布归一化到 range [-1, +1],这有助于通过更平滑的梯度更新来更平滑地学习。