为什么在 PyCaffe 中将 ndarray 分配给 ndarray 会引发属性错误?
Why does assigning an ndarray to an ndarray in PyCaffe raise an Attribute Error?
在阅读 Caffe 教程 (http://nbviewer.ipython.org/github/BVLC/caffe/blob/master/examples/00-classification.ipynb) 时,我遇到了以下语句:
net.blobs['data'].data[...] = transformer.preprocess('data',
caffe.io.load_image
(caffe_root + 'examples/images/cat.jpg'))
它基本上用于将单个图像分配给 net.blobs['data'].data
。
net.blobs['data'].data[...]
是 4D ndarray,transformer...
returns 是 3D ndarray,因此省略号用于在第 0 轴上复制 3D 数组。这让我觉得我应该能够重写代码以避免省略号如下:
z3=transformer.preprocess('data',
caffe.io.load_image
(caffe_root + 'examples/images/cat.jpg'))
z4 = z3[np.newaxis,...]
net.blobs['data'].data = z4
但是,当我这样做时,我得到
>> net.blobs['data'].data = z4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
尽管如此,
net.blobs['data'].data[...] = z3
工作正常。这对任何人都有意义吗?
我已经验证了变量的形状和类型,如下所示:
>>> print net.blobs['data'].data.shape, z3.shape, z4.shape
(1, 3, 227, 227) (3, 227, 227) (1, 3, 227, 227)
>>> print type(net.blobs['data'].data),type(z3),type(z4)
<type 'numpy.ndarray'> <type 'numpy.ndarray'> <type 'numpy.ndarray'>
为什么 net.blobs['data'].data = z4
会导致问题?
执行 obj.attr = blah
是在对象 obj
上设置一个属性,因此 obj
控制它。执行 obj.attr[...] = blah
是在 obj.attr
引用的对象上设置一个 item(例如,某些类似数组的对象的 "contents"),因此对象 obj.attr
控制这个。
在您的示例中,net.blobs['data']
是某种不允许设置其 data
属性的对象,因此您不能执行 net.blobs['data'].data = blah
。但是 net.blobs['data'].data
是一个数组, 确实 允许您更改其内容,因此您可以 net.blobs['data'].data[...] = stuff
。您正在使用这两种语法对两个不同的对象进行操作(一种情况下为 net.blobs['data']
,另一种情况下为 net.blobs['data'].data
)。
第一种方法(net.blobs['data'].data = z4
)的问题在于'data'是net.blobs['data']的属性(即Caffe Blob object) 无法分配。如果将 numpy 数组分配给数据属性,则意味着 "instead of using the memory allocated for data, use the memory of the numpy array",这是 不可接受的 。
但是如果你使用 net.blobs['data'].data[...] = z4
,你的意思是 "copy the data from the numpy array to the memory allocated for the data attribute",这是 可以接受的。
更多信息,您可以阅读 Caffe 用户组中的 a similar question。
在阅读 Caffe 教程 (http://nbviewer.ipython.org/github/BVLC/caffe/blob/master/examples/00-classification.ipynb) 时,我遇到了以下语句:
net.blobs['data'].data[...] = transformer.preprocess('data',
caffe.io.load_image
(caffe_root + 'examples/images/cat.jpg'))
它基本上用于将单个图像分配给 net.blobs['data'].data
。
net.blobs['data'].data[...]
是 4D ndarray,transformer...
returns 是 3D ndarray,因此省略号用于在第 0 轴上复制 3D 数组。这让我觉得我应该能够重写代码以避免省略号如下:
z3=transformer.preprocess('data',
caffe.io.load_image
(caffe_root + 'examples/images/cat.jpg'))
z4 = z3[np.newaxis,...]
net.blobs['data'].data = z4
但是,当我这样做时,我得到
>> net.blobs['data'].data = z4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
尽管如此,
net.blobs['data'].data[...] = z3
工作正常。这对任何人都有意义吗?
我已经验证了变量的形状和类型,如下所示:
>>> print net.blobs['data'].data.shape, z3.shape, z4.shape
(1, 3, 227, 227) (3, 227, 227) (1, 3, 227, 227)
>>> print type(net.blobs['data'].data),type(z3),type(z4)
<type 'numpy.ndarray'> <type 'numpy.ndarray'> <type 'numpy.ndarray'>
为什么 net.blobs['data'].data = z4
会导致问题?
执行 obj.attr = blah
是在对象 obj
上设置一个属性,因此 obj
控制它。执行 obj.attr[...] = blah
是在 obj.attr
引用的对象上设置一个 item(例如,某些类似数组的对象的 "contents"),因此对象 obj.attr
控制这个。
在您的示例中,net.blobs['data']
是某种不允许设置其 data
属性的对象,因此您不能执行 net.blobs['data'].data = blah
。但是 net.blobs['data'].data
是一个数组, 确实 允许您更改其内容,因此您可以 net.blobs['data'].data[...] = stuff
。您正在使用这两种语法对两个不同的对象进行操作(一种情况下为 net.blobs['data']
,另一种情况下为 net.blobs['data'].data
)。
第一种方法(net.blobs['data'].data = z4
)的问题在于'data'是net.blobs['data']的属性(即Caffe Blob object) 无法分配。如果将 numpy 数组分配给数据属性,则意味着 "instead of using the memory allocated for data, use the memory of the numpy array",这是 不可接受的 。
但是如果你使用 net.blobs['data'].data[...] = z4
,你的意思是 "copy the data from the numpy array to the memory allocated for the data attribute",这是 可以接受的。
更多信息,您可以阅读 Caffe 用户组中的 a similar question。