用于节点的类似numpy的包[关闭]
Posted
技术标签:
【中文标题】用于节点的类似numpy的包[关闭]【英文标题】:numpy-like package for node [closed] 【发布时间】:2015-10-03 10:32:27 【问题描述】:在我从事 Python 开发的这些年里,我一直惊讶于如果你设法重写循环通过你的 ndarray 并执行某些操作的代码,并且使用在整个数组上工作的 numpy 函数,事情变得如此之快。一次。最近我越来越多地切换到节点,我正在寻找类似的东西。到目前为止,我发现了一些东西,但没有一个看起来很有希望:
scikit-node,在 python 中运行 scikit-learn,并与 node.js 接口。我没有尝试过,但我不认为它会给我带来我想要的最先进的速度。 有一些相当古老和更新的 javascript 矩阵库(sylvester、gl-matrix、...)。除了不确定它们是否能很好地处理大于 4x4 的矩阵(这在 3D 渲染中最有用)之外,它们似乎是原生 javascript(有些不确定,它们使用 webGL 加速)。在浏览器上很好,在节点上则不然。据我所知,npms 可以用 C++ 编写,所以我想知道为什么 node.js 没有类似 numpy 的库。需要这种权力的社区是否对节点没有足够的兴趣?是否有希望 ES6 特性(列表推导)允许 javascript 编译器自动将原生 JS 代码矢量化为 C++ 速度?我可能还缺少其他东西吗?
编辑,回应近距离投票:注意,我不是在问“什么是做 xyz 的最佳包”。我只是想知道是否有技术原因没有在节点上执行此操作的包、社会原因或根本没有原因,而我只是错过了一个包。也许为了避免太多自以为是的批评,我想知道:我有大约 10000 个矩阵,每个矩阵都是 100 x 100。将它们加在一起的最佳方法是什么(* 更正,合理的快速)?
编辑2 经过更多的挖掘,结果发现我在谷歌上搜索错误的东西。谷歌搜索“node.js 科学计算”,并有一些非常有趣的注释的链接:
https://cs.stackexchange.com/questions/1693/a-faster-leaner-javascript-for-scientific-computing-what-features-should-i-kee http://www.quora.com/Can-Node-js-handle-numerical-computation-the-same-way-that-languages-like-R-or-Julia-can Javascript and Scientific Processing?据我现在了解,基本上没有人打扰过。此外,由于 js TypedArrays 中存在一些重大遗漏(例如 64 位整数),因此仅使用 NPM 可能很难添加良好的支持,而不是破解引擎本身——这会破坏目的。再说一次,我没有进一步研究这最后的陈述。
【问题讨论】:
Edge 将支持 SIMD,如果这与您所说的完全接近的话。还可以检查 [].map(),它可以执行["A","B","c"].map(Function.call.bind("".toLowerCase))
之类的操作
据我所知,edge 是一个节点 - .net 桥,对吧?我不确定这有什么帮助。我熟悉 map() 函数调用,但在我的测试中,以这种方式将 2 个矩阵加在一起甚至达不到 numpy 做同样事情的速度(我可以想象;这一定很难弄清楚对于编译器来说,在合理的时间内发生了什么)。
asm 可以以大约 90% 的原始性能运行 llvm 代码。加载需要很长时间,但运行速度很快。使用 webassembly,加载时间将减少 90%,运行性能会略微提高。从现在开始,动态语言将比预编译代码更快,因为运行时优化考虑了编译器没有的输入,而其余的仍然是 JIT 和快速的。您还可以在不重新编译的情况下升级动态应用程序的性能(例如升级 V8),这是对较小且不断缩小的性能差异的权衡。
检查npmjs.com/package/numjsnumjs
因为 numjs 对我来说看起来像纯 javascript,我希望它只给你 numpy 接口,而不是速度。不过还没有测试过。
【参考方案1】:
我开始https://www.npmjs.com/package/@nexys/math-ts 一个非常简单轻巧的数字打字稿库/包
Github:https://github.com/Nexysweb/math-ts
【讨论】:
【参考方案2】:scijs 的 ndarray 也不错。 link
var mat = ndarray(new Float64Array([1, 0, 0, 1]), [2,2])
//Now:
//
// mat = 1 0
// 0 1
//
【讨论】:
【参考方案3】:numjs 是 nodejs 中类似 numpy 的库。
【讨论】:
【参考方案4】:这里是 Google 的 TensorFlow.js(以前的 https://deeplearnjs.org),它正是这样做的,并且具有使用 WebGL 在 GPU 上训练深度神经网络的能力。你也可以port TensorFlow models to it。
不要误以为这只是为了深度学习。它是一个成熟的数值计算平台,内置 GPU 加速。它遵循像 NumPy(和 Tensorflow Eager、PyTorch 等)那样急切的“随手执行”模型,而不是像 Tensorflow 这样的“定义然后运行”模型。因此,任何曾经使用过 NumPy 的人都会觉得它很自然。
这里是非常丰富的 Github 存储库:
https://github.com/tensorflow/tfjs-core(旧链接 https://github.com/PAIR-code/deeplearnjs 现在重定向到那里)
【讨论】:
好答案! deeplearn.js 现在称为 tensorflow.js,可以在 js.tensorflow.org 找到 这似乎是唯一(当前)合理的答案。所有其他关于库的建议似乎要么是实验性的,要么是用纯 JavaScript 编写的。 NumPy 的主要好处是它的核心是用 C 编写的,仅仅实现 NumPy 的 API 是没有意义的,你也想要性能提升。但我暂时猜测,就像 TensorFlow 是 Python 或 JavaScript 对 C++ 库的包装器一样,应该可以用 JavaScript API 包装 NumPy 的 C 代码。 这里是 Node.JS 的实现:github.com/tensorflow/tfjs-node 好吧,您仍然需要根据用例将张量写入 javascript 数组,因此很难推荐为张量功能实现整个 tf 库。有趣的是,这可能是不正确的,引擎可能使用动态指针来创建结构。 ***.com/a/61713477/11144990 这个库的问题在于它不是为无痛苦地随机访问张量而设计的。它是为在 GPU 上执行而设计的,因此所有张量都是在该 GPU(或 CPU,如果在本地运行)上创建的。这意味着您不能简单地触摸 Tensor3D 的元素 [3][4][5],您必须在没有承诺的情况下通过 Tensor3D.arraySync() 下载它,更改值,然后创建一个新的张量。 Yeeeouch。【参考方案5】:与@Julius 关于 deeplearn.js 的回答相同,tensorflow.js 是同一项目的延续。为了在 REPL 中使用 tensorflow 模块,我使用以下方法在全局范围内安装了它(仅供参考——通常建议不要这样做):
$ npm install --global @tensorflow/tfjs
然后,我运行$ node
来启动节点REPL。
这对你来说可能会有所不同(特别是如果你决定在本地安装 tensorflow),但我输入这个是为了引用 tensorflow 模块:
var tf = require('/usr/local/lib/node_modules/@tensorflow/tfjs')
要创建秩为 1 的张量(相当于 numpy 中的一维数组),请尝试:
var x = tf.tensor( [-3,4] )
然后将其平方:
x.square().print()
您的输出应该得到[9,16]
。详情请见https://js.tensorflow.org。
我想说 tensorflow.js 不仅是 numpy 的 JS 替代品,也是 sklearn、keras,当然还有 tensorflow 的替代品。
【讨论】:
是否有与 matplotlib 类似但适用于 JS 的矩阵/数组渲染器。我想如果能够使用 canvas 或 webgl 在浏览器中渲染数组(尤其是图像数组)会很酷。 是的,plotly.js 支持 webgl:codepen.io/destrada/pen/rmrGYL。在链接中,scattergl 用于根据数据制作散点图。 我已更新 @Julius 的答案以引用 TensorFlow.js【参考方案6】:我没有尝试过,但我找到了node-lapack。由于 Numpy 的大部分速度来自使用 blas/lapack 来完成所有操作,因此这应该会有所帮助。从自述文件看来它也有一个数组对象,这对于在每个操作中不在 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,它在数值方面更为占主导地位,除非 Python 缺少某些特定的 Node 功能......
【讨论】:
【参考方案7】:不,对于 Node.js 和更普遍的 JavaScript 不存在类似 numpy 的包没有技术原因。
有两个主要障碍阻碍 Node.js 和 JavaScript 在数据科学和数值计算社区中获得更多的思想份额。
第一个障碍是社区。尽管 JavaScript 社区很大,但在该社区中从事数字计算有趣事情的人却很少。因此,如果您想在 JavaScript 和 Node.js 中进行数值计算,那么在此过程中寻找资源来帮助您可能会很困难,而且可能会感觉像是一项孤独的工作。
其次,缺乏可比较的库(鸡和蛋:需要库来吸引库作者,并且需要作者来编写好的库)。库不能用 JavaScript 编写或利用 Node.js(例如,通过本机插件)没有技术原因。我知道,因为我用 JavaScript 编写了许多数值计算库。因此,虽然在 JavaScript 中可以进行数值计算,但问题在于无法吸引具有足够专业知识并能够投入时间和精力编写高质量数值计算实现的开发人员。
关于 OP 中提到的特定语言功能:
ES6/ES2015:最近添加的语言都没有帮助或阻碍 JavaScript 中数值计算库的开发。像列表推导这样的潜在添加也不会改变游戏规则。 WebAssembly 是对 Web 平台产生影响的一个变化。使用 WebAssembly,编译 C/C++/Fortran 库以在 Web 浏览器中运行将变得更加容易。在给出这个答案的时候,WebAssembly 看起来是将 SIMD 引入网络的手段,可能会允许一些加速,尽管重点似乎是短 SIMD,而不是长 SIMD。但即使使用 WebAssembly,将数值计算库移植到 Web 也不会像点击编译按钮那么简单。数字计算代码库需要经过修改才能在 Web 上使用,即使这样,也可能需要编写更高级别的 API 来掩盖一些较低级别的功能,例如手动管理堆。 原生插件:是的,节点模块可以编写为原生插件,允许在 Node.js 应用程序中使用 C/C++/Fortran 代码。个人为此编写了库;例如,请参阅stdlib。如果做得好,Node.js 可以以与直接使用本机实现相当的速度执行数值计算。 类型化数组:就像现在一样,它们适用于数值计算。与 C 类似,您可以创建池化缓冲区,从而实现高效的内存重用和更好的性能。此外,与 R、Python 和 Julia 等语言类似,您可以利用类型化数组来创建 ndarray(也称为跨步数组)接口。虽然 U/Int64 整数数组目前在此答案时不可用,但 (a) 它们的缺席并不是一个阻碍,并且 (b) 提案正在规范级别推进以将 U/Int64 整数数组添加到 JavaScript。具有结构化类型的复数也是如此。我个人认为,某种形式的数值计算在 JavaScript 和 Node.js 中是不可避免的。优势(普遍性、分布性、性能)和潜在应用(边缘计算、集成机器学习、数据可视化)太强大了,以至于不支持数据科学应用,至少在基本层面上。
披露:我和其他人目前正在开展一个项目 (https://github.com/stdlib-js/stdlib),该项目旨在提供 JavaScript 和 Node.js 中的数字计算工具。
【讨论】:
【参考方案8】:大部分节点工作似乎都在网络“全栈”领域,在快速数值处理具有优势的领域中完成的工作要少得多。
在快速数值处理具有优势的领域,Python、R 等可能占据主导地位。
结合这两个事实,你最终会发现没有多少人投入到节点数值处理库中。
【讨论】:
以上是关于用于节点的类似numpy的包[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Mysql连接在节点js中一段时间后关闭并给出PROTOCOL_CONNECTION_LOST'