ND4J切片会复制原始阵列吗?

时间:2019-05-11 17:17:06

标签: slice deeplearning4j dl4j nd4j

ND4J INDArray切片是通过java - Get an arbitrary slice of a Nd4j array - Stack Overflow中回答的一种重载get()方法实现的。由于INDArray占用了连续的本机内存块,因此使用get()进行切片会生成原始内存的副本(尤其是行切片,在其中可以使用以下方法创建新的INDArray):相同的后备内存)?

我找到了另一种INDArray方法subArray()。这有什么区别吗?

之所以这样问,是因为我试图创建一个DatasetIterator来直接从INDArray中提取数据,并且我想消除可能的开销。源代码中的抽象太多,我自己找不到实现。

python - Numpy: views vs copy by slicing - Stack Overflow中提出了有关NumPy的类似问题,而答案可以在Indexing — NumPy v1.16 Manual中找到:

  

这里的经验法则可以是:在左值索引的上下文中(即,索引位于分配的左侧值中),不会创建数组的视图或副本(因为不需要)。但是,对于常规值,上述创建视图的规则确实适用。

1 个答案:

答案 0 :(得分:1)

简短的答案是:不,它在可能的情况下使用引用。要进行复制,可以调用.dup()函数。

引用https://deeplearning4j.org/docs/latest/nd4j-overview

  

视图:当两个或多个NDArray引用同一数据时

     

ND4J中的一个关键概念是两个NDArray实际上可以指向相同的事实   内存中的基础数据。通常,我们有一个NDArray指向   另一个数组的某些子集,仅在某些情况下会发生   操作(例如INDArray.get(),INDArray.transpose(),   INDArray.getRow()等。这是一个功能强大的概念,   值得理解。

     

有两个主要动机:

     

具有显着的性能优势,尤其是避免   复制阵列我们在执行性能方面获得了很多能力   我们的NDArrays上的操作考虑一个像矩阵这样的简单操作   转置在大(10,000 x 10,000)的矩阵上。使用视图,我们可以   在恒定时间内执行此矩阵转置而无需执行任何操作   复制(即O(1)为大O表示法),从而避免了可观的成本   复制所有数组元素。 当然,有时候我们确实想   进行复制-此时,我们可以使用INDArray.dup()获得一个   复制。例如,要获取转置矩阵的副本,请使用INDArray   out = myMatrix.transpose()。dup()。在此dup()调用之后,将有   原始数组myMatrix和数组out之间没有链接(因此,   更改一个不会影响另一个)。