一些背景的问题:用Cython:移调memoryview
我试图优化定制的神经网络代码。 它很大程度上依赖循环,我决定使用cython来加速计算。
我按照常规的在线技巧:用适当的cdefs声明所有本地变量并关闭边界检查和非检查。这几乎没有给我10%的表现。
那么,我的代码依赖于许多类的成员。所以我决定把整个班级转换成一个cdef班级。原来,cython不允许numpy ndarrays作为类成员的类型。相反,人们必须使用记忆体。 不幸的是,这两种类型似乎极不相容。
我已经遇到了这样的问题:Cython memoryview transpose: Typeerror
概括起来:你可以存储np.ndarray在memoryview。您可以转置它并将返回的数组存储在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必须是一个类的成员,因此它必须是一个memoryview。 Memoryviews不允许转置。他们有一个.T方法,但这对我没有帮助。
实际问题:
- 如何正确地存储numpy的数组作为CDEF类中的一个成员?
- 如果答案是:“作为一个内存视图”,我该如何转置一个内存视图?
这看起来像个好主意。再一次,我会尽快检查我的家。感谢您的快速回答 – lhk
作品,谢谢 – lhk