根据GithubOctoverse2017报告,JavaScript是Github上最流行的语言。以拉取请求的数量来衡量,JavaScript与Python、Java和Go的总和一样活跃。JavaScript已经征服了网络并“渗透”到服务器、移动、桌面和其他平台。与此同时,GPU加速的使用已经远远超出了计算机图形学的范围,现在已成为机器学习的必要组成部分。训练神经网络和深度架构是一个计算密集型过程,已在机器智能领域产生了许多重要的先进成果。本文着眼于这些趋势的日益融合,并概述了一些将GPU加速神经网络引入JavaScript世界的项目。概览下面列出的所有项目都得到积极维护,在Github上有数千颗星,同时也分布在NPM或CDN上。它们都是通过WebGL在浏览器中进行GPU加速,如果不存在合适的显卡,则回退到CPU。本概述不包括旨在运行现有模型(尤其是使用Python框架训练的模型)的库。***,列表中有四个项目。尽管其功能集面向神经网络,但deeplearn.js可以描述为通用机器学习框架。Propel是一个提供自动微分的科学计算库。Gpu.js提供了一种在GPU上运行JavaScript函数的便捷方式。Brain.js是旧神经网络库的延续,并使用Gpu.js硬件加速。Deeplearn.jsDeeplearn.js是这四个项目中的最新项目,被描述为“用于机器智能的硬件加速JavaScript库”。它由GoogleBrain团队和一个由50多名贡献者组成的社区提供支持。两位主要作者是DanielSmilkov和NikhilThorat。import*asdlfrom'deeplearn'constxs=inputXs.as4D(-1,IMAGE_HEIGHT,IMAGE_WIDTH,1)constconv1Weights=dl.variable(dl.randomNormal([FILTER_HEIGHT,FILTER_WIDTH,1,NUMBER_FILTERS],0,0.1)asdl.Tensor4D)constlayer=dl.tidy(()=>{returnxs.conv2d(conv1Weights,1,'same').relu().maxPool([2,2],STRIDES,PADDING)})定义了deeplearn.js中的卷积层在TypeScript中并以Tensorflow为模型,deeplearn.js支持GoogleBrain旗舰开源项目中提供的越来越多的功能。API包含三个部分。***部分描述了用于创建、初始化和转换张量的函数,张量是用于保存数据的类似数组的结构。API的下一部分提供了对张量执行的操作。这包括基本的数学运算、归约、归一化和卷积。在这一点上,循环神经网络的支持还不成熟,但它包含了大量的长短期记忆网络单元。第三部分围绕模型训练展开。涵盖了所有流行的优化器,从随机梯度下降(SGD)到Adam。另一方面,交叉熵损失函数是文献中提到的唯一损失函数。API的其余部分用于设置环境和管理资源。node.js上的实验性GPU加速,可用于headless-gl。该项目网站有许多令人难忘的演示。其中包括由递归神经网络生成的钢琴演奏、用于构建模型的可视化界面,以及基于SqueezeNet的网络摄像头应用程序,SqueezeNet是一种参数相对较少的图像分类器。PropelJSPropelJS被描述为“JavaScript的可微分编程”。主要作者是RyanDahl和BertBelder,他们的工作得到了11位社区贡献者的补充。import*asprfrom"propel"exportasyncfunctiontrain(maxSteps=0){constds=pr.dataset("mnist/train").batch(128).repeat(100)constexp=awaitpr.experiment("exp001")for(constbatchPromiseofds){const{images,labels}=awaitbatchPromiseexp.sgd({lr:0.01},(params)=>images.rescale([0,255],[-1,1]).linear("L1",params,200).relu().linear("L2",params,100).relu().linear("L3",params,10).softmaxLoss(labels))if(maxSteps&&exp.step>=maxSteps)break}}一种feedforward神经网络,它有三个层次的训练,是在MNIST数据集上训练的。自动微分(AD)是该项目的核心,使我们不必手动指定导数。对于给定的函数f(x)定义支持的张量操作,梯度函数可以用grad.多变量情况由multigrad涵盖。除了AD,项目的方向似乎并不完全清楚。虽然网站上提到“类似numpy的基础设施”作为目标,但API正在“大力开发”,包括与神经网络和计算机视觉相关的功能。使用load函数,可以解析npy文件的内容并将其用作张量。在浏览器环境中,PropelJS使用了deeplearn.js中的WebGL功能。对于节点的GPU加速,该项目使用TensorFlow的CAPI。虽然gpu.js是笔者常用的使用CUDA而不是WebGL的方式,但它可以证明GPU编程的耗时性。因此,笔者在遇到gpu.js的时候,非常惊喜。该项目在Github上拥有约5700颗星,有18位贡献者,其受欢迎程度可与deeplearn.js相媲美。随着时间的推移,一些人做出了重大贡献。罗伯特·普卢默(RobertPlummer)是第一作者。importGPUfrom'gpu.js'constgpu=newGPU()constmultiplyMatrix=gpu.createKernel(function(a,b){varsum=0;for(vari=0;i<512;i++){sum+=a[this.thread.y][i]*b[i][this.thread.x];}returnsum;}).setOutput([512,512])通过gpu.js实现矩阵乘法:HelloWorld相当于GPU编程中的一个kernel,在In当前上下文,在GPU上执行的函数,而不是CPU。使用gpu.js,内核可以用JavaScript的子集编写。然后代码被编译并在GPU上运行。几周前添加了通过OpenCL的Node.js支持。数字的三个维度和数字数组用作输入和输出。除了基本的数学运算之外,gpu.js还支持局部变量、循环和if/else语句。为了实现代码重用并允许更加模块化的设计,可以在内核代码中注册和使用自定义函数。在内核的JavaScript定义中,此对象提供线程标识符并保存一个值,该值在实际内核中保持不变,但在外部是动态的。该项目专注于加速JavaScript功能,并不试图提供神经网络框架。为此,我们可以转向依赖于gpu.js的库。Brain.jsBrain.js是harthur/brain的继任者,harthur/brain是一个可追溯到2010年的历史内容库。importGPUfrom'gpu.js'constgpu=newGPU()constmultiplyMatrix=gpu.createKernel(function(a,b){varsum=0;for(vari=0;i<512;i++){sum+=a[this.thread.y][i]*b[i][this.thread.x];}returnsum;}).setOutput([512,512])共有近30人参与了这两个内容库。对GPU加速神经网络的支持基于gpu.js,并且可以说是该项目最近最重要的开发。除了前馈网络之外,Brain.js还包括三种重要类型的递归神经网络的实现:经典Elman网络、长短期记忆网络,以及最近带有门控递归单元的网络。主页显示了一个学习颜色对比度偏好的神经网络。在源代码中可以找到另外两个演示,其中一个涉及使用ASCII符号绘制的字符。机器学习加速的JavaScript库的出现有几个有趣的含义。在线课程可以将与机器学习或GPU计算相关的练习直接合并到Web应用程序中。学生不必在不同的操作系统和软件版本之间设置单独的开发环境。许多基于神经网络的演示可以更轻松地部署,无需服务器端API。对机器学习感兴趣的JavaScript开发人员可以利用他们的专业知识,减少在集成问题上花费的时间。此外,可以更有效地使用客户端可用的计算资源。毕竟,并非所有显卡都用于虚拟现实和加密货币挖掘。澄清一下,作者不提倡将本文中提到的库用于任务关键型神经网络。Python生态系统仍然是大多数应用程序的首选。然而,令人鼓舞的是,在过去12个月中取得了明显进展。Deeplearn.js一年前还不存在。Gpu.js活跃度比较低,Brain.js不支持GPU加速。随着时间的推移,这些项目将在某些方面与已建立的框架竞争,并用于一些最适合JavaScript的全新应用程序。
