作者:Aral Roca

翻译:疯狂的技术宅

原文:https://aralroca.com/blog/fir...

未经容许严禁转载

在本文中咱们来钻研怎么用 TensorFlow.js 创立根本的 AI 模型,并应用更简单的模型实现一些乏味的性能。我只是刚刚开始接触人工智能,只管不须要深刻的人工智能常识,但还是须要搞清楚一些概念才行。

什么是模型?

真实世界是很简单的,咱们须要对其进行简化能力了解,能够用通过模型来进行简化,这种模型有很多种:比方世界地图,或者图表等。

比方要建设一个用来示意房子出租价格与屋宇面积关系的模型:首先要收集一些数据:

房间数量价格
3131000
3125000
4235000
4265000
5535000

而后,把这些数据显示在二维图形上,把每个参数(价格,房间数量)都做为 1 个维度:

而后咱们能够画一条线,并预测 更多房间的房屋出租价格。这种模型被称为线性回归,它是机器学习中最简略的模型之一。不过这个模型还不够好:

  1. 只有 5 个数据,所以不够牢靠。
  2. 只有 2 个参数(价格,房间),然而还有更多可能会影响价格的因素:比方地区、装修状况等。

能够通过增加更多的数据来解决第一个问题,比方一百万个。对于第二个问题,能够增加更多维度。在二维图表中能够很容易了解数据并画一条线,在三维图中能够应用立体:

然而当数据的维度是三维呢四维甚至是 1000000 维的时候,大脑就没有方法在图表上对其进行可视化了,然而能够在维度超过三维时通过数学来计算超平面,而神经网络就是为了解决这个问题而生的。

什么是神经网络?

要解什么是神经网络,须要晓得什么是神经元。真正的神经元看上去是这样的:

神经元由以下几局部组成:

  • 树突:这是数据的输出端。
  • 轴突:这是输入端。
  • 突触(未在图中示意):该构造容许一个神经元与另一个神经元之间进行通信。它负责在轴突的神经末梢和左近神经元的树突之间传递电信号。这些突触是学习的要害,因为它们会依据用处增减电流动。

机器学习中的神经元(简化):

  • Inputs(输出) :输出的参数。
  • Weights(权重) :像突触一样,用来通过调节神经元更好的建设线性回归。
  • Linear function(线性函数) :每个神经元就像一个线性回归函数,对于线性回归模型,只须要一个神经元够了。
  • Activation function(激活函数) :能够用一些激活函数来将输入从标量改为另一个非线性函数。常见的有 sigmoid、RELU 和 tanh。
  • Output(输入) :利用激活函数后的计算输入。

激活函数是十分有用的,神经网络的弱小次要归功于它。如果没有任何激活性能,就不可能失去智能的神经元网络。因为只管你的神经网络中有多个神经元,但神经网络的输入始终将是线性回归。所以须要一些机制来将各个线性回归变形为非线性的来解决非线性问题。通过激活函数能够将这些线性函数转换为非线性函数:

训练模型

正如 2D 线性回归的例子所形容的,只须要在图中画一条线就能够预测新数据了。尽管如此,“深度学习”的思维是让咱们的神经网络学会画这条线。对于一条简略的线,能够用只有一个神经元的非常简单的神经网络即可,然而对于想要做更简单事件的模型,例如对两组数据进行分类这种操作,须要通过“训练”使网络学习怎么失去上面的内容:

这个过程并不简单,因为它是二维的。每个模型都用来形容一个世界,然而“训练”的概念在所有模型中都十分类似。第一步是绘制一条随机线,并在算法中通过迭代对其进行改良,每次迭代中过程中修改谬误。这种优化算法名为 Gradient Descent(梯度降落)(有着雷同概念的算法还有更简单的 SGD 或 ADAM 等)。每种算法(线性回归,对数回归等)都有不同的老本函数来度量误差,老本函数会始终收敛于某个点。它能够是凸函数或凹函数,然而最终要收敛在 0% 误差的点上。咱们的指标就是实现这一点。

当应用梯度降落算法时,先从其老本函数的某个随机点开始,然而咱们不晓得它到底在什么中央!这就像你被蒙着眼睛丢在一座山上,想要下山的话必须一步一步地走到最低点。如果地形是不规则的(例如凹函数),则降落会更加简单。

在这里不会深刻解释“梯度降落”算法,只须要记住这是训练 AI 模型过程中最小化预测误差的优化算法就足够了。这种算法须要大量的工夫和 GPU 进行矩阵乘法。通常在第一次执行时很难达到这个收敛点,因而须要修改一些超参数,例如学习率(learning rate)或增加正则化(regularization)。在梯度降落迭代之后,当误差靠近 0% 时,会靠近收敛点。这样就创立了模型,接下来就可能进行预测了。

用 TensorFlow.js 训练模型

TensorFlow.js 提供了一种创立神经网络的简便办法。首先用 trainModel 办法创立一个 LinearModel 类。咱们将应用程序模型。程序模型是其中一层的输入是下一层的输出的模型,即当模型拓扑是简略的层级构造,没有分支或跳过。在 trainModel 办法外部定义层(咱们仅应用一层,因为它足以解决线性回归问题):

import * as tf from '@tensorflow/tfjs';/*** 线性模型类*/export default class LinearModel {  /** * 训练模型 */  async trainModel(xs, ys){    const layers = tf.layers.dense({      units: 1, // 输入空间的纬度      inputShape: [1], // 只有一个参数    });    const lossAndOptimizer = {      loss: 'meanSquaredError',      optimizer: 'sgd', // 随机梯度降落    };    this.linearModel = tf.sequential();    this.linearModel.add(layers); // 增加一层    this.linearModel.compile(lossAndOptimizer);    // 开始模型训练    await this.linearModel.fit(      tf.tensor1d(xs),      tf.tensor1d(ys),    );  }  //...}

应用这个类进行训练:

const model = new LinearModel()// xs 与 ys 是 数组成员(x-axis 与 y-axis)await model.trainModel(xs, ys)

训练完结后就能够开始预测了。

用 TensorFlow.js 进行预测

只管在训练模型时须要当时定义一些超参数,然而进行个别的预测还是很容易的。通过上面的代码就够了:

import * as tf from '@tensorflow/tfjs';export default class LinearModel {  ... //后面训练模型的代码  predict(value){    return Array.from(      this.linearModel      .predict(tf.tensor2d([value], [1, 1]))      .dataSync()    )  }}

当初就能够预测了:

const prediction = model.predict(500) // 预测数字 500console.log(prediction) // => 420.423

在 TensorFlow.js 中应用预训练的模型

训练模型是最难的局部。首先对数据进行标准化来进行训练,还须要正确的设定所有超参数等等。对于咱们初学者,能够间接用那些事后训练好的模型。 TensorFlow.js 能够应用很多预训练的模型,还能够导入应用 TensorFlow 或 Keras 创立的内部模型。例如能够间接用 posenet 模型(实时人体姿势评估)做一些有意思的我的项目:

???? 这个 Demo 的代码:https://github.com/aralroca/p...

它用起来很容易:

import * as posenet from '@tensorflow-models/posenet'// 设置一些常数const imageScaleFactor = 0.5const outputStride = 16const flipHorizontal = trueconst weight = 0.5// 加载模型const net = await posenet.load(weight)// 进行预测const poses = await net.estimateSinglePose(  imageElement,  imageScaleFactor,  flipHorizontal,  outputStride)

这个 JSON 是 pose 变量:

{  "score": 0.32371445304906,  "keypoints": [    {      "position": {        "y": 76.291801452637,        "x": 253.36747741699      },      "part": "nose",      "score": 0.99539834260941    },    {      "position": {        "y": 71.10383605957,        "x": 253.54365539551      },      "part": "leftEye",      "score": 0.98781454563141    }    // 前面还有: rightEye, leftEar, rightEar, leftShoulder, rightShoulder    // leftElbow, rightElbow, leftWrist, rightWrist, leftHip, rightHip,    // leftKnee, rightKnee, leftAnkle, rightAnkle...  ]}

从官网的 demo 能够看失去,用这个模型能够开发出很多乏味的我的项目。

???? 这个我的项目的源代码: https://github.com/aralroca/f...

导入 Keras 模型

能够把内部模型导入 TensorFlow.js。上面是一个用 Keras 模型(h5格局)进行数字辨认的程序。首先要用 tfjs_converter 对模型的格局进行转换。

pip install tensorflowjs

应用转换器:

tensorflowjs_converter --input_format keras keras/cnn.h5 src/assets

最初,把模型导入到 JS 代码中:

// 载入模型const model = await tf.loadModel('./assets/model.json')// 筹备图片let img = tf.fromPixels(imageData, 1)img = img.reshape([1, 28, 28, 1])img = tf.cast(img, 'float32')// 进行预测const output = model.predict(img)

只须要几行代码行就实现了。当然还能够在代码中增加更多的逻辑来实现更多功能,例如能够把数字写在 canvas 上,而后失去其图像来进行预测。

???? 这个我的项目的源代码: https://github.com/aralroca/M...

为什么要用在浏览器中?

因为设施的不同,在浏览器中训练模型时,效率可能很低。用 TensorFlow.js 利用 WebGL 在后盾训练模型,比用 Python 版的 TensorFlow 慢 1.5 ~ 2倍。

然而在 TensorFlow.js 呈现之前,没有能间接在浏览器中应用机器学习模型的 API,当初则能够在浏览器利用中离线训练和应用模型。而且预测速度更快,因为不须要向服务器发送申请。另一个益处是成本低,因为所有这些计算都是在客户端实现的。

总结

  • 模型是示意事实世界的一种简化形式,能够应用它来进行预测。
  • 能够用神经网络创立模型。
  • TensorFlow.js 是创立神经网络的简便工具。


本文首发微信公众号:前端先锋

欢送扫描二维码关注公众号,每天都给你推送陈腐的前端技术文章

欢送持续浏览本专栏其它高赞文章:

  • 深刻了解Shadow DOM v1
  • 一步步教你用 WebVR 实现虚拟现实游戏
  • 13个帮你进步开发效率的古代CSS框架
  • 疾速上手BootstrapVue
  • JavaScript引擎是如何工作的?从调用栈到Promise你须要晓得的所有
  • WebSocket实战:在 Node 和 React 之间进行实时通信
  • 对于 Git 的 20 个面试题
  • 深刻解析 Node.js 的 console.log
  • Node.js 到底是什么?
  • 30分钟用Node.js构建一个API服务器
  • Javascript的对象拷贝
  • 程序员30岁前月薪达不到30K,该何去何从
  • 14个最好的 JavaScript 数据可视化库
  • 8 个给前端的顶级 VS Code 扩大插件
  • Node.js 多线程齐全指南
  • 把HTML转成PDF的4个计划及实现

  • 更多文章...