03.20 Github優秀項目:GPU加速的神經網絡與JavaScript的碰撞

根據Github Octoverse 2017的報告,JavaScript是Github上最流行的語言。根據拉取請求的數量來衡量,JavaScript的活躍度與Python、Java和Go之和相當。

JavaScript已經征服了網絡,並“滲入”了服務器、移動端、桌面和其他平臺。

與此同時,GPU加速的使用已經遠遠超出了計算機圖形領域,現在已經成為機器學習的一個必需組成部分。

訓練神經網絡與深層架構是一個計算密集型過程,在機器智能領域帶來了許多重要的先進結果。

本文著眼於這些趨勢的不斷融合,並提供了將GPU加速的神經網絡引入到JavaScript世界的一些項目的概述。

Github優秀項目:GPU加速的神經網絡與JavaScript的碰撞

概述

下面列出的所有項目都是受到了積極維護的,在Github上有數千顆星,而且在NPM或CDN上也有分佈。

它們都是通過WebGL在瀏覽器中實現GPU加速,如果不存在合適的顯卡則可以退回到CPU。

本概述中不包括那些旨在運行現有模型的庫(特別是那些使用Python框架訓練的模型)。

最後,四個項目榜上有名。

雖然它的特性集面向神經網絡,但deeplearn.js可以被描述為通用機器學習框架。Propel是一個提供自動微分的科學計算的庫。Gpu.js提供了一種方便的方式來運行GPU上的JavaScript函數。Brain.js是舊的神經網絡庫的延續,並使用Gpu.js硬件加速。

Github優秀項目:GPU加速的神經網絡與JavaScript的碰撞

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庫的出現有幾個有趣的含義

Github優秀項目:GPU加速的神經網絡與JavaScript的碰撞

在線課程可以將與機器學習或GPU計算相關的練習直接融入到web應用程序中。學生不必在不同的操作系統和軟件版本之間建立單獨的開發環境。

基於神經網絡的許多演示可以更輕鬆地部署,不再需要服務器端API。

對機器學習感興趣的JavaScript開發人員可以充分利用他們的專業技能,在集成問題上花費更少的時間。

此外,客戶端可用的計算資源可能更有效地使用。畢竟,並不是所有的顯卡都被用於虛擬現實和加密貨幣的挖掘。

要說明的是,筆者並不提倡將本文中提到的庫用於關鍵任務的神經網絡。Python的生態系統仍然是大多數應用程序的首選。

然而令人鼓舞的是,過去12個月裡取得了明顯的進展。Deeplearn.js在一年前並不存在。Gpu.js的活躍水平相對較低,Brain.js不支持GPU加速。

隨著時間的推移,這些項目將在某些方面與已建立的框架相競爭,並在某些最適合JavaScript的全新應用程序中使用。


分享到:


相關文章: