您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 Code iProcess 课程 认证 咨询 工具 火云堂 讲座吧   成长之路  
会员   
 
   
 
  
每天15篇文章
不仅获得谋生技能
更可以追随信仰
 
     
   
 订阅
  捐助
TensorFlow.js、迁移学习与AI产品创新之道
 
434 次浏览     评价:  
 2018-5-11 
 
编辑推荐:

本文来自于网络,全文从技术聊到产品的玩法,设计师/产品经理只有懂得技术的新特性,才能为产品融入新的玩法。

1 概念篇

1.1 tensors

TensorFlow.js 把 N 维数组都统称为 tensor ,为方便理解,见下图。

动手实践下代码:

var shape=[2,3];

var a=tf.tensor([1,2,3,4,4,5],shape);

a.print()

也可以改写为:

var a=tf.tensor([[1,2,3],[4,4,5]]);

a.print()

还可以写成 tf.scalar, tf.tensor1d , tf.tensor2d , tf.tensor3d 和 tf.tensor4d,以提高代码的可读性。

var a=tf.scalar(4);

a.print();

var b=tf.tensor1d([0,2,3,4]);

b.print();

var c=tf.tensor2d([[0,3],[4,5]]);

c.print();

TensorFlow.js还提供了直接创建所有值为0或者1的张量( tensor ),实验下:

tf.zeros([10]).print();
tf.zeros([2,8]).print();
tf.zeros([2,2,3]).print();
tf.ones([10]).print();
tf.ones([2,8]).print();
tf.ones([2,2,3]).print();

1.2 Variables

Tensors 是不可变的,一旦创建,不能改变其值;而 variables 则可以动态改变其值,主要用于在模型训练期间存储和更新值。

var initalValues=tf.ones([8]);

initalValues.print();

//biases变量,通过assign方法更新其值

var biases=tf.variable(initalValues);

biases.print();

var updatedValues=tf.tensor1d([0,1,2,3,4,5,6,7]);

updatedValues.print();

biases.assign(updatedValues);

biases.print();

1.3 Operations ( Ops )

一些数学的运算,矩阵变换,卷积操作,逻辑操作等。官方 api 文档很齐全,写得很清楚( https://js.tensorflow.org/api/0.6.1/ ),下面练习下 square 和 add :

//square

var d=tf.tensor2d([[1,2,3],[4,5,6]]);

d.print();

var d_squared=d.square();

d_squared.print();

//add

var a=tf.tensor2d([[1,2,3],[4,5,6]]);

var b=tf.tensor2d([[3,1,9],[14,25,16]]);

a.print();
b.print();

var c=a.add(b);

c.print();

d.add(b).square().print();

1.4 Models and Layers

Models 相当于 JS 函数的概念,给定一些输入,使用 Ops 来表示模型所做的工作,产生一些期望的输出。 TensorFLow.js 有 2 种创建模型的方法。

// 定义一个 predict 函数

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;
});
}

// 定义常量

var a = tf.scalar(2),
b = tf.scalar(4),
c = tf.scalar(8);

// 测试下 predict 函数

predict(1999993).print();

由于 TensorFlow.js 是使用 GPU 来运算的,所以需要管理 GPU 的内存,当使用 tensors 和 variables 时。其中, tf.tidy 的方法有助于避免内存泄漏(避免程序崩溃),试下 tidy :

// y = 3 ^ 2 + 1

var y = tf.tidy(() => {

// a, b, 以及 one 将会被清空当 tidy 结束时。


const one = tf.scalar(1);

const a = tf.scalar(3);


const b = a.square();



console.log('tensors 的数量 (in tidy): ' + tf.memory().numTensors);




return b.add(one);
});

console.log('tensors 的数量 (outside tidy): ' + tf.memory().numTensors);


y.print();

除了 tidy 外,还有 dispose 可以用来手动管理 GPU 内存。试验下:

const x=tf.tensor2d([[0,2,3],[1,2,3]]);

const x_squared=x.square();

x.print();

x_squared.print();

console.log(tf.memory().numTensors);

x.dispose();

console.log(tf.memory().numTensors);

x_squared.dispose();

console.log(tf.memory().numTensors);

tensorFlow.js 还内置了一些 model 的抽象,可以使用 tf.model 来构造一个不含 layer 的模型。 tf 包含的 layer 有 tf.layers.simpleRNN , tf.layers.gru 和 tf.layers.lstm 等。这里得通过几个小型项目来实践了。

2 官方示例

我们可以下载官方示例,在本地运行查看效果。官方 tensorFlow.js 项目,使用 yarn 作为包管理工具,使用 Parcel 作为 Web 应用的打包工具。

http://www.parceljs.io

如何使用官方示例,只要解压后,进入项目目录,终端输入 yarn ,安装完依赖包后再输入 yarn watch 即可运行项目。

官网有几个示例,第一个简单的是从头开始构建一个小型的模型,用于拟合曲线。第二个示范了 CNN 识别手写数字。第三个使用了迁移学习,训练一个神经网络来预测摄像头的数据。第四个介绍如何将 Keras 或 TensorFlow 训练好的模型导入 TensorFlow.js 来使用。有兴趣可以详细学习下。

3 webcam-transfer-learning

其中官方的游戏示例 webcam-transfer-learning ,建议玩一玩,是基于 MobileNet 的一个迁移学习的例子。

3.1 MobileNet

MobileNets:
Efficient Convolutional Neural Networks for Mobile Vision Applications

这是谷歌的一篇论文提出的,可以极大的压缩模型文件大小,非常适合移动端使用。本文使用 Keras 预训练的图像分类模型 MobileNet_25_224 。通过加载训练好的 keras 模型,可以直接在浏览器使用或再次在浏览器中使用迁移学习,训练新的模型。

先下载训练好的模型:

https://github.com/fchollet/deep-learning-models/releases/download/v0.6/mobilenet_2_5_224_tf.h5

然后终端运行:

pip install tensorflowjs

然后运行:

tensorflowjs_converter --input_format keras mobilenet_2_5_224_tf.h5 model

转成 tensorFlow.js 可调用的 model 后,我们需要把 model 放置在一个服务器上,并设置允许跨域请求,这边可以使用一个 nodejs 的库:

npm install http-server -g

进入model文件夹内运行:

http-server -p 3000 --cors

加载 model 可以使用:

const model = await tf.loadModel(‘https://localhost:3000/model.json');

官方也很贴心的把模型放到 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/model.json 供调用了。

这里我测试了下 MobileNet 的效果:

3.2 Transfer Learning

webcam-transfer-learning 是一个图像分类问题,将摄像头拍摄的照片与上下左右的动作做关联。主要是训练数据收集:摄像头拍摄,每张图片归一化处理成 shape 为 [1,244,244,3] 的张量,作为训练数据;为此 tensorFlow.js 特地封装了调用 webcam 的相关方法,以方便直接对接到 tensorFLow.js 中使用。并使用 Transfer Learning 迁移学习来减少训练数据的量,达到分类的目的。

3.2.1 预处理

加载预训练模型 MoblieNet ,并截取合适的层作为输出。上文已经介绍过如何把 keras 训练的模型转成 tensorFlow.js 的模型格式了,这里我们直接从谷歌提供的模型服务中获取。

代码:

async function loadMobilenet() {

const mobilenet = await tf.loadModel(
'https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/model.json');

console.log(mobilenet.layers)

const layer = mobilenet.getLayer(‘conv_pw_13_relu');


console.log(layer.output.shape)

return tf.model({
inputs: mobilenet.inputs,
outputs: layer.output
});


}

通过调用 getLayer(‘conv_pw_13_relu’) ,我们进入了预训练的 MobileNet 模型的内部层,并构建了一个新的模型,其中输入是与 MobileNet 相同的输入,但输出的是 MobileNet 中间层名为 conv_pw_13_relu 的层。我们凭经验选择了这一层( 它对我们的任务很有效 )。一般来说,接近预训练模型结束的层将在传输学习任务中表现更好,因为它包含输入的更高级语义特征。尝试选择另一个图层,看看它是如何影响模型质量的!可以使用 model.layers 打印模型的图层查看。

在代码中加入:

console.log(layer.output.shape)

打印出来是 [ null , 7 , 7 , 256 ] ,每次用户拍摄照片,都会马上调用 MobileNet 输出 conv_pw_13_relu 层,作为 Model 的输入数据(上图的红色框)。

3.2.2 迁移学习

我们将把 MobileNet 的这一层输出作为我们新创建的模型的输入,新创建的模型输出为 4 个类别的预测。(上图的红色框)

model = tf.sequential({

layers: [
tf.layers.flatten({
inputShape: [7, 7, 256]
}),

tf.layers.dense({
units: ui.getDenseUnits(),
activation: 'relu',
kernelInitializer: 'varianceScaling',
useBias: true
}),


tf.layers.dense({
units: NUM_CLASSES,
kernelInitializer: 'varianceScaling',
useBias: false,
activation: 'softmax'
})



]
});

创建2个全连接层的模型,独立于 mobilenet 模型。根据用户拍摄的4个图片,训练此新模型。

这里使用了 tf.layers.flatten 。关于 tf.layers.flatten 的使用,可以实践下:

model=tf.sequential();

model.add(tf.layers.flatten({inputShape:[12,4]}));

nn=model.predict(tf.ones([99,12,4]));

console.log(nn.shape);

nn.print()

输入是一个shape 为[99,12,4]的三维张量,最后输出的是一个shape 为 [99, 48] 的二维张量,flatten 把 [12 , 4] ,压缩为 [ 12X4 ] 。

4 基于用户个性化数据的产品

webcam-transfer-learning 游戏给我们提供了一个基于用户个性化数据的玩法。用户可以非常低成本的训练属于自己的图像分类模型,用于各种分类问题。我们可以拓展下,比如识别用户的手势动作,来控制游戏中的人物;识别用户的表情,控制3d人物的表情;识别图像中的人脸数量,自动隐藏所浏览的内容,防止被窥视……甚至 autodraw 、ui2code 、手写字识别等这些应用都可以尝试融入用户个性化的数据再训练的玩法,给予用户掌控权。

我认为新技术都会有一种很自然的新的交互方式与之匹配。基于浏览器的用户个性化数据再训练,可以提炼出以下基本的交互流程:

设定类别

—> 采集数据

—> 开始训练

—> 使用用户数据

—> 核心功能

—> 完成任务/得到某个结果。

用户使用自己的数据,应用更符合用户个性化特征,是一种不同于个性化推荐的“个性化”产品设计方法。

   
435 次浏览  评价: 差  订阅 捐助
相关文章

我们该如何设计数据库
数据库设计经验谈
数据库设计过程
数据库编程总结
 
相关文档

数据库性能调优技巧
数据库性能调整
数据库性能优化讲座
数据库系统性能调优系列
相关课程

高性能数据库设计与优化
高级数据库架构师
数据仓库和数据挖掘技术
Hadoop原理、部署与性能调优
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
 
 

关于我们 | 联系我们 | 京ICP备10020922号 京公海网安备110108001071号