Делает ли нарезка ND4J копию исходного массива?

Нарезка ND4J INDArray достигается с помощью одного из перегруженных методов get(), как указано в java - Получить произвольный фрагмент массива Nd4j - Qaru QaruSite. Поскольку INDArray берет непрерывный блок собственной памяти, создает ли нарезка с использованием get() копию исходной памяти (особенно нарезка строк, при которой можно создать новый INDArray с той же резервной памятью)?

Я нашел еще один INDArray способ subArray(). Имеет ли это значение?

Я спрашиваю об этом, потому что пытаюсь создать DatasetIterator, который может напрямую извлекать данные из INDArray, и я хочу устранить возможные накладные расходы. В исходном коде слишком много абстракции, и я не смог найти реализацию самостоятельно.

Аналогичный вопрос о NumPy задается в python - Numpy: просмотры против копирования путем нарезки – 2 Ответа, а ответ можно найти в Индексирование — Руководство NumPy v1.16:

Эмпирическое правило здесь может быть таким: в контексте индексации lvalue (т. е. индексы помещаются в значение левой части присваивания) представление или копия массива не создаются (потому что в этом нет необходимости). Однако с обычными значениями применяются приведенные выше правила создания представлений.


person Shreck Ye    schedule 11.05.2019    source источник


Ответы (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 и исходным массивом (таким образом, изменения в одном не повлияют на другой).

person David Tóth    schedule 13.05.2019