【问题标题】:ValueError: all input arrays must have the same shape (Machine Learning)ValueError:所有输入数组必须具有相同的形状(机器学习)
【发布时间】:2019-03-22 13:47:14
【问题描述】:

我的一项机器学习作业有问题。我们被要求使用机器学习来估计给定图像的个人的年龄。我们得到了一个包含 28360 个训练图像和 7090 个测试图像的数据集。

我遇到的问题是在我的代码的 sn-p #3 中,可以找到 HERE :) 特别是,我收到了ValueError: all input arrays must have the same shape。就像我上面提到的,我的火车数据集的大小为 28360。运行程序后,我可以从 temp.append(img)print(len(temp)) 再次给我,28360。也许我没有全面了解究竟是什么np.stack(temp) 正在做或如何工作,但我的初始和最终数组的大小似乎相同,为什么会出现问题。?

四处询问,我被告知问题不一定与我的temp 列表的长度有关,而是我可能遇到了与其他人不同大小的图像。包含的一个或多个调整大小的图像(它们是数组)具有不同的形状,可能是因为调整大小失败或图像丢失或其他原因。如果是这种情况,如何在 28360 张图像的数据集中找到哪些不同以及为什么要修复它们或删除它们。这真的是问题吗,还是其他原因?

任何人,请帮忙。我究竟做错了什么?任何 cmets/建议将不胜感激。先感谢您。干杯和美好的一天。! :D

【问题讨论】:

  • 当您遇到错误时,您应该告诉我们它发生在哪里。这可能需要显示部分或全部回溯。但是错误是np.stack 在尝试加入的数组形状不同时引发的那种事情。这意味着您需要查看数组列表并找到形状不同的数组。你知道如何查看数组的shape吗?
  • 所以错误出现在我的源代码的第45行。我还包括了上面的所有引用,但 HERE 又是这样。为了找到数组的形状,我使用了类似于print('test x shape:', test_x.shape) 的东西,对吗?不过有点迷茫。 “查看数组列表并找到形状不同的数组”是什么意思?再次感谢您的迅速回复。
  • [x.shape for x in temp] 应该列出temp 列表中所有元素的形状。 (我们倾向于使用复制粘贴到文本而不是链接的代码和回溯。但是 pastebin 链接比屏幕截图更好。我看到了您的链接但没有检查它,并且没有意识到它包含追溯。)

标签: python numpy tensorflow machine-learning numpy-ndarray


【解决方案1】:

你知道问题所在,有些图像很痛苦,我猜你必须调试。尝试每次执行 np.stack() 并找出出错的地方。当堆栈不再工作时,将打印所有图像的形状,这可能会让您知道出了什么问题。由于我无法重现它,因此无法进一步提供帮助。 np.stack 将所有图像连接在一起,但因此每个 image.shape 必须相同。

for image_name in train.Id:
    img_path = os.path.join(data_dir, 'train', img_name)
    img = imageio.imread(img_path)
    img = skimage.transform.resize(img, (32, 32), mode='constant')
    img = img.astype('float32') # this will help us in later stage
    temp.append(img)
    try:
        train_x = np.stack(temp)
    except ValueError:
        [print(im.shape) for im in temp]
        break

为了让您更好地使用 np.stack,请考虑以下代码:

tmp = [np.zeros((400,400,3)), np.zeros((400,400,3))]
print(np.stack(tmp).shape)
>>> (2, 400, 400, 3)

tmp = [np.zeros((400,400,3)), np.zeros((400,400))]
print(np.stack(tmp).shape)
>>> ValueError: all input arrays must have the same shape

在第一个示例中,我有一个包含两个 3D 数组的列表,它们的形状完全相同。 Numpy 将它们堆叠在一起并创建一个新维度,通常称为批量大小。在第二个中,我在列表中有一个 3D 和一个 2D 数组,当您尝试堆叠具有不同形状 (400, 400, 3) 与 (400, 400) 的两个数组时,您会得到您提到的 ValueError。

我还冒昧地查看了 skimage 文档here
在返回时您可以看到以下内容:

img_array : ndarray 不同的颜色波段/通道存储在三维中,因此灰度图像为 MxN,RGB 图像为 MxNx3,RGBA 图像为 MxNx4。

我感觉您的某些图像被读取为 MxNx4 数组而不是 MxNx3

希望对我有所帮助,请随时向我提问。

编辑

for image_name in train.Id:
    img_path = os.path.join(data_dir, 'train', img_name)
    img = imageio.imread(img_path)
    img = skimage.transform.resize(img, (32, 32), mode='constant')
    img = img.astype('float32') # this will help us in later stage
    if len(img.shape) == 3 and img.shape[-1] == 3  # only append if 3D and last dimension is a 3, standing for RGB
        temp.append(img)
train_x = np.stack(temp)

【讨论】:

  • 感激不尽!你真的把整个问题放在眼里。无论如何,运行以下代码 sn-p 确实按照您的建议在调用 break 语句时给了我一个 (32, 32) 的数组。我想我不明白我遇到的问题的原因之一仅仅是因为我认为在调用实现 Skimage 时默认情况下第三维是“3”。使用您提供的 Skimage 文档,我可以返回并将附加到该数组形状的图像名称归因于确认。果然,我拉出了一张灰色图像。
  • 现在不能这样做,因为课程将在几分钟后开始,我相信它需要几分钟才能处理,但我希望以 img = skimage.transform.resize(img, (32, 32, 3), mode='constant') 运行它会修复我的问题。再次感谢您!
  • 显然您可以通过这种方式将灰度图像升级为 3D 图像,但不确定这种升级是否值得信赖。通常最好确切地了解您的数据的外观,而不是混合灰度和 RGB 图像。我将编辑我的代码并为您提供解决方法。
猜你喜欢
  • 1970-01-01
  • 2016-12-15
  • 1970-01-01
  • 2019-09-22
  • 2018-06-12
  • 2017-06-18
  • 2018-05-18
  • 2018-06-23
  • 2017-07-13
相关资源
最近更新 更多