numpy-подобный пакет для узла

В течение моих лет разработки Python я всегда был поражен тем, насколько намного быстрее, если вам удастся переписать этот код, который зацикливается на вашем ndarray и что-то делает, с функциями numpy, которые работают на весь массив сразу. Совсем недавно я переключаюсь все больше на узел, и я ищу что-то подобное. До сих пор я обнаружил некоторые вещи, ни один из которых не выглядит многообещающим:

  • scikit-node, запускает scikit-learn в python и взаимодействует с узлом. Я не пробовал, но я не ожидаю, что это даст мне самую высокую скорость, которую я бы хотел.
  • Есть несколько довольно старых и новых, javascript матричных библиотек (sylvester, gl-matrix ,...). В дополнение к тому, что они не уверены, что они хорошо работают с матрицами размером больше 4x4 (что наиболее полезно при 3D-рендеринге), они, похоже, являются встроенным javascript (и некоторые, не уверенные в этом, используют ускорение webGL). Отлично в браузере, а не на узле.

Насколько я знаю, npms можно записать в C++, поэтому мне интересно, почему нет нумероподобных библиотек для узла. Недостаточно ли интерес к узлу из сообщества, которому нужна такая власть? Есть ли надежда, что функции ES6 (понимание списков) позволят компиляторам javascript автоматически индексировать собственный JS-код на скорости C++? Возможно, мне что-то не хватает?

Изменить, в ответ на близкие голоса: Заметьте, я не прошу "что такое лучший пакет для xyz". Мне просто интересно, есть ли техническая причина, по которой нет пакета для этого на узле, социальной причины или вообще нет причин, и есть только пакет, который я пропустил. Возможно, чтобы избежать слишком многих упрямых критиков, я хочу знать: у меня около 10000 матриц, которые 100 х 100 каждый. Какой лучший (* исправление, разумный быстрый) способ добавить их вместе?

Edit2 После еще нескольких копаний выяснилось, что я искал неправильную вещь. Google для "node.js научных вычислений" и есть ссылки на некоторые очень интересные заметки:

В принципе, насколько я понимаю, до сих пор никто не беспокоился. Кроме того, поскольку в js TypedArrays (например, 64bit ints) есть некоторые основные упущения, может быть сложно добавить хорошую поддержку, просто используя NPM, а не взламывать сам движок - что-то, что может победить цель. Опять же, я больше не изучал это последнее утверждение.

Ответ 1

Нет, нет никаких технических причин, по которым для Node.js и, в более общем смысле, JavaScript, не существует многоподобного пакета.

Существует два основных препятствия, мешающие Node.js и JavaScript получать больше разума в науках о данных и числовых вычислительных сообществах.

Первым препятствием является сообщество. Хотя сообщество JavaScript огромно, подмножество людей в этом сообществе, занимающееся интересными вещами в числовых вычислениях, невелико. Следовательно, если вы хотите делать числовые вычисления в JavaScript и Node.js, поиск ресурсов, которые помогут вам на этом пути, может быть трудным, и это может показаться одиноким делом.

Далее, отсутствие сопоставимых библиотек (курица и яйцо: библиотеки необходимы для привлечения авторов библиотек, и авторы должны писать хорошие библиотеки). Нет никаких технических причин, по которым библиотеки не могут быть написаны на JavaScript или использовать Node.js (например, через собственные надстройки). Я знаю, поскольку я написал много числовых вычислительных библиотек в JavaScript. Поэтому, хотя числовые вычисления возможны в JavaScript, проблема связана с невозможностью привлечь разработчиков, обладающих достаточным опытом и способных вложить время и усилия, необходимые для написания высококачественных числовых вычислений.

Что касается особенностей языка, упомянутых в OP:

  • ES6/ES2015: ни одно из последних языковых дополнений не помогает или препятствует разработке числовых вычислительных библиотек в JavaScript. Потенциальные дополнения, такие как списки, не будут также изменяться. Одно изменение на веб-платформу, которое будет иметь значение, - WebAssembly. С помощью WebAssembly упрощается компиляция библиотек C/C++/Fortran для работы в веб-браузерах. Во время этого ответа WebAssembly выглядит как средство для переноса SIMD в Интернет, что потенциально может привести к некоторым ускорениям, хотя фокус, похоже, на коротком SIMD, а не надолго. Но даже с помощью WebAssembly перенос числовых вычислительных библиотек в Интернет не будет таким простым, как нажатие кнопки компиляции. Числовые вычислительные базы кода должны быть массированы, чтобы стать пригодными для использования в Интернете, и даже тогда API-интерфейсы более высокого уровня, вероятно, должны быть записаны для маскировки некоторых функций более низкого уровня, таких как ручное управление кучей.
  • Нативные надстройки: да, узловые модули могут быть записаны как собственные надстройки, что позволяет использовать код C/C++/Fortran в приложении Node.js. У людей есть письменные библиотеки с этой целью; например, см. stdlib. Если все сделано хорошо, Node.js может выполнять числовые вычисления со скоростью, сравнимой с непосредственным использованием собственных реализаций.
  • Типизированные массивы: как и сейчас, они подходят для числовых вычислений. Подобно C, вы можете создавать объединенные буферы, которые позволяют эффективно использовать память и повышать производительность. Кроме того, подобно языкам R, Python и Julia, вы можете использовать типизированные массивы для создания интерфейсов ndarray (aka strided array). В то время как массивы с целыми числами U/Int64 в настоящее время недоступны на момент ответа, (а) их отсутствие не является пробной пробкой, и (б) предложения продвигаются на уровне спецификации, чтобы добавить массивы с целыми числами U/Int64 к JavaScript. То же самое для сложных чисел со структурированными типами.

Мое личное убеждение состоит в том, что некоторая форма числовых вычислений неизбежна в JavaScript и Node.js. Преимущества (вездесущность, распределение, производительность) и потенциальные приложения (краевые вычисления, интеграция машинного обучения, визуализация данных) слишком сильны в эволюционных силах, которые не поддерживают приложения для научных исследований данных, по крайней мере на базовом уровне.

раскрытие: В настоящее время я и другие работают над проектом (https://github.com/stdlib-js/stdlib), целью которого является предоставление числовых вычислительных средств в JavaScript и Node.js.

Ответ 2

Большинство работы с узлами, по-видимому, находятся в веб-хранилище "полный стек", причем гораздо меньше делается в тех областях, где быстрое числовое преобразование является преимуществом.

В областях, где быстрое числовое преобразование является преимуществом, Python, R и т.д., Вероятно, имеют доминирующий ум.

Объедините эти два факта, и в итоге у вас не так много людей, которые вкладывают усилия в числовые библиотеки обработки узлов.

Ответ 3

Я не пробовал это, но нашел узлопакет. Поскольку Numpy получает большую часть своей скорости от использования blas/lapack, чтобы делать все, это должно помочь. Из readme похоже, что у него тоже есть объект массива, что существенно для того, чтобы не конвертировать между JS и lapack при каждой операции.

Вот часть их демо:

var lapack = require('lapack');

var result = lapack.sgeqrf([
    [1, 2, 3],
    [3, 4, 5],
    [5, 6, 7]
]);

console.log(result.R);
console.log(result.tau);

result = sgesvd('A', 'A', [
    [1, 2, 3],
    [3, 4, 5],
    [5, 6, 7]
]);

console.log(result.U);
console.log(result.S);
console.log(result.VT);

result = lapack.sgetrf([
    [1, 2, 3],
    [3, 4, 5],
    [5, 6, 7]
]);

// see the readme for more

Это, по-видимому, довольно прямой интерфейс для lapack с использованием тех же имен, поэтому в этом отношении он не так удобен, как Numpy, но по крайней мере он заботится о размерах массива и материалах и должен быть примерно таким же быстрым (поскольку большая часть работы делаются с помощью Lapack в любом случае).

Однако это не будет работать в браузере, что означает, что везде, где это доступно, возможно, Python также доступен. Лично я бы придерживался Python, который намного более доминирует для численного материала, если нет какой-то конкретной функции Node Python отсутствует...

Ответ 4

Хотя я никогда не пробовал, NumJs выглядит действительно круто! Это очень убедительная попытка клонирования javascript NumPy.

Это то, что я буду использовать, будь то только для удобства вещательных операций.

Ответ 5

Вот Google https://deeplearnjs.org/#getting-started, который делает именно это, и имеет встроенные возможности для обучения глубоких нейронных сетей на графических процессорах с использованием WebGL. Вы также можете переносить модели Tensorflow на https://deeplearnjs.org/demos/mnist/mnist.html

Не обманывайте себя, думая, что это только для глубокого обучения. Это полноценная вычислительная платформа с встроенным ускорением gpu. Это следует за нетерпеливой моделью "выполнить, когда вы идете", например numpy (и Tensorflow Eager и PyTorch и т.д.), А не модель "define then run", например Tensorflow. Таким образом, будет естественным использовать любого, кто раньше использовал numpy.

Вот очень информативный репортаж github:

https://github.com/PAIR-code/deeplearnjs

Ответ 7

В том же духе @Julius ответ на вопрос deeplearn.js, tensorflow.js является продолжением того же проекта. Чтобы поиграть с модулем tensorflow в REPL, я установил его глобально (FYI - обычно рекомендуется не делать этого), используя это:

$ npm install --global @tensorflow/tfjs

Затем я запустил $ node чтобы запустить узел REPL.

Это может отличаться для вас (особенно если вы решили установить localhost) локально, но я ввел это для ссылки на модуль tensorflow:

var tf = require('/usr/local/lib/node_modules/@tensorflow/tfjs')

Чтобы создать тензор ранга 1 (эквивалентно 1-мерному массиву в numpy), попробуйте:

var x = tf.tensor( [-3,4] )

И соберите его с:

x.square().print()

Вы должны получить [9,16] для вашего вывода. Подробнее см. Https://js.tensorflow.org.

Я бы сказал, что tensorflow.js является не только заменой JS для numpy, но также и для sklearn, keras и, конечно, тензорным потоком.