【51CTO.com快译】虽然您可以借助TensorFlow用数量较少的训练数据来训练简单的神经网络,但对于拥有庞大训练数据集的深度神经网络而言,确实需要使用具有CUDA功能的英伟达GPU、谷歌TPU或FPGA进行加速。就在不久前,替代方法一直是在CPU集群上训练数周。
TensorFlow 2.0引入的创新之一是JavaScript实现:TensorFlow.js。我没料到这会加快训练或推理速度,但确实如此,它通过WebGL API支持所有的GPU(不仅仅支持具有CUDA功能的GPU)。
TensorFlow.js简介
TensorFlow.js是一个库,用于使用JavaScript开发和训练机器学习模型,并将其部署在浏览器中或Node.js上。您可以使用现有模型、转换Python TensorFlow模型、使用迁移学习用您自己的数据重新训练现有模型以及从头开始开发模型。
TensorFlow.js后端
TensorFlow.js支持多个后端来执行,不过每次只有一个后端处于活跃状态。TensorFlow.js Node.js环境支持使用Python/C TensorFlow的安装版本作为后端,TensorFlow反过来可能使用机器可用的硬件加速技术,比如CUDA。还有面向Node.js的基于JavaScript的后端,但功能有限。
在浏览器中,TensorFlow.js有几个特点不一的后端。WebGL后端使用面向存储的WebGL纹理和面向执行的WebGL着色器提供GPU支持,速度比普通CPU后端最多快100倍。 WebGL不需要CUDA,因此它可以充分利用现有的任何GPU。
浏览器版的WebAssembly(WASM)TensorFlow.js后端使用XNNPACK库来优化神经网络operator的CPU实现。WASM后端通常比JavaScript CPU后端快得多(快10倍至30倍),但除了超小模型外,通常比WebGL后端要慢。您的实际情况可能有所不同,因此请在您自己的硬件上针对自己的模型测试WASM后端和WebGL后端。
TensorFlow.js模型和层
TensorFlow.js支持用于构建神经网络模型的两个API。一个是Layers API,与TensorFlow 2中的Keras API实际上一样。另一个是Core API,它实际上直接操纵张量(tensor)。
与Keras一样,TensorFlow.js Layers API有两种创建模型的方法:顺序型和功能型。顺序型API是层的线性堆栈,通过层列表(如下所示)或model.add()方法来实现:
- const model = tf.sequential({
- layers: [
- tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}),
- tf.layers.dense({units: 10, activation: 'softmax'}),
- ]
- });
功能型API使用tf.model() API,可创建任意的有向无环图(DAG)网络:
- // Create an arbitrary graph of layers, by connecting them
- // via the apply() method.
- const input = tf.input({shape: [784]});
- const dense1 = tf.layers.dense({units: 32, activation: 'relu'}).apply(input);
- const dense2 = tf.layers.dense({units: 10, activation: 'softmax'}).apply(dense1);
- const model = tf.model({inputs: input, outputs: dense2});
Core API可使用不同的代码实现同样的目的,但与层之间没有简单直观的联系。以下的模型貌似基本的张量操作,但它创建与前两个公式一样的网络。注意下面model()函数中使用的relu()和softmax(),这两个都是神经网络操作。
- // The weights and biases for the two dense layers.
- const w1 = tf.variable(tf.randomNormal([784, 32]));
- const b1 = tf.variable(tf.randomNormal([32]));
- const w2 = tf.variable(tf.randomNormal([32, 10]));
- const b2 = tf.variable(tf.randomNormal([10]));
- function model(x) {
- return x.matMul(w1).add(b1).relu().matMul(w2).add(b2).softmax();
- }
预构建的TensorFlow.js模型
存储库中记载了十多个预构建的TensorFlow.js模型,它们托管在NPM(用于Node.js中)和unpkg(用于浏览器中)上。您可以使用所提供的这些模型或用于迁移学习。稍花点精力,您还可以将它们用作构建其他模型的模块。
其中一些模型实时使用设备的摄像头,比如手姿势:
图1. 手姿势可以检测手掌,并跟踪手骨骼手指。
以下列表介绍了大多数预包装的TensorFlow.js模型,便于索引。
- 图像分类
- 对象检测
- 身体分割
- 姿势估计
- 文本毒性检测
- 通用句子编码器
- 语音命令识别
- KNN分类器
- 简单人脸检测
- 语义分割
- 人脸标志检测
- 手姿势检测
- 自然语言问答
- ml5.js简介
ml5.js是主要在纽约大学开发的一种对用户友好的开源高级TensorFlow.js接口。ml5.js可在浏览器中立即访问预训练的模型,以检测人体姿势、生成文本、用另一种样式设置图像、创作音乐、音高检测和常用英语单词关系等。TensorFlow.js主要针对数据科学家和开发人员,ml5.js则旨在支持公众更广泛地了解机器学习。
ml5.js中的大多数示例依赖TensorFlow.js模型。它们已包装成网页,您可以按原样运行或编辑它们,比如使用不同的图像。
图2. PoseNet可以在浏览器中根据图像或视频源执行实时姿势估计。
将Python TensorFlow模型转换成JavaScript
TensorFlow.js存储库的一部分含有用于所保存的TensorFlow和Keras模型的转换器。它支持三种格式:SavedModel(TensorFlow的默认格式)、HDF5(Keras的默认格式)和TensorFlow Hub。您可以将该转换器用于标准存储库中的保存模型、自己训练的模型以及在别处找到的模型。
转换实际上有两个步骤。第一步是将现有模型转换成model.json和二进制权重文件。第二步是使用API将模型加载到TensorFlow.js中:使用面向转换后的TensorFlow和TensorFlow Hub模型的tf.loadGraphModel,或者使用面向转换后的Keras模型的tf.loadLayersModel。
使用迁移学习
TensorFlow.js支持迁移学习,支持方式实际上与TensorFlow一样。说明文档给出了几个示例,用于为您自己的图像定制MobileNet,以及为您自己的声音类定制语音命令识别模型。实际上,您在这每一个代码实验室中所做的就是在训练后的模型上添加一个小小的自定义分类器,并对其进行训练。
总体而言,TensorFlow能做的,TensorFlow.js基本上都能做。然而,鉴于TensorFlow.js的目标环境(面向游戏的普通GPU)通常比常常用于TensorFlow深度学习训练的庞大英伟达服务器GPU拥有较少的GPU内存,您可能不得不缩减模型的大小,以便在浏览器中运行。转换实用程序可以为您完成这部分工作,但是您要手动取出层,并缩减训练的批处理大小。
原文标题:How to use TensorFlow in your browser,作者:Martin Heller
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】