【发布时间】:2016-05-14 22:13:30
【问题描述】:
问题的一些背景:
我正在尝试优化自定义神经网络代码。 它严重依赖循环,我决定使用 cython 来加快计算速度。
我遵循了通常的在线提示:使用适当的 cdef 声明所有局部变量并关闭 boundscheck 和 nonecheck。这几乎没有给我 10% 的性能。
嗯,我的代码依赖于很多类成员。因此,我决定将整个类转换为 cdef 类。事实证明,cython 不允许 numpy ndarrays 作为类成员的类型。相反,必须使用内存视图。 不幸的是,这两种类型似乎非常不兼容。
我已经遇到过这个问题:Cython memoryview transpose: Typeerror
总结一下:您可以将 np.ndarray 存储在内存视图中。您可以转置它并将返回的数组存储在 memview 中。但如果该 memview 是类成员,则不是。然后,您必须创建一个中间 memview,将结果存储在其中并将中间 memview 分配给类成员。
这是代码(非常感谢 DavidW)
def double[:,:,:,:] temporary_view_of_transpose
# temporary_view_of_transpose now "looks at" the memory allocated by transpose
# no square brackets!
temporary_view_of_transpose = out_image.transpose(1, 0, 2, 3)
# data is copied from temporary_view_of_transpose to self.y
self.y[...] = temporary_view_of_transpose # (remembering that self.y must be the correct shape before this assignment).
现在我遇到了一个新问题。 上面的代码来自所谓的“前向传递”。还有一个相应的反向传递,它反向执行所有计算(用于分析梯度)。
这意味着对于向后传递,我必须转置 memoryview 并将其存储在一个 numpy 数组中:
cdef np.ndarray[DTYPE_t, ndim=4] d_out_image = self.d_y.transpose(1, 0, 2,3)
d_y 必须是类成员,因此它必须是内存视图。 Memoryviews 不允许转置。他们有一个 .T 方法,但这对我没有帮助。
实际问题:
- 如何正确地将 numpy 数组存储为 cdef 类的类成员?
- 如果答案是:“作为内存视图”,我该如何转置内存视图?
【问题讨论】:
标签: python c++ numpy cython conv-neural-network