slice - ND4J 切片是否会复制原始数组?
问题描述
ND4JINDArray
切片是通过javaget()
中回答的一种重载方法实现的- 获取 Nd4j 数组的任意切片 - 代码日志。作为INDArray
一个连续的本机内存块,使用切片是否get()
会复制原始内存(尤其是行切片,其中可以创建一个INDArray
具有相同后备内存的新内存)?
我找到了另一种INDArray
方法subArray()
。这个有什么区别吗?
我问这个是因为我正在尝试创建一个DatasetIterator
可以直接从INDArray
s 中提取数据的程序,并且我想消除可能的开销。源代码中有太多抽象,我自己找不到实现。
在python - Numpy: views vs copy by slicing - Stack Overflow中提出了一个关于 NumPy 的类似问题,答案可以在Indexing - NumPy v1.16 Manual中找到:
这里的经验法则可以是:在左值索引的上下文中(即索引放置在赋值的左侧值中),不创建数组的视图或副本(因为没有必要)。但是,对于常规值,上述创建视图的规则确实适用。
解决方案
简短的回答是:不,它尽可能使用参考。要进行复制,.dup()
可以调用该函数。
引用https://deeplearning4j.org/docs/latest/nd4j-overview
视图:当两个或多个 NDArray 引用相同的数据时
ND4J 中的一个关键概念是两个 NDArrays 实际上可以指向内存中相同的底层数据。通常,我们有一个 NDArray 引用另一个数组的某个子集,并且这只发生在某些操作中(例如 INDArray.get()、INDArray.transpose()、INDArray.getRow() 等。这是一个强大的概念,并且一个值得理解的。
这样做的主要动机有两个:
有相当大的性能优势,尤其是在避免复制数组方面我们在如何对 NDArray 执行操作方面获得了很多能力考虑一个简单的操作,例如在大型 (10,000 x 10,000) 矩阵上进行矩阵转置。使用视图,我们可以在恒定时间内执行此矩阵转置,而无需执行任何复制(即大 O 表示法中的 O(1)),从而避免复制所有数组元素的巨大成本。当然,有时我们确实想要制作一个副本——此时我们可以使用 INDArray.dup() 来获取一个副本。例如,要获取转置矩阵的副本,请使用 INDArray out = myMatrix.transpose().dup()。在此 dup() 调用之后,原始数组 myMatrix 和数组 out 之间将没有链接(因此,对其中一个的更改不会影响另一个)。
推荐阅读
- xpath - 我可以在 xpath 的 contains() 函数中使用 OR 运算符吗?
- python - 根据创建日期使用 JIRA Rest API 提取数据时出错
- node.js - 在终端上运行节点安装命令的问题
- linux - 从 McPat 输出到另一个目录不起作用
- cordova - 尝试在 ionic 4 项目中安装时出现@ionic/storage npm 安装错误
- c# - 更新父表时更新子表的最佳方法是什么?
- c++ - 我的模板类方法返回错误类型?
- html - 无法从 Swift 中较大的多行字符串中提取子字符串
- javascript - 获取获取内容?
- c - 理解和操作指向整数数组的指针