TensorFlow.js、迁移学习与AI产品创新之道

TensorFlow 的 JS 版本终于出啦,deeplearn.js 正式收编至 TensorFlow 项目,并改名为 TensorFlow.js :

采用 WebGL 加速的基于浏览器的 JS 机器学习库。

摘要:

本文涉及 TensorFlow 基本概念的理解,迁移学习技术的实践应用,全文从技术聊到产品的玩法,设计师/产品经理只有懂得技术的新特性,才能为产品融入新的玩法。设计师也应该关注新技术带来的新的交互方式的变化,研究怎么样的交互方式才适合基于浏览器的深度学习应用。

阅读本文需要有 tensorflow ,及 javascript 、nodejs 的相关知识基础,以下为正文:

为了快速练习代码,我们可以使用 chrome 直接打开官网:

https://js.tensorflow.org/

然后打开 console 面板,直接输入代码即可使用 TensorFlow.js 。官方指南写得非常清楚,对 TensorFlow.js 核心概念的介绍,包括 tensors , operations , models , layers 以及 training ,都有简洁的代码示例。这里配合动手环节,加深对这几个概念的理解。

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 、手写字识别等这些应用都可以尝试融入用户个性化的数据再训练的玩法,给予用户掌控权。

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

设定类别

—> 采集数据

—> 开始训练

—> 使用用户数据

—> 核心功能

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

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

以上为全文内容,本文同时在知乎专栏:《人工智能+设计修炼指南》发表。最近我在思考把文章当成产品来打磨,定了个小基调:一篇文章尽量涉及2个不同领域的内容,跨界思考之间的关联性

原文发布于微信公众号 - 科技Mix设计Lab(Design-AI-Lab)

原文发表时间:2018-04-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器之心

教程 | 用深度学习DIY自动化监控系统

监控是安保和巡查一个不可或缺的组成部分。在大多数情况下,这项工作需要长时间去查找一些你不期望发生的事。我们做的这件事很重要,但也是一项非常乏味的任务。

1921
来自专栏数据小魔方

excel数据分析工具库系列三|趋势平滑

今天要跟大家分享的内容是数据分析工具库系列三——趋势平滑! 在时间序列数据中,往往存在很多周期性趋势以及随机干扰因素,给我们的分析工作工作带来很多不便。 当然有...

3186
来自专栏企鹅号快讯

教你快速使用OpenCV/Python/dlib进行眨眼检测识别!

摘要: 图像识别的新思路:眼睛纵横比,看看大牛如果用这种思路玩转识别眨眼动作! ? 今天我们来使用面部标志和OpenCV 检测和计算视频流中的眨眼次数。为了构建...

73510
来自专栏AI科技大本营的专栏

手动特征工程已经OUT了!自动特征工程才是改进机器学习的方式

【导读】近年来,我们在自动模型选择和超参数调优方面取得了进展,但机器学习流程中最重要的方面-- 特征工程,在很大程度上被我们所忽略。在本文中,我们将使用 Fea...

1763
来自专栏玉树芝兰

如何用Python和机器学习训练中文文本情感分类模型?

利用Python机器学习框架scikit-learn,我们自己做一个分类模型,对中文评论信息做情感分析。其中还会介绍中文停用词的处理方法。

3002
来自专栏ATYUN订阅号

【学术】无人零售背后的秘密:使用Tensorflow目标检测API实现更智能的零售结账

我一直在使用Tensorflow目标检测API,并对这些模型的强大程度感到惊讶。我想要分享一些API实际使用案例的性能。 Tensorflow目标检测API地址...

3939
来自专栏机器学习算法与Python学习

10月机器学习开源项目Top10

过去一个月里,我们对近 250 个机器学习开源项目进行了排名,并挑选出热度前 10 的项目。这份清单的平均 github star 数量高达 1345,涵盖了包...

1023
来自专栏IT派

干货 | 机器学习在web攻击检测中的应用实践

岳良, 携程信息安全部高级安全工程师。2015年加入携程,主要负责渗透测试,安全评审,安全产品设计。 一、背景 在web应用攻击检测的发展历史中,到目前为止...

55711
来自专栏大数据文摘

核心算法|谷歌如何从网络的大海里捞到针

2158
来自专栏华章科技

核心算法:谷歌如何从网络的大海里捞到针

作 者: David Austin,Grand Valley State University

1098

扫码关注云+社区

领取腾讯云代金券