TensorFlow.js是通过WebGL加速、基于浏览器的机器学习js框架。通过tensorflow.js,我们可以在浏览器中开发机器学习、运行现有的模型或者重新训练现有的模型。

一、安装

     有两种方法可以在你的项目中引入tensorflow.js。一种是通过script标签引入,另外一种就是通过npm进行安装。

(1)通过script标签,如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tensorflow</title>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.9.0"></script>
</head>
<body>
<script>
console.log(tf);
</script>
</body>
</html>

  即直接引入tensorflow.js文件,然后我们在浏览器中打开console控制台,就可以看到tf是一个tensorflow.js暴露出来的对象,其包含了很多属性和方法。

(2)npm安装,即通过npm install @tensorflow/tfjs,然后在入口文件中使用 import * as tf from '@tensorflow/tfjs' 即可。

  

  注意:tensorflow是用ES7的写法,所以,如果要在浏览器环境下运行,就必须使用babel转换为浏览器可以执行的代码。

二、核心概念

(1)Tensors(张量)

  Tensorflow.js中数据的主要表现形式就是tensor(张量):由 一组数值  形成 一维或多维数组。一个Tensor实例有一个shape属性来定义这一组数值如何组成张量(比如在数组的每个维度的数量各自有多少)。而最主要的Tensor实例的构造函数就是 tf.tensor 函数,如下所示:

const shape = [, ]; // 2行,3列
const a = tf.tensor([1.0, 2.0, 3.0, 10.0, 20.0, 30.0], shape);
a.print();
console.log(Object.prototype.toString.call(a)); const b = tf.tensor([[1.0, 2.0, 3.0], [10.0, 20.0, 30.0]]);
b.print();
  1. 我们制定了shape为2行3列,那么调用tf.tensor构造函数来构造张量时,就需要在第一个参数中传入 2 * 3 = 6个数字的数组,接着通过a.print()在控制台打印出来,是一个二维数组。
  2. 为了确定张量a的类型,我们可以使用JavaScript的Object.prototype.toString.call()方法来查看。 实际上张量虽然表现为一维或多维数组,但他本质上是一个对象。
  3. 张量的形状也可以直接被传入数组来直接构造,即张量b就是通过传入一个二维数组构造得到的张量。

       

  

    然后,对于构建低维度的张量,我们推荐使用下面的函数来增强代码的可读性:tf.scalar(零维), tf.tensor1d(一维), tf.tensor2d(二维), tf.tensor3d(三维)、tf.tensor4d(四维)以及 tf.ones(值全是1)或者tf.zeros(值全是0) ,如下所示:

    const a = tf.scalar(3.14);
a.print(); // 输出零维张量 const b = tf.tensor2d([[, , ], [, , ]]);
b.print(); // 输出二维张量 const c = tf.zeros([, ]);
c.print(); // 输出2行3列的值全是0的张量 const d = tf.ones([, ]);
d.print(); // 输出3行5列的值全是1的张量

  如下所示:

TensorFlow.js中,张量tensors是不可变(immutable)的;一旦被创建,你就无法改变他们的值,除了使用操作符产生新的tensors张量。

  

(2)Variables(变量)

  Variables变量是通过张量进行初始化得到的。不像Tensor的值不可变,变量的值是可变的。你可以使用变量的assign方法分配一个新的tensor到这个变量上,这是变量就会改变

    const initialValues = tf.zeros([]);
const biases = tf.variable(initialValues);
biases.print();
console.log(Object.prototype.toString.call(biases)); const updatedValues = tf.tensor1d([, , , , ]);
biases.assign(updatedValues);
biases.print();

  如上所示,首先使用tf.zeros得到一个张量,然后利用这个张量初始化得到一个变量,接着我们就可以打印这个变量,并且通Object.prototype.toString.call(biases)方法可以判断变量也是一个对象,接着,我们再生成一个张量,然后变量调用assign方法传入这个张量,就可以得到一个新的变量了,如下

  

  于是我们可以得出这样一个结论:变量由张量生成,且张量不可变而变量可变。

(3)Operations操作

  张量可以用来存储数据,而operation可以用来操作数据。 TensorFlow.js为线性代数计算和机器学习提供了一系列有用的操作符,可以用来处理张量。因为张量是不可变的,所以这些操作符不会改变这些张量的值,而是会返回一个新的张量。 就像JavaScript中的字符串一样,无论你怎么操作,这些字符串本身不会改变,而只会返回一个新的值。

  比如下面这个一元操作符 square 操作符用来求平方:

    const a = tf.tensor2d([[1.0, 2.0], [3.0, 4.0]]);
const a_squared = a.square();
a_squared.print();
a.print();

  如上所示,我们通过tf.tensor2d创建了一个2行2列的张量a,然后使用square操作得到了a_square,下面是控制台中的结果:

  下面是一个add、sub、mul的二元操作符示例:

    const a = tf.tensor2d([[5.0, 6.0], [7.0, 8.0]]);
const b = tf.tensor2d([[1.0, 2.0], [3.0, 4.0]]); const a_plus_b = a.add(b);
a_plus_b.print(); const a_sub_b = a.sub(b);
a_sub_b.print(); const a_mul_b = a.mul(b);
a_mul_b.print();

   如下所示,我们就可以得到add、sub、mul的结果:

  

另外,在TensorFlow.js中也是支持链式操作的,如下所示:

    const a = tf.tensor2d([[2.0, 2.0], [2.0, 2.0]]);
const b = tf.tensor2d([[3.0, 3.0], [3.0, 3.0]]);
const c = tf.tensor2d([[5.0, 5.0], [5.0, 5.0]]);
const res = a.add(b).square().sub(c);
res.print();

    即首先得到a.add(b)的结果然后再sub(减)c,这样的链式操作得到res,结果如下:

  

(4)模型(Models)和层(Layers)

  从概念上来说,一个模型一个给定一些输入将会产生特定的输出的函数。从前面黑体字可以看出,一个模型就是一个函数,只是它完成了特定的任务。

  在TensorFlow.js中有两种方式来创建模型,一种是通过操作(ops)来直接完成模型本身所做的工作,另外一种就是通过高级API tf.model来创建一个模型,显然第二种是更容易的。

  我们先看第一种创建模型的方法:

   function predict (input) {
// y = a*x^2 + b*x + c
return tf.tidy(() => {
const x = tf.scalar(input); const ax2 = a.mul(x.square());
const bx = b.mul(x);
const y = ax2.add(bx).add(c); return y;
});
} // 定义常量
const a = tf.scalar();
const b = tf.scalar();
const c = tf.scalar(); // 对于2预测输出
const result = predict();
result.print(); // Tensor 24

  如上所示,我们定义的predict函数就是一个模型,对于给定的输入,我们就可以得到预测的输出。注意:所有的数字都需要经过tf.scalar()张量处理。

  

  而第二种创建模型的方法就是用 TensorFlow.js 中的 tf.model 方法(这里的model并不是真正可以调用的方法,而是一个总称,比如实际上可以调用的是tf.sequential模型),这在深度学习中是非常流行的概念。 下面的代码就创建了 tf.sequential 模型:

    const model = tf.sequential();
model.add(
tf.layers.simpleRNN({
units: ,
recurrentInitializer: 'GlorotNormal',
inputShape: [, ]
})
); const optimizer = tf.train.sgd(LEARNING_RATE);
model.compile({optimizer, loss: 'categoricalCrossentropy'});
model.fit({x: data, y: labels});

  注意:这段代码有错,日后解决。 这里大概就是在表达tf创建模型有给定的模型供我们使用,而第一种方法是我们完全自己去写的模型。

(5)内存管理: dispose和tf.tidy

  因为TensorFlow.js使用了GPU来加速数学运算,因此当tensorflow处理张量和变量时就有必要来管理GPU内存。而主要的两个管理内存的方法就是: dispose 和 tf.tidy。

   dispose

我们可以使用对 张量 或者 变量 在运算之后使用dispose来清理以及释放它的GPU内存。如下所示:

    const x = tf.tensor2d([[0.0, 2.0], [4.0, 6.0]]);
const x_squared = x.square(); x.dispose();
x_squared.dispose();

  tf.tidy

   当我们做了大量了Tensor操作时,再使用 dispose 处理起来会非常不方便。所以TensorFlow.js提供了另外一个函数:tf.tidy,这个函数和JavaScript中作用域都扮演了同样的角色,只不过这个函数是为tensors服务的。

    tf.tidy 执行了一个函数并且清理了中间创建的tensor,以此加速了GPU内存,但是它不会清理其内部函数最终的返回值,所以只是起到了GPU加速目的,而不会影响tensor计算,如下:

   const average = tf.tidy(() => {
// tf.tidy会清除所有的tensor产生的内存使得GPU加速
// 尽管下面是一个简单操作,但是还是会产生很多中间张量,
// 所以将这些数学运算放在tidy函数中是最佳实践
const y = tf.tensor1d([1.0, 2.0, 3.0, 4.0]);
const z = tf.ones([]); return y.sub(z).square().mean();
}); average.print(); // Tensor 3.5

    这样,我们就可以使用最大效率的GPU加速了。其中,mean()函数是求取平均值的操作,如下所示:

    const average = tf.tensor1d([, , , , ]).mean();
average.print(); // Tensor 3

  因此, tf.tidy可以帮助阻止程序内存泄露。下面是两个我们需要额外注意的点:

  1. 传入tf.tidy内的函数必须是同步的且不能Promise,我们建议对于更新UI的代码以及http请求的代码都放在tf.tidy之外。
  2. tf.tidy 不会清理变量 Variable。 因为变量往往会持续整个机器学习模型的生命周期,所以,即使它们在tf.tidy函数中创建TensorFlow.js也不会清理它们,然而,是可以通过dispose来手动清理的。

  

    到这里,tensorflow.js的安装和核心概念就结束了,后面会有更多关于tensorflow的文章。

TensorFlow.js之安装与核心概念的更多相关文章

  1. webpack安装与核心概念

    安装webpack webpack核心概念:入口.输出.加载器.插件.模块.模式 一.安装webpack 1.安装webpack之前需要安装nodejs环境,在使用nodejs环境自带的包管理工具np ...

  2. ElasticSearch安装和核心概念

    1.ElasticSearch安装 elasticsearch的安装超级easy,解压即用(要事先安装好java环境). 到官网 http://www.elasticsearch.org下载最新版的 ...

  3. Tensoflw.js - 01 - 安装与入门(中文注释)

    Tensoflw.js - 01 - 安装与入门(中文注释) 参考 W3Cschool 文档:https://www.w3cschool.cn/tensorflowjs/ 本文主要翻译一些英文注释,添 ...

  4. ElasticSearch学习笔记-01 简介、安装、配置与核心概念

    一.简介 ElasticSearch是一个基于Lucene构建的开源,分布式,RESTful搜索引擎.设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便.支持通过HTTP使用JSON进 ...

  5. tensorflow核心概念和原理介绍

    关于 TensorFlow TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库. 节点(Nodes)在图中表示数学操作,图中的线(edges)则表示 ...

  6. docker核心概念与配置安装

    一.Docker的三大核心概念: 镜像(image)  容器(container) 仓库(repository) 1.Docker镜像类是与虚拟机镜像,可以把它理解为一个只读的模板. 不仅仅是操作系统 ...

  7. docker的核心概念和安装

    里Dcoker的安装要求 我这里安装的是在vmware下的centos7 64位 并且通过模拟远程连接xshell 我在安装好之后就配置了静态ip,这里我就不多说怎么配置了 具体静态ip配置可以参考 ...

  8. Docker 核心概念、安装、端口映射及常用操作命令,详细到令人发指。

    Docker简介 Docker是开源应用容器引擎,轻量级容器技术. 基于Go语言,并遵循Apache2.0协议开源 Docker可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发 ...

  9. Ext JS 6学习文档–第2章–核心概念

    核心概念 在下一章我们会构建一个示例项目,而在这之前,你需要学习一些在 Ext JS 中的核心概念,这有助于你更容易理解示例项目.这一章我们将学习以下知识点: 类系统,创建和扩展类 事件 Ext JS ...

随机推荐

  1. 最全js表单验证

    /***************************************************************** 表单校验工具类 (linjq) ***************** ...

  2. IntelliJ IDEA 2017版 spring-boot2.0.4的集成JSP

    一.必须依赖四个包,其中三个是springboot自带包,可以不写版本号,有一个不在springboot中,需要设置版本号 <!--引入Spring Boot内嵌的Tomcat对Jsp的解析包- ...

  3. 小论文matlab作图技巧

    小论文matlab作图技巧 编辑->复制选项 编辑->图形属性 图中右击->字型 编辑->复制图片,即可. 效果: 宽:5.9高: 7.91

  4. 如何悄悄地提升MySQL用户权限

    温馨提示: 一次成功的非法提权,需要的必备条件是:1.对mysql权限表的查.改权限: 2.一次不经意的数据库服务器重启: 此次测试版本:5.6.25 准备邪恶用户: grant update on ...

  5. Jersey RESTful WebService框架学习(三)使用@QueryParam

    介绍:@QueryParamuri路径请求参数写在方法的参数中,获得请求路径附带的参数.比如:@QueryParam("desc") String desc 前端控制 <!D ...

  6. ng-repeat动态改变样式

    当我们使用AngularJs的ng-repeat时候动态绑定数据时,遇到遍历出来的标签样式都一样,这时候希望根据数组的下标分别对应不同的样式 解决:使用$index获取数组下标根据下标改变样式 < ...

  7. 20180705 fragment

    https://www.cnblogs.com/chaowang/p/6180825.html https://blog.csdn.net/xxkalychen/article/details/537 ...

  8. Python之turtle库

    在命令行下```python -m pip install turtle``` 大致有两种命令: 运动命令: forward(distance) #向前移动距离distance代表距离 backwar ...

  9. CentOS 6.0 安装配置rails 2.3.11 + redmine 1.2.1 笔记

    没想到安装过程这么曲折,gem安装时下载经常是不成功的,无耐只好把.gem文件下载回来再本地安装,加上radmine 1.2.1对各组件的版本了也比较挑剔,中间走了不少弯路,折腾了二天时间,终于摸清路 ...

  10. Eclipse tomcat配置 未在Eclipse中添加.jar包出错

    JavaWeb: 报错信息The superclass "javax.servlet.http.HttpServlet" was not found on the Java Bui ...