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中找到:
这里的经验法则可以是:在左值索引的上下文中(即,索引位于分配的左侧值中),不会创建数组的视图或副本(因为不需要)。但是,对于常规值,上述创建视图的规则确实适用。
答案 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之间没有链接(因此, 更改一个不会影响另一个)。