服务器 频道

盘点:GPU加速的神经网络与JavaScript的交叉

  【IT168 编译】根据Github Octoverse 2017的报告,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.js

  Deeplearn.js是这四个中最受欢迎的项目,被描述为“用于机器智能的硬件加速JavaScript库”。它由谷歌大脑团队和超过50个贡献者组成的社区提供支持。两位主要作者是Daniel Smilkov和Nikhil Thorat。

  import * as dl from 'deeplearn'

  const xs = inputXs.as4D(-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1)

  const conv1Weights = dl.variable(

  dl.randomNormal([FILTER_HEIGHT, FILTER_WIDTH, 1, NUMBER_FILTERS], 0, 0.1) as dl.Tensor4D)

  const layer1 = dl.tidy(() => {

  return xs.conv2d(conv1Weights, 1, 'same')

  .relu()

  .maxPool([2, 2], STRIDES, PADDING)

  })

在deeplearn.js中定义卷积层


  在TypeScript中编写,且仿照Tensorflow,deeplearn.js支持谷歌大脑的旗舰开源项目中所提供功能的日益增长的部分。API有三个部分。

  第一部分介绍了用于创建、初始化和转换张量的函数,即用于保存数据的类似数组的结构。

  API的下一部分提供了在张量上执行的操作。这包括基本的数学运算,还原,归一化和卷积。在这一点上,对递归神经网络的支持是不成熟的,但它包含了大量的长短期记忆网络细胞。

  第三部分围绕模型训练展开。所有流行的优化器,从随机梯度下降(SGD)到Adam都包括在内。另一方面,交叉熵损失函数是文献中提到的唯一损失函数。

  API的其余部分用于设置环境和管理资源。

  node.js上的实验GPU加速,可以通过headless-gl实现。

  该项目网站有许多令人难忘的演示。其中包括由一个由递归神经网络生成的钢琴表演,一个建立模型的视觉界面和一个基于SqueezeNet(一个参数相对较少的图像分类器)的网络摄像头应用。

  PropelJS

  PropelJS被描述为“JavaScript的可微分编程”。主要作者是Ryan Dahl和Bert Belder,其工作得到了11位社区贡献者的补充。

  import * as pr from "propel"

  export async function train(maxSteps = 0) {

  const ds = pr.dataset("mnist/train").batch(128).repeat(100)

  const exp = await pr.experiment("exp001")

  for (const batchPromise of ds) {

  const { images, labels } = await batchPromise

  exp.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

  }

  }

一种前馈神经网络,它有三个层次的训练,在MNIST数据集上进行了训练


  自动微分(AD)是这个项目的核心,使我们不必手动指定衍生品。对于一个给定的函数f(x)定义了受支持的张量操作,梯度函数可以用grad来得到。多变量案例由multigrad覆盖。

  除了AD之外,项目的方向似乎并不完全清楚。虽然在网站上提到了“类似numpy 的基础架构”作为目标,但是API在“繁重的开发”下,包括与神经网络和计算机视觉相关的功能。使用load函数,可以解析npy文件的内容并作为张量使用。

  在浏览器环境中,PropelJS使用了deeplearn.js中的WebGL功能。对于节点的GPU加速,项目使用了TensorFlow的C API。

  gpu.js

  虽然笔者常用的是CUDA而不是WebGL,但可以证明GPU编程的耗时性。因此,当笔者遇到gpu.js时,感到非常惊喜。Github上大约有5700颗星,这个项目有有18个贡献者,其受欢迎程度可以与deeplearn.js媲美。随着时间的推移,有几个人做出了巨大的贡献。Robert Plummer是主要作者。

  import GPU from 'gpu.js'

  const gpu = new GPU()

  const multiplyMatrix = gpu.createKernel(function(a, b) {

  var sum = 0;

  for (var i = 0; i < 512; i++) {

  sum += a[this.thread.y][i] * b[i][this.thread.x];

  }

  return sum;

  }).setOutput([512, 512])

通过gpu.js实现矩阵乘法:在GPU编程中Hello World是等同的


  一个内核,在当前上下文中,是在GPU上执行的函数,而不是CPU。通过gpu.js,内核可以在JavaScript的一个子集中编写。然后编译代码并在GPU上运行。Node.js通过OpenCL的支持已经在几个星期前增加了。

  数字和数字数组的三个维度被用作输入和输出。除了基本的数学运算,gpu.js支持局部变量、循环和if/else语句。

  为了使代码重用和允许更模块化的设计,可以在内核代码中注册和使用自定义函数。

  在内核的JavaScript定义中,该对象提供了线程标识符,并持有在实际内核中保持不变的值,但在外部是动态的。

  该项目专门研究加速JavaScript函数,并没有尝试提供一个神经网络框架。为此,我们可以转向一个取决于gpu.js的库。

  Brain.js

  Brain.js是harthur/brain的继承者,后者是一个可以追溯到2010年的历史内容库。

  import brain from 'brain.js'

  const network = new brain.recurrent.RNN()

  const data = [

  {input: [0, 0], output: [0]},

  {input: [0, 1], output: [1]},

  {input: [1, 0], output: [1]},

  {input: [1, 1], output: [0]}

  ]

  network.train(data)


  总共有近30个人参与了这两个内容库。

  对GPU加速的神经网络的支持基于gpu.js,而且,可以说,这是该项目近期最重要的进展。

  除了前馈网络,Brain.js包括三种重要类型的递归神经网络的实现:经典Elman网络,长短期记忆网络,以及最近的有门控的周期性单元的网络。

  主页上显示了一个学习颜色对比偏好的神经网络。在源代码中可以找到另外两个演示,其中一个涉及到使用ASCII符号绘制的字符。

  机器学习加速JavaScript库的出现有几个有趣的含义。

  在线课程可以将与机器学习或GPU计算相关的练习直接融入到web应用程序中。学生不必在不同的操作系统和软件版本之间建立单独的开发环境。

  基于神经网络的许多演示可以更轻松地部署,不再需要服务器端API。

  对机器学习感兴趣的JavaScript开发人员可以充分利用他们的专业技能,在集成问题上花费更少的时间。

  此外,客户端可用的计算资源可能更有效地使用。毕竟,并不是所有的显卡都被用于虚拟现实和加密货币的挖掘。

  要说明的是,笔者并不提倡将本文中提到的库用于关键任务的神经网络。Python的生态系统仍然是大多数应用程序的首选。

  然而令人鼓舞的是,过去12个月里取得了明显的进展。Deeplearn.js在一年前并不存在。Gpu.js的活跃水平相对较低,Brain.js不支持GPU加速。

  随着时间的推移,这些项目将在某些方面与已建立的框架相竞争,并在某些最适合JavaScript的全新应用程序中使用。

0
相关文章