【问题标题】:Chainer, why does my model expect **array** of images?Chainer,为什么我的模型需要 **array** 图像?
【发布时间】:2017-10-03 00:39:46
【问题描述】:

我编写了一个非常简单的玩具链模型:

class Upscale(chainer.Chain):
def __init__(self):
    super(Upscale, self).__init__(
        d1=L.Deconvolution2D(3, 40, 4, stride=2),
        c1=L.Convolution2D(40, 3, 4)
        )


def __call__(self, x, test=False):
    h = self.c1(self.d1(x))
    return h

我可以调用它,它似乎工作。但是,我必须这样称呼它:

model = Upscale()
...
xp = cuda.cupy
...
image = xp.zeros((1, 3, 768, 1024), dtype=xp.float32)
image[0] = load_image("foo.jpg", xp)
...
y = model(image[0:1])

供参考,load_image 为:

def load_image(path, xp):
image = Image.open(path).convert('RGB')
return xp.asarray(image, dtype=xp.float32).transpose(2, 0, 1)

我的模型将接受数组形状 (1, 3, 768, 1024) 但不接受数组形状 (3, 768, 1024)。我不明白为什么会这样。或者,如何编写一个接受单个图像的链接器模型会有所帮助。我得到的错误是:

Traceback (most recent call last):
  File "upscale.py", line 92, in <module>
    main()
  File "upscale.py", line 68, in main
    y0 = model(image, test=True)
  File "upscale.py", line 21, in __call__
    h = self.c1(self.d1(x))
  File "/usr/local/lib/python2.7/dist-packages/chainer/links/connection/deconvolution_2d.py", line 116, in __call__
    deterministic=self.deterministic)
  File "/usr/local/lib/python2.7/dist-packages/chainer/functions/connection/deconvolution_2d.py", line 332, in deconvolution_2d
    return func(x, W, b)
  File "/usr/local/lib/python2.7/dist-packages/chainer/function.py", line 189, in __call__
    self._check_data_type_forward(in_data)
  File "/usr/local/lib/python2.7/dist-packages/chainer/function.py", line 273, in _check_data_type_forward
    self.check_type_forward(in_type)
  File "/usr/local/lib/python2.7/dist-packages/chainer/functions/connection/deconvolution_2d.py", line 50, in check_type_forward
    x_type.shape[1] == w_type.shape[0]
  File "/usr/local/lib/python2.7/dist-packages/chainer/utils/type_check.py", line 487, in expect
    expr.expect()
  File "/usr/local/lib/python2.7/dist-packages/chainer/utils/type_check.py", line 449, in expect
    '{0} {1} {2}'.format(left, self.inv, right))
chainer.utils.type_check.InvalidType:
Invalid operation is performed in: Deconvolution2DFunction (Forward)

Expect: in_types[0].ndim == 4
Actual: 3 != 4

【问题讨论】:

  • 你可以为你的图片添加一个额外的维度

标签: chainer


【解决方案1】:

在我的环境中,我确认以下代码可以正常工作。 请告诉我 print(image.shape)、print(image[0].shape) 和 print(image[0:].shape) 的结果。 我也想知道你的chainer版本。

import cupy
from PIL import Image
import chainer.links as L
import chainer


def load_image(path):
    image = Image.open(path).convert('RGB')
    return cupy.asarray(image, dtype=cupy.float32).transpose(2, 0, 1)

image = cupy.zeros((1, 3, 768, 1024), dtype=cupy.float32)
image[0] = load_image("foo.png")
print(image[0].shape)  # (3, 768, 1024)
print(image.shape)  # (1, 3, 768, 1024)
print(image[0:1].shape)  # (1, 3, 768, 1024)

class Upscale(chainer.Chain):
    def __init__(self):
        super(Upscale, self).__init__(
            d1=L.Deconvolution2D(3, 40, 4, stride=2),
            c1=L.Convolution2D(40, 3, 4)
        )


    def __call__(self, x, test=False):
        h = self.c1(self.d1(x))
        return h

model = Upscale()
model.to_gpu()
y = model(image[0:1])  # work

【讨论】:

  • 我可能不够精确。但我的问题是:对于您的样本,为什么 y = model(image[0]) 不起作用? Chainer 似乎需要一个数组来存储图像。
  • 大部分chainer函数和层,输入数组的第一个维度必须是mini-batch的维度。反卷积层的输入数组的形状应该是(N,c,h,w)。 N=小批量大小,c=通道大小,h=图像高度,w=图像宽度。如果要输入 1 张图片,则应构建包含 1 张图片的 mini-batch。
  • 好的,约定是接收小批量,额外维度是小批量。很公平。
猜你喜欢
  • 1970-01-01
  • 2016-03-20
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 2019-06-22
  • 2016-09-29
  • 2015-11-28
  • 2019-05-24
相关资源
最近更新 更多