2019-03-04 15:13:02 qq_33612918 阅读数 146
  • AI时代,机器学习该如何入门?

    机器学习入门视频教程,该课程会告诉大家如何入门机器学习,掌握机器学习必要的基础知识,了解机器学习路径。对于机器学习,很多人的观点是:机器学习技术是今后所有技术人员都绕不过的一个门槛。 那么,普通程序员该学习机器学作为一名对机器学习心有向往的程序员,我该以什么样的姿势开始呢?不妨看看该课程。

    7185 人正在学习 去看看 CSDN讲师

原理

已知测得的点 xi = [x1, x2, x3 ...]yi = [y1, y2, y3 ...]
利用梯度下降法,使得代价函数(即误差)取最小值,求得此时的参数值
举个例子,假设要拟合的函数为y = ax + b,代价函数为 J(a, b),现在要使代价函数最小
不妨想,在登山的过程中,东西方向为 a, 南北方向为b,函数值y为山的高度。我们要下山,找到山的最低点的过程,就是梯度下降。现在理一理我们下山的步骤:

  1. 先向东西方向看,下降最大的方向是哪边(这个步骤叫求 a 的偏导)
  2. 再向南北方向看,下降最大的方向是哪边(这个步骤叫求 b 的偏导)
  3. 向确定的方向跨 α 步 (这个 α 叫做步长)
  4. 不断重复步骤123,确定四周已经足够平滑(设置 误差 ,表示已经到最低点了)
    在这里插入图片描述

代码实现

// 一元线性回归
// _a, _b 	—— 需求的参数值
// xi, yi 	—— 样本数组
// _step 	—— 步长设置
// _inaccuracy —— 最大误差
function gradient_descent(_a, _b, xi, yi, _step, _inaccuracy) {
	let a = _a	//设置初始值
	let	b = _b	//设置初始值
	const step = _step					// 定义步长
	const inaccuracy = _inaccuracy		// 定义最大误差
	let count = 400						// 最大迭代次数,防止无限循环
	while (count--){
		let grad_a = Ja(a, b, xi, yi) * step
		let grad_b = Jb(a, b, xi, yi) * step
		a = a - grad_a
		b = b - grad_b
		let cost = J(a, b, xi, yi)	// 代价函数
		console.log('cost:'+cost, 'a:'+a, 'b:'+b)
		if(Math.abs(grad_a) < inaccuracy && Math.abs(grad_b) < inaccuracy){
			console.log('count:'+count)
			return [a, b]
		}
		old_cost = cost
	}
	console.log('count:'+count)
	return [a, b]
}
// 代价函数
function J(a, b, xi, yi) {
	const number = xi.length
	let sum = 0
	for(let i = 0; i < number; i++){
		sum = sum + (a*xi[i]+b-yi[i]) * (a*xi[i]+b-yi[i])
	}
	return sum/2
}
// 对 J 求 a 的偏导
function Ja(a, b, xi, yi) {
	const number = xi.length
	let sum = 0
	for(let i = 0; i < number; i++){
		sum = sum + (a*xi[i]+b-yi[i])*xi[i]
	}
	return sum
}
// 对 J 求 b 的偏导
function Jb(a, b, xi, yi) {
	const number = xi.length
	let sum = 0
	for(let i = 0; i < number; i++){
		sum = sum + a*xi[i]+b-yi[i]
	}
	return sum
}

// 测试
const xi = [1,2,3,4,5,9, ]
const yi = [1,3,2,4,5,7, ]
console.log(gradient_descent(0, 0, xi, yi, 0.01, 1e-3))
2020-01-01 15:10:01 Aria_Miazzy 阅读数 15
  • AI时代,机器学习该如何入门?

    机器学习入门视频教程,该课程会告诉大家如何入门机器学习,掌握机器学习必要的基础知识,了解机器学习路径。对于机器学习,很多人的观点是:机器学习技术是今后所有技术人员都绕不过的一个门槛。 那么,普通程序员该学习机器学作为一名对机器学习心有向往的程序员,我该以什么样的姿势开始呢?不妨看看该课程。

    7185 人正在学习 去看看 CSDN讲师

开始

TensorFlow.js 是一个 JavaScript 库,用于在浏览器和 Node.js 训练和部署机器学习模型。

了解开始的更多方式,请参阅下面的部分。

 

在不直接处理张量的情况下编写 ML 程序

想要开始机器学习,同时不用担心任何类似张量或优化器的低级细节吗?

ml5.js 库构建在 TensorFlow.js 之上,通过简洁的、可利用的 API,可以在浏览器中访问机器学习算法和模型。

Check out ml5.js

 

安装 TensorFlow.js

TensorFlow.js 与 Tensors (张量)、Layers (图层)、Optimizers (优化器) 和损失函数等概念兼容(或希望与它们兼容)吗?TensorFlow.js 为 JavaScript 中神经网络编程提供了灵活的构建块。

请参阅如何在浏览器或 Node.js 中启动和运行 TensorFlow.js 代码。

Get Setup

 

将预训练模型转换到 TensorFlow.js

学习如何将预训练模型从 python 转换为 TensorFlow.js

Keras Model GraphDef Model

 

从现有 TensorFlow.js 代码中学习

tfjs-examples 提供了使用 TensorFlow.js 实现各种 ML 任务的简短代码示例。

See it on GitHub

 

可视化您的 TensorFlow.js 模型的状态

tfjs-vis 是一个用于在浏览器内实现可视化的小型库,用于TensorFlow.js。

See it on GitHub See Demo

 

准备好用 TensorFlow.js 处理数据

TensorFlow.js 支持使用 ML 最佳实践处理数据。

See docs

 

安装

浏览器安装

在您基于浏览器的项目中获取TensorFlow.js有以下两种主要方法

如果您不熟悉Web开发,或者从未听说过webpack或parcel等工具,我们建议您使用脚本标签(script tags)。如果您经验丰富或想要编写更大的程序,那么使用构建工具进行探索可能更加合适。

 

使用脚本标签(script tags)

将以下脚本标签添加到您的主HTML文件中:

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>

有关脚本标签的设置,请参阅代码示例:

See code sample script tag setup

 

从NPM安装

您可以使用 npm cli工具或是yarn安装TensorFlow.js。

yarn add @tensorflow/tfjs

 

npm install @tensorflow/tfjs

 

See sample code for installation via NPM

 

Node.js 安装

您可以使用 npm cli工具或是yarn安装TensorFlow.js。

选项1: 安装带有原生C++绑定的TensorFlow.js。

yarn add @tensorflow/tfjs-node

 

npm install @tensorflow/tfjs-node

 

选项2: (仅限Linux)如果您的系统具有支持CUDA的NVIDIA®GPU,请使用GPU包以获得更高的性能。

yarn add @tensorflow/tfjs-node-gpu

 

npm install @tensorflow/tfjs-node-gpu

 

选项3: 安装纯JavaScript版本,这是性能方面最慢的选项。

yarn add @tensorflow/tfjs

 

npm install @tensorflow/tfjs

 

See sample code for Node.js usage

TypeScript

当使用TypeScript时,如果您的项目使用严格的空值检查,或者在编译过程中遇到错误,则您可能需要在您的tsconfig.json文件中设置skipLibCheck:true

 

从二维数据进行预测

在这个教程中你将使用一组汽车的数字数据集训练一个模型并且预测。

本练习将演示训练许多不同类型模型的常用步骤,但将使用小数据集和简单(浅)模型。 主要目的是帮助您熟悉TensorFlow.js训练模型的基本术语、概念和语法 并为进一步的探索和学习提供一个垫脚石。

打开Codelab

 

使用卷积神经网络进行手写数字识别

在这个教程中,我们将会使用Tensorflow.js建立手写数字识别卷积神经网络模型。首先,我们训练分类器,让它查看数千个图像以及其标签。然后我们将使用模型从未见过的测试数据来评估分类器的准确性。

在 CodeLab 中打开

 

Tensorflow.js 张量和变量

张量(Tensor)和变量(Variable)是TensorFlow.js中数据的主要表现形式,两者不同之处在于张量是不可变的,而变量是可变的。

 

张量(Tensor)

TensorFlow.js中数据的中心单位是张量:一组数值形成一个或多个维度的数组。 张量实例具有定义数组形状的形状属性。

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

// 2x3 Tensor
const shape = [2, 3]; // 2 行, 3 列
const a = tf.tensor([1.0, 2.0, 3.0, 10.0, 20.0, 30.0], shape);
a.print(); // 打印张量值
// 输出:    [[1 , 2 , 3 ],
//          [10, 20, 30]]

// shape也可以用下面的方式实现:
const b = tf.tensor([[1.0, 2.0, 3.0], [10.0, 20.0, 30.0]]);
b.print();
// 输出:    [[1 , 2 , 3 ],
//          [10, 20, 30]]

但是,为了构造低秩张量,我们推荐使用下面的函数来增强代码的可读性: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([[2, 3, 4], [5, 6, 7]]);
b.print(); // 输出二维张量

const c = tf.zeros([2, 3]);
c.print(); // 输出2行3列的值全是0的张量

const d = tf.ones([3, 5]);
d.print(); // 输出3行5列的值全是1的张量

在TensorFlow.js中,张量是不变的; 一旦创建你就不能改变它们的值。 但是,您可以对它们执行操作来生成新的张量。

 

变量(Variable)

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

const initialValues = tf.zeros([5]);
const biases = tf.variable(initialValues); // 初始化biases
biases.print(); // 输出: [0, 0, 0, 0, 0]

const updatedValues = tf.tensor1d([0, 1, 0, 1, 0]);
biases.assign(updatedValues); // 更新 biases的值
biases.print(); // 输出: [0, 1, 0, 1, 0]

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

11

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

 

以上就是Tensorflow.js 张量和变量的相关介绍,希望对大家有所帮助。

 

Tensorflow.js 模型

在Tensorflow.js中,从概念上来说,一个模型就是一个给定一些输入将会产生特定的输出的函数。简单来说,一个模型就是一个函数,只是它完成了特定的任务。

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

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

function predict(input) {
  // y = a * x ^ 2 + b * x + c
  // More on tf.tidy in the next section
  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(2);
const b = tf.scalar(4);
const c = tf.scalar(8);

const result = predict(2);
result.print() 

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

 

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

const model = tf.sequential();
model.add(
  tf.layers.simpleRNN({
    units: 20,
    recurrentInitializer: 'GlorotNormal',
    inputShape: [80, 4]
  })
);

const optimizer = tf.train.sgd(LEARNING_RATE);
model.compile({optimizer, loss: 'categoricalCrossentropy'});
model.fit({x: data, y: labels)});

以上就是TensorFlow.js模型创建的两种方法介绍,希望对大家有所帮助。

 

Tensorflow.js 内存管理

因为TensorFlow.js使用了GPU来加速数学运算,因此当tensorflow处理张量和变量时就有必要来管理GPU内存。在TensorFlow.js中,我们可以通过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

进行大量的张量操作时使用dispose可能会很麻烦。 TensorFlow.js提供了另一个函数tf.tidy,它对JavaScript中的常规范围起到类似的作用,不同的是它针对GPU支持的张量。

tf.tidy执行一个函数并清除所有创建的中间张量,释放它们的GPU内存。 它不清除内部函数的返回值。

const average = tf.tidy(() => {
  const y = tf.tensor1d([1.0, 2.0, 3.0, 4.0]);
  const z = tf.ones([4]);

  return y.sub(z).square().mean();
});

average.print()

使用tf.tidy将有助于防止应用程序中的内存泄漏。它也可以用来更谨慎地控制内存何时回收。

 

两个重要的注意事项

传递给tf.tidy的函数应该是同步的,并且不会返回Promise。我们建议在tf.tidy内不要有更新UI或在发出远程请求的代码。

tf.tidy不会清理变量。变量通常持续到机器学习模型的整个生命周期,因此TensorFlow.js不会清理它们,即使它们是在tidy中创建的。不过,您可以手动调用dispose处理它们。

 

 

 

Tensorflow.js 拟合曲线

这篇文章中,我们将使用TensorFlow.js来根据数据拟合曲线。即使用多项式产生数据然后再改变其中某些数据(点),然后我们会训练模型来找到用于产生这些数据的多项式的系数。简单的说,就是给一些在二维坐标中的散点图,然后我们建立一个系数未知的多项式,通过TensorFlow.js来训练模型,最终找到这些未知的系数,让这个多项式和散点图拟合。

 

先决条件

本教程假定您熟悉核心概念中介绍的TensorFlow.js的基本构建块:张量,变量和操作。 我们建议在完成本教程之前先完成核心概念的学习。

 

运行代码

这篇文章关注的是创建模型以及学习模型的系数,完整的代码在这里可以找到。为了在本地运行,如下所示:

$ git clone https://github.com/tensorflow/tfjs-examples
$ cd tfjs-examples/polynomial-regression-core
$ yarn
$ yarn watch

即首先将核心代码下载到本地,然后进入polynomial-regression-core(即多项式回归核心)部分,最后进行yarn安装并运行。

 

输入数据

我们的数据集由x坐标和y坐标组成,当绘制在笛卡尔平面上时,其坐标如下所示:

1

 

该数据是由三次方程 y = ax^{3}+ bx^{2} + cx + d 生成的。

我们的任务是学习这个函数的a,b,c和d系数以最好地拟合数据。 我们来看看如何使用TensorFlow.js操作来学习这些值。

 

学习步骤

第1步:设置变量

首先,我们需要创建一些变量。即开始我们是不知道a、b、c、d的值的,所以先给他们一个随机数,入戏所示:

const a = tf.variable(tf.scalar(Math.random()));
const b = tf.variable(tf.scalar(Math.random()));
const c = tf.variable(tf.scalar(Math.random()));
const d = tf.variable(tf.scalar(Math.random()));

 

第2步:建立模型

我们可以通过TensorFlow.js中的链式调用操作来实现这个多项式方程  y = ax3 + bx2 + cx + d,下面的代码就创建了一个 predict 函数,这个函数将x作为输入,y作为输出:

function predict(x) {
  // y = a * x ^ 3 + b * x ^ 2 + c * x + d
  return tf.tidy(() => {
    return a.mul(x.pow(tf.scalar(3))) // a * x^3
      .add(b.mul(x.square())) // + b * x ^ 2
      .add(c.mul(x)) // + c * x
      .add(d); // + d
  });
}

其中,在上一篇文章中,我们讲到tf.tify函数用来清除中间张量,其他的都很好理解。

接着,让我们把这个多项式函数的系数使用之前得到的随机数,可以看到,得到的图应该是这样:

2

 

因为开始时,我们使用的系数是随机数,所以这个函数和给定的数据匹配的非常差,而我们写的模型就是为了通过学习得到更精确的系数值。

 

第3步:训练模型

最后一步就是要训练这个模型使得系数和这些散点更加匹配,而为了训练模型,我们需要定义下面的三样东西:

  • 损失函数(loss function):这个损失函数代表了给定多项式和数据的匹配程度。 损失函数值越小,那么这个多项式和数据就跟匹配。
  • 优化器(optimizer):这个优化器实现了一个算法,它会基于损失函数的输出来修正系数值。所以优化器的目的就是尽可能的减小损失函数的值。
  • 训练迭代器(traing loop):即它会不断地运行这个优化器来减少损失函数。

所以,上面这三样东西的 关系就非常清楚了: 训练迭代器使得优化器不断运行,使得损失函数的值不断减小,以达到多项式和数据尽可能匹配的目的。这样,最终我们就可以得到a、b、c、d较为精确的值了。

 

定义损失函数

这篇文章中,我们使用MSE(均方误差,mean squared error)作为我们的损失函数。MSE的计算非常简单,就是先根据给定的x得到实际的y值与预测得到的y值之差 的平方,然后在对这些差的平方求平均数即可

1044137-20180415120225981-2029551102

于是,我们可以这样定义MSE损失函数:

function loss(predictions, labels) {
  // 将labels(实际的值)进行抽象
  // 然后获取平均数.
  const meanSquareError = predictions.sub(labels).square().mean();
  return meanSquareError;
}

即这个损失函数返回的就是一个均方差,如果这个损失函数的值越小,显然数据和系数就拟合的越好。

 

定义优化器

对于我们的优化器而言,我们选用 SGD (Stochastic Gradient Descent)优化器,即随机梯度下降。SGD的工作原理就是利用数据中任意的点的梯度以及使用它们的值来决定增加或者减少我们模型中系数的值。

TensorFlow.js提供了一个很方便的函数用来实现SGD,所以你不需要担心自己不会这些特别复杂的数学运算。 即 tf.train.sdg 将一个学习率(learning rate)作为输入,然后返回一个SGDOptimizer对象,它与优化损失函数的值是有关的。

在提高它的预测能力时,学习率(learning rate)会控制模型调整幅度将会有多大。低的学习率会使得学习过程运行的更慢一些(更多的训练迭代获得更符合数据的系数),而高的学习率将会加速学习过程但是将会导致最终的模型可能在正确值周围摇摆。简单的说,你既想要学的快,又想要学的好,这是不可能的。

下面的代码就创建了一个学习率为0.5的SGD优化器。

const learningRate = 0.5;
const optimizer = tf.train.sgd(learningRate);

 

定义训练循环

既然我们已经定义了损失函数和优化器,那么现在我们就可以创建一个训练迭代器了,它会不断地运行SGD优化器来使不断修正、完善模型的系数来减小损失(MSE)。下面就是我们创建的训练迭代器:

function train(xs, ys, numIterations = 75) {

  const learningRate = 0.5;
  const optimizer = tf.train.sgd(learningRate);

  for (let iter = 0; iter < numIterations; iter++) {
    optimizer.minimize(() => {
      const predsYs = predict(xs);
      return loss(predsYs, ys);
    });
  }

现在,让我们一步一步地仔细看看上面的代码。首先,我们定义了训练函数,并且以数据中x和y的值以及制定的迭代次数作为输入:

function train(xs, ys, numIterations) {
...
}

接下来,我们定义了之前讨论过的学习率(learning rate)以及SGD优化器:

const learningRate = 0.5;
const optimizer = tf.train.sgd(learningRate);

最后,我们定义了一个for循环,这个循环会运行numIterations次训练。在每一次迭代中,我们都调用了optimizer优化器的minimize函数,这就是见证奇迹的地方:

for (let iter = 0; iter < numIterations; iter++) {
  optimizer.minimize(() => {
    const predsYs = predict(xs);
    return loss(predsYs, ys);
  });
}

minimize 接受了一个函数作为参数,这个函数做了下面的两件事情:

1、首先它对所有的x值通过我们在之前定义的pridict函数预测了y值。

2、然后它通过我们之前定义的损失函数返回了这些预测的均方误差。

minimize函数之后会自动调整这些变量(即系数a、b、c、d)来使得损失函数更小。

在运行训练迭代器之后,a、b、c以及d就会是通过模型75次SGD迭代之后学习到的结果了。 

查看结果!

一旦程序运行结束,我们就可以得到最终的a、b、c和d的结果了,然后使用它们来绘制曲线,如下所示:

3

这个结果已经比开始随机分配系数的结果拟合的好得多了!

 

 

 

Tensorflow.js 图片训练

这篇文章中,我们将使用CNN构建一个Tensorflow.js模型来分辨手写的数字。首先,我们通过使之“查看”数以千计的数字图片以及他们对应的标识来训练分辨器。然后我们再通过此模型从未“见到”过的测试数据评估这个分辨器的精确度。

 

一、运行代码

这篇文章的全部代码可以在仓库TensorFlow.js examples 中的tfjs-examples/mnist 下找到,你可以通过下面的方式clone下来然后运行这个demo:

$ git clone https://github.com/tensorflow/tfjs-examples
$ cd tfjs-examples/mnist
$ yarn
$ yarn watch

上面的这个目录完全是独立的,所以完全可以copy下来然后创建你个人的项目。

 

二、数据相关

这里我们将会使用  MNIST  的手写数据,这些我们将要去分辨的手写数据如下所示:

11

为了预处理这些数据,我们已经写了 data.js, 这个文件包含了Minsdata类,而这个类可以帮助我们从MNIST的数据集中获取到任意的一些列的MNIST。

而MnistData这个类将全部的数据分割成了训练数据和测试数据。我们训练模型的时候,分辨器就会只观察训练数据。而当我们评价模型时,我们就仅仅使用测试数据,而这些测试数据是模型还没有看见到的,这样就可以来观察模型预测全新的数据了。

这个MnistData有两个共有方法:

1、nextTrainBatch(batchSize): 从训练数据中返回一批任意的图片以及他们的标识。

2、nextTestBatch(batchSize):  从测试数据中返回一批图片以及他们的标识。

注意:当我们训练MNIST分辨器时,应当注意数据获取的任意性是非常重要的,这样模型预测才不会受到我们提供图片顺序的干扰。例如,如果我们每次给这个模型第一次都提供的是数字1,那么在训练期间,这个模型就会简单的预测第一个就是1(因为这样可以减小损失函数)。 而如果我们每次训练时都提供的是2,那么它也会简单切换为预测2并且永远不会预测1(同样的,也是因为这样可以减少损失函数)。如果每次都提供这样典型的、有代表性的数字,那么这个模型将永远也学不会做出一个精确的预测。

 

三、创建模型

在这一部分,我们将会创建一个卷积图片识别模型。为了这样做,我们使用了Sequential模型(模型中最为简单的一个类型),在这个模型中,张量(tensors)可以连续的从一层传递到下一层中。

  首先,我们需要使用tf.sequential先初始化一个sequential模型:

const model = tf.sequential();

既然我们已经创建了一个模型,那么我们就可以添加层了。

 

四、添加第一层

我们要添加的第一层是一个2维的卷积层。卷积将过滤窗口掠过图片来学习空间上来说不会转变的变量(即图片中不同位置的模式或者物体将会被平等对待)。

我们可以通过tf.layers.conv2d来创建一个2维的卷积层,这个卷积层可以接受一个配置对象来定义层的结构,如下所示:

model.add(tf.layers.conv2d({
  inputShape: [28, 28, 1],
  kernelSize: 5,
  filters: 8,
  strides: 1,
  activation: 'relu',
  kernelInitializer: 'VarianceScaling'
}));

让我们拆分对象中的每个参数吧:

  • inputShape。这个数据的形状将回流入模型的第一层。在这个示例中,我们的MNIST例子是28 x 28像素的黑白图片,这个关于图片的特定的格式即[row, column, depth],所以我们想要配置一个[28, 28, 1]的形状,其中28行和28列是这个数字在每个维度上的像素数,且其深度为1,这是因为我们的图片只有1个颜色:
  • kernelSize。划过卷积层过滤窗口的数量将会被应用到输入数据中去。这里,我们设置了kernalSize的值为5,也就是指定了一个5 x 5的卷积窗口。
  • filters。这个kernelSize的过滤窗口的数量将会被应用到输入数据中,我们这里将8个过滤器应用到数据中。
  • strides。 即滑动窗口每一步的步长。比如每当过滤器移动过图片时将会由多少像素的变化。这里,我们指定其步长为1,这意味着每一步都是1像素的移动。
  • activation。这个activation函数将会在卷积完成之后被应用到数据上。在这个例子中,我们应用了relu函数,这个函数在机器学习中是一个非常常见的激活函数。
  • kernelInitializer。这个方法对于训练动态的模型是非常重要的,他被用于任意地初始化模型的weights。我们这里将不会深入细节来讲,但是 VarianceScaling (即这里用的)真的是一个初始化非常好的选择。

 

五、添加第二层  

让我们为这个模型添加第二层:一个最大的池化层(pooling layer),这个层中我们将通过 tf.layers.maxPooling2d 来创建。这一层将会通过在每个滑动窗口中计算最大值来降频取样得到结果。

model.add(tf.layers.maxPooling2d({
  poolSize: [2, 2],
  strides: [2, 2]
}));
  • poolSize。这个滑动池窗口的数量将会被应用到输入的数据中。这里我们设置poolSize为[2, 2],所以这就意味着池化层将会对输入数据应用2x2的窗口。
  • strides。 这个池化层的步长大小。比如,当每次挪开输入数据时窗口需要移动多少像素。这里我们指定strides为[2, 2],这就意味着过滤器将会以在水平方向和竖直方向上同时移动2个像素的方式来划过图片。

  注意:因为poolSize和strides都是2x2,所以池化层空口将会完全不会重叠。这也就意味着池化层将会把激活的大小从上一层减少一半。

 

六、添加剩下的层

重复使用层结构是神经网络中的常见模式。我们添加第二个卷积层到模型,并在其后添加池化层。请注意,在我们的第二个卷积层中,我们将滤波器数量从8增加到16。还要注意,我们没有指定inputShape,因为它可以从前一层的输出形状中推断出来:

model.add(tf.layers.conv2d({
  kernelSize: 5,
  filters: 16,
  strides: 1,
  activation: 'relu',
  kernelInitializer: 'VarianceScaling'
}));

model.add(tf.layers.maxPooling2d({
  poolSize: [2, 2],
  strides: [2, 2]
}));

接下来,我们添加一个 flatten层,将前一层的输出平铺到一个向量中:

model.add(tf.layers.flatten());

最后,让我们添加一个 dense层(也称为全连接层),它将执行最终的分类。 在dense层前先对卷积+池化层的输出执行flatten也是神经网络中的另一种常见模式:

model.add(tf.layers.dense({
  units: 10,
  kernelInitializer: 'VarianceScaling',
  activation: 'softmax'
}));

我们来分析传递给dense层的参数。

  • units. 激活输出的数量。由于这是最后一层,我们正在做10个类别的分类任务(数字0-9),因此我们在这里使用10个units。 (有时units被称为神经元的数量,但我们会避免使用该术语。)
  • kernelInitializer. 我们将对dense层使用与卷积层相同的VarianceScaling初始化策略。
  • activation. 分类任务的最后一层的激活函数通常是 softmax。 Softmax将我们的10维输出向量归一化为概率分布,使得我们10个类中的每个都有一个概率值。

 

定义优化器

对于我们的卷积神经网络模型,我们将使用学习率为0.15的随机梯度下降(SGD)优化器:

const LEARNING_RATE = 0.15;
const optimizer = tf.train.sgd(LEARNING_RATE);

 

定义损失函数

对于损失函数,我们将使用通常用于优化分类任务的交叉熵( categoricalCrossentropy)。 categoricalCrossentropy度量模型的最后一层产生的概率分布与标签给出的概率分布之间的误差,这个分布在正确的类标签中为1(100%)。 例如,下面是数字7的标签和预测值:

|class | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |----------|---|---|---|---|---|---|---|---|---|---| |label | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | |prediction|.1 |.01|.01|.01|.20|.01|.01|.60|.03|.02|

如果预测的结果是数字7的概率很高,那么categoricalCrossentropy会给出一个较低的损失值,而如果7的概率很低,那么categoricalCrossentropy的损失就会更高。在训练过程中,模型会更新它的内部参数以最小化在整个数据集上的categoricalCrossentropy。

 

定义评估指标

对于我们的评估指标,我们将使用准确度,该准确度衡量所有预测中正确预测的百分比。

 

编译模型

为了编译模型,我们传入一个由优化器,损失函数和一系列评估指标(这里只是'精度')组成的配置对象:

model.compile({
  optimizer: optimizer,
  loss: 'categoricalCrossentropy',
  metrics: ['accuracy'],
});

 

配置批量大小

在开始训练之前,我们需要定义一些与batch size相关的参数:

const BATCH_SIZE = 64;
const TRAIN_BATCHES = 100;
const TEST_BATCH_SIZE = 1000;
const TEST_ITERATION_FREQUENCY = 5;

 

进一步了解分批量和批量大小

为了充分利用GPU并行化计算的能力,我们希望将多个输入批量处理,并使用单个前馈网络调用将他们馈送到网络。

我们批量计算的另一个原因是,在优化过程中,我们只能在对多个样本中的梯度进行平均后更新内部参数(迈出一步)。这有助于我们避免因错误的样本(例如错误标记的数字)而朝错误的方向迈出了一步。

当批量输入数据时,我们引入秩D + 1的张量,其中D是单个输入的维数。

如前所述,我们MNIST数据集中单个图像的维度为[28,28,1]。当我们将BATCH_SIZE设置为64时,我们每次批量处理64个图像,这意味着我们的数据的实际形状是[64,28,28,1](批量始终是最外层的维度)。

注意:*回想一下在我们的第一个conv2d配置中的inputShape没有指定批量大小(64)。 Config被写成批量大小不可知的,以便他们能够接受任意大小的批次。

 

编写训练循环

以下是训练循环的代码:

for (let i = 0; i < TRAIN_BATCHES; i++) {
  const batch = data.nextTrainBatch(BATCH_SIZE);
 
  let testBatch;
  let validationData;

  if (i % TEST_ITERATION_FREQUENCY === 0) {
    testBatch = data.nextTestBatch(TEST_BATCH_SIZE);
    validationData = [
      testBatch.xs.reshape([TEST_BATCH_SIZE, 28, 28, 1]), testBatch.labels
    ];
  }
 
  const history = await model.fit(
      batch.xs.reshape([BATCH_SIZE, 28, 28, 1]),
      batch.labels,
      {
        batchSize: BATCH_SIZE,
        validationData,
        epochs: 1
      });

  const loss = history.history.loss[0];
  const accuracy = history.history.acc[0];

}

让我们分析代码。 首先,我们获取一批训练样本。 回想一下上面说的,我们利用GPU并行化批量处理样本,在对大量样本进行平均后才更新参数:

const batch = data.nextTrainBatch(BATCH_SIZE);
  • 每5个step(TEST_ITERATION_FREQUENCY),我们构造一次validationData,这是一个包含一批来自MNIST测试集的图像及其相应标签这两个元素的数组,我们将使用这些数据来评估模型的准确性:
if (i % TEST_ITERATION_FREQUENCY === 0) {
  testBatch = data.nextTestBatch(TEST_BATCH_SIZE);
  validationData = [
    testBatch.xs.reshape([TEST_BATCH_SIZE, 28, 28, 1]),
    testBatch.labels
  ];
}

model.fit是模型训练和参数实际更新的地方。

注意:在整个数据集上执行一次model.fit会导致将整个数据集上传到GPU,这可能会使应用程序死机。 为避免向GPU上传太多数据,我们建议在for循环中调用model.fit(),一次传递一批数据,如下所示:

  const history = await model.fit(
      batch.xs.reshape([BATCH_SIZE, 28, 28, 1]), batch.labels,
      {batchSize: BATCH_SIZE, validationData: validationData, epochs: 1});

我们再来分析一下这些参数:

  • X. 输入图像数据。请记住,我们分批量提供样本,因此我们必须告诉fit函数batch有多大。 MnistData.nextTrainBatch返回形状为[BATCH_SIZE,784]的图像 —— 所有的图像数据是长度为784(28 * 28)的一维向量。但是,我们的模型预期图像数据的形状为[BATCH_SIZE,28,28,1],因此我们需要使用reshape函数。
  • y. 我们的标签;每个图像的正确数字分类。
  • BATCHSIZE. 每个训练batch中包含多少个图像。之前我们在这里设置的BATCH_SIZE是64。
  • validationData. 每隔TEST_ITERATION_FREQUENCY(这里是5)个Batch,我们构建的验证集。该数据的形状为[TEST_BATCH_SIZE,28,28,1]。之前,我们设置了1000的TEST_BATCH_SIZE。我们的评估度量(准确度)将在此数据集上计算。
  • epochs. 批量执行的训练次数。由于我们分批把数据馈送到fit函数,所以我们希望它每次仅从这个batch上进行训练。

每次调用fit的时候,它会返回一个包含指标日志的对象,我们把它存储在history。我们提取每次训练迭代的损失和准确度,以便将它们绘制在图上:

const loss = history.history.loss[0];
const accuracy = history.history.acc[0];

 

查看结果!

如果你运行完整的代码,你应该看到这样的输出:

v2-22a6180e611dc02770481d6de33f9396_hd

 

TensorFlow.js 导入Keras模型

Keras模型(通常通过Python API创建)的存储格式可以有多种, 其中“整个模型”(即架构+权重+优化器状态都存在一个文件内)格式可以转换为 TensorFlow.js Layers格式,可以直接加载到TensorFlow.js中进行推理或进一步训练。

TensorFlow.js Layers格式是一个包含model.json文件和一组二进制格式的权重文件分片的目录。 model.json文件包含模型拓扑结构(又名“体系结构”或“图”:层的描述以及它们如何连接)以及权重文件的清单。

 

要求

运行模型格式转换程序需要Python环境;如果你想要一个独立的环境,你可以使用pipenv或virtualenv。要安装转换器,请使用这个命令 

pip install tensorflowjs

将Keras模型导入TensorFlow.js可以分为两个步骤。首先,将现有的Keras模型转换为TF.js Layers格式,然后将其加载到TensorFlow.js中。

 

1、将Keras模型转换为TF.js Layers格式

Keras模型通常使用model.save(filepath)保存,它生成一个包含模型拓扑结构和权重的HDF5(.h5)文件。要将这样的文件转换为TF.js Layer格式,请运行以下命令,其中path / to / my_model.h5是Keras .h5源文件,path / to / tfjs_target_dir是TF.js文件的输出目录:

# bash

tensorflowjs_converter --input_format keras \
                       path/to/my_model.h5 \
                       path/to/tfjs_target_dir

这一步骤的另一个方案:使用Python API直接导出为TF.js Layers格式

如果您在Python中使用Keras模型,则可以将其直接导出为TensorFlow.js Layers格式,如下所示:

# Python

import tensorflowjs as tfjs

def train(...):
    model = keras.models.Sequential()   # for example
    ...
    model.compile(...)
    model.fit(...)
    tfjs.converters.save_keras_model(model, tfjs_target_dir)

 

2、将模型加载到TensorFlow.js中

使用Web服务器来为您在步骤1中生成的转换模型文件提供服务。请注意,为了允许JavaScript获取文件,您可能需要配置服务器以允许跨源资源共享(CORS)。

然后通过提供model.json文件的URL将模型加载到TensorFlow.js中:

// JavaScript

import * as tf from '@tensorflow/tfjs';

const model = await tf.loadModel('https://foo.bar/tfjs_artifacts/model.json');

现在该模型已准备好进行推理,评估或重新训练。例如,加载的模型可以立即用于预测:

// JavaScript

const example = tf.fromPixels(webcamElement);  // for example
const prediction = model.predict(example);

TensorFlow.js Examples中的很多例子都采用此方法,使用已在Google云端存储上转换并托管的预训练模型。

请注意,您使用model.json文件名来引用整个模型。 loadModel(...)获取model.json,然后发出额外的HTTP(S)请求以获取model.json权重清单中引用的权重文件分片。这种方法允许所有这些文件被浏览器缓存(也可能通过互联网上的其他缓存服务器),因为model.json和weight shard分别小于典型的缓存文件大小限制。因此,模型可能会在随后的场合更快加载。

 

支持的功能

TensorFlow.js Layers目前仅支持使用标准Keras构造的Keras模型。使用了不受支持的操作或层(例如自定义层,Lambda层,自定义损失或自定义指标)的模型将无法自动导入,因为它们所依赖的Python代码无法正确地转换为JavaScript。

 

机器学习资源

使用Tensorflow.js进行机器学习需要一些列不同的只是,尤其是机器学习,神经网络,Javascript,Node.js以及浏览器开发这些方面。取决于你的背景你可能对其中的一个或一些知识领域并不熟悉。这里有很多优秀的在线学习资源,本页将重点介绍一些资源,以帮助用神经网络引导您的机器学习知识。

 

高水平介绍

我们推荐您可以从下列视频获取高水平的深度学习以及Tensorflow.js的介绍。

 

TensorFlow.js 介绍

下列资源诸着重介绍了Tensorflow.js同时也涉及了机器学习的基本知识。

 

综合课程

下列是综合的深度学习在线课程。大部分课程使用python作为主要语言。然而,即使语法没有涉及但是这些概念也可以被转换在Tensorflow.js上。

 

综合书籍

 

数学概念

机器学习是一门需要一定数学基础的学科,如果你只是需要使用机器学习模型,那么理解模型背后的数学原理是没有必要的。如果你计划调整机器学习模型或是从头建立一个模型,那么熟悉基本的数学概念对您是有帮助的。 你不必预先学习所有的数学知识,而是可以在遇到不熟悉的概念时查找并学习它们。

2017-12-19 09:32:29 kwame211 阅读数 317
  • AI时代,机器学习该如何入门?

    机器学习入门视频教程,该课程会告诉大家如何入门机器学习,掌握机器学习必要的基础知识,了解机器学习路径。对于机器学习,很多人的观点是:机器学习技术是今后所有技术人员都绕不过的一个门槛。 那么,普通程序员该学习机器学作为一名对机器学习心有向往的程序员,我该以什么样的姿势开始呢?不妨看看该课程。

    7185 人正在学习 去看看 CSDN讲师

垃圾邮件过滤、面部识别、推荐引擎——当你有一个大数据集,你想要进行预测分析或模式识别时,机器学习是一种方法。自由开源软件的普及使得机器学习更容易在单台机器和规模上实现,并且在大多数流行的编程语言中也能实现。这11个开源工具包括了Python、R、c++、Java、Scala、Clojure、JavaScript和Go等的库。






Scikit-learn

Python已经成为数学、科学和统计方面的首选编程语言,因为它易于采用,而且几乎任何应用程序都可以使用这些库。scikit- learn通过在几个现有的Python包——numpy、SciPy和matplotlib——上构建数学和科学工作,利用了这一广度。生成的库可以用于交互式的“工作台”应用程序,或者嵌入到其他软件中并重新使用。该工具包在BSD许可下可用,因此它是完全开放和可重用的。

Project: scikit-learn

GitHub:https://github.com/scikit-learn/scikit-learn


Shogun(幕府)

尊敬的Shogun创建于1999年,并以c++编写,但可以使用Java、Python、c#、Ruby、R、Lua、Octave和Matlab。最新的版本是6.0.0,增加了对Microsoft Windows和Scala语言的本机支持。虽然广受欢迎,但Shogun却有竞争。另一个基于c++的机器学习库MLpack,自2011年以来就一直在使用,但是它声称比竞争库更容易使用(通过更完整的API集)。

Project:Shogun

GitHub:https://github.com/shogun-toolbox/shogun


Accord.Net Framework

Accord,机器学习和信号处理框架。.Net是之前一个项目的扩展,协议包括一组用于处理音频信号和图像流的库(如视频)。它的视觉处理算法可以用于人脸检测、拼接图像或追踪移动对象等任务。协议还包括提供更传统的机器学习功能的库,从神经网络到决策树系统。

Project:Accord.Net Framework

GitHub:https://github.com/accord-net/framework/


Apache Mahout

Apache Mahout长期以来与Hadoop捆绑在一起,但它旗下的许多算法也可以在Hadoop之外运行。它们对于独立应用程序非常有用,这些应用程序最终可能会迁移到Hadoop或Hadoop项目中,这些项目可能会被拆分为独立的应用程序。最后几个版本增强了对高perfomance Spark框架的支持,并增加了对GPU加速线性代数的ViennaCL库的支持。

Project:Apache Mahout

官网:https://mahout.apache.org/


Spark MLlib

MLlib是Apache Spark和Apache Hadoop的机器学习库,它拥有许多常见的算法和有用的数据类型,设计以速度和规模运行。尽管Java是在MLlib工作的主要语言,Python用户可以将MLlib与NumPy库连接起来,Scala用户可以编写针对MLlib的代码,并且R用户可以在1.5版中插入Spark。另一个项目,MLbase,建立在MLlib之上,使其更容易获得结果。用户不需要编写代码,而是通过一种声明式语言à la来进行查询。

Project:Spark MLlib

官网:https://spark.apache.org/mllib/


H2O

未命名1511147383.png

H2O的算法主要针对业务流程——比如欺诈或趋势预测——而不是图像分析。H2O可以以独立的方式与HDFS存储、在YARN、MapReduce中,或者直接在Amazon EC2实例中交互。Hadoop mavens可以使用Java与H2O进行交互,但该框架还为Python、R和Scala提供了绑定,允许您与这些平台上的所有库交互。

Project:H2O

GitHub:https://github.com/0xdata/h2o


Cloudera Oryx

未命名1511147392.png

Oryx是Cloudera Hadoop发行版的创建者,它使用Spark和Kafka流处理框架来运行实时数据的机器学习模型。Oryx提供了一种方法来构建需要决策的项目,比如推荐引擎或实时异常检测,这些都是由新的和历史数据提供的。版本2.0是对项目的近乎完全的重新设计,其组件在lambda体系结构中松散耦合。新的算法,以及这些算法的新抽象,对于超参数选择,可以随时添加。

Project:Cloudera Oryx

GitHub:https://github.com/cloudera/oryx


GoLearn

未命名1511147400.png

据开发人员斯蒂芬·惠特沃斯(Stephen Whitworth)说,GoLearn是一个为谷歌的Go语言学习的机器学习库,它的目标是简单和可定制。它的简单性在于数据在库中加载和处理的方式,这种方式是在SciPy和R语言之后进行的,而定制的功能在于如何在应用程序中轻松地扩展某些数据结构。惠特沃斯还为Vowpal Wabbit库创建了一个Go包装器,这是在Shogun工具箱中发现的一个库。

Project:GoLearn

GitHub:https://github.com/sjwhitworth/golearn


Weka

未命名1511147408.png

Weka是一组专门用于数据挖掘的Java机器学习算法。这个GNU gplv3许可的集合有一个包系统来扩展它的功能,包括官方的和非官方的软件包。Weka甚至还带了一本书来解释软件和使用的技术。虽然Weka并没有专门针对Hadoop用户,但由于一组包装器,最新的版本可以与Hadoop一起使用。注意,Weka还不支持Spark,只有MapReduce。Clojure用户可以通过clj - ml库利用Weka。

Project:Weka

官网:http://www.cs.waikato.ac.nz/ml/weka/


Deeplearn.js

未命名1511147417.png

在web浏览器中深度学习的另一个项目,Deeplearn.js,通过谷歌来实现。神经网络模型可以直接在任何现代浏览器中进行训练,而不需要额外的客户端软件。Deeplearn.js还可以通过WebGL API进行gpu加速计算,因此性能并不局限于系统的CPU。项目中可用的函数是在谷歌的TensorFlow之后形成的,这使得该项目的用户可以轻松地开始使用这个项目。

Project:Deeplearn.js

官网:https://pair-code.github.io/deeplearnjs/


ConvNetJS

未命名1511147424.png

顾名思义,ConvNetJS是一个用于神经网络机器学习的JavaScript库,便于使用浏览器作为数据工作台。对于使用节点的用户,也可以使用NPM版本。js和库的设计是为了正确使用JavaScript的异步性。例如,培训操作一旦完成就可以执行回调。还包括了大量的演示示例。

Project:ConvNetJS

GitHub:https://github.com/karpathy/convnetjs

2017-03-18 22:01:34 u012986684 阅读数 939
  • AI时代,机器学习该如何入门?

    机器学习入门视频教程,该课程会告诉大家如何入门机器学习,掌握机器学习必要的基础知识,了解机器学习路径。对于机器学习,很多人的观点是:机器学习技术是今后所有技术人员都绕不过的一个门槛。 那么,普通程序员该学习机器学作为一名对机器学习心有向往的程序员,我该以什么样的姿势开始呢?不妨看看该课程。

    7185 人正在学习 去看看 CSDN讲师

机器学习 (Machine Learning,ML)

1、定义:研究开发一系列的算法,不需要外部明显的指示,只需要数据来学习,建模,并且利用建好的模型和新的输入来预测的学科。

例子:下棋、语音识别、自动驾驶等。

学习:E、T、P (经验、任务、衡量)


2、目前的应用:

语音识别

自动驾驶(google)

https://www.youtube.com/watch?v=cdgQpa1pUUE

语音翻译(micosoft )

https://www.youtube.com/watch?v=Nu-nlQqFCKg

计算机视觉

推荐系统(淘宝、亚马逊等)

无人机(亚马逊运输)

https://www.youtube.com/watch?v=w2itwFJCgFQ

识别垃圾邮件(gmail)


3、Demo:

人脸识别

无人驾驶汽车

https://www.youtube.com/watch?v=cdgQpa1pUUE

电商推荐系统



2017-07-07 15:28:07 u011001084 阅读数 310
  • AI时代,机器学习该如何入门?

    机器学习入门视频教程,该课程会告诉大家如何入门机器学习,掌握机器学习必要的基础知识,了解机器学习路径。对于机器学习,很多人的观点是:机器学习技术是今后所有技术人员都绕不过的一个门槛。 那么,普通程序员该学习机器学作为一名对机器学习心有向往的程序员,我该以什么样的姿势开始呢?不妨看看该课程。

    7185 人正在学习 去看看 CSDN讲师

https://mp.weixin.qq.com/s/N6aEUn7J2H48J8XZ4pmvAg

基于 JavaScript 的机器学习?!没错,是 基于 JavaScript 的机器学习!关注前端之巅系列文章——《机器学习与 JavaScript》,利用 JavaScript 开启机器学习之路! 基于 JavaScript 的机器学习?

你应该觉得基于 JavaScript 的机器学习不简单吧?

JAVASCRIPT?!我难道不应该用 Python 么?我难道要用 JavaScript 去做如此复杂的运算?难道我不应该使用 Python 或者 R 语言么?scikit-learn 算法库会不会不能在 JavaScript 中使用?简单来说:基于 JavaScript 的机器学习完全没有问题。

详细来讲,基于 JavaScript 的机器学习是有可能的,并且我总是很吃惊为什么开发者们没有给予它应有的关注。就 scikit-learn 算法库而言,JavaScript 开发者已经开发了一系列实现该算法的库,一会儿就会用到一个库。接下来会先讲一点机器学习的知识,然后就放松心情一起来看代码吧。

据 Arthur Samuel 所讲,机器学习 就是在不对其进行具体编程的情况下,使计算机拥有学习的能力。换句话说,它在我们不操作计算机的情况下,却能拥有自我学习的能力,并能执行正确的指令。并且谷歌公司已经将策略从移动优先转变为 AI 优先很长一段时间了。

 为什么在机器学习领域没有提到 JavaScript 呢?
  1. JavaScript 很慢。(完全错误的观念 !?! )

  2. JavaScript 很难进行矩阵操作。(但是有很多库的,比如math.js

  3. JavaScript 仅仅被认为是用来做 web 开发的。(Node.js 默默的笑了)

  4. 机器学习中很多库都是基于 Python 开发的。(那是因为 JavaScript 开发者并没有在场)

现在已经有很多的 JavaScript 库了,它们已经预定义了机器学习算法,比如:线性回归、支持向量机、朴素贝叶斯算法等,以下列出了几个库:

  1. brain.js(神经网络)

  2. Synaptic(神经网络)

  3. Natural(自然语言处理)

  4. ConvNetJS(卷积神经网络)

  5. mljs(一种具有多个函数方法的子库)

 开启 JavaScript 的机器学习之路

我将使用mljs的回归库来执行线性回归模型的分析。全部代码都在 Github 上:machine-learning-with-js(https://github.com/abhisheksoni27/machine-learning-with-js )。

第一步. 安装依赖的库

$ yarn add ml-regression csvtojson

或者你更喜欢 npm:

$ npm install ml-regression csvtojson

ml-regression所做的事正如它的名字那样,机器学习线性回归库。

csvtojson是在node.js环境中的一个cvs数据解析器,它可以在你加载完cvs 数据后将其快速的转换为JSON

第二步. 初始化依赖库并加载数据

首先从 这里 下载数据文件,并将数据文件放在你的工程目录中。假设你已经初始化了一个空的 npm 工程,打开index.js文件,并输入以下代码:(你可以直接复制 / 粘贴,但为了能够更好的理解它,建议你能亲自输入这段代码)

const ml = require('ml-regression');
const csv = require('csvtojson');
const SLR = ml.SLR; // 简单线性回归
const csvFilePath = 'advertising.csv'; // 数据文件
let csvData = [], // 已解析的数据
    X = [], // 输入
    y = []; // 输出
let regressionModel;

我把这个文件放在了项目的根目录下,因此如果你放在了别的目录下,请同时更改上述代码中的csvFilePath变量。

这样的代码看起来相当整洁,不是么?

接下来使用csvtojson库的fromFile方法加载数据文件。

csv()
    .fromFile(csvFilePath)
    .on('json', (jsonObj) => {
        csvData.push(jsonObj);
    })
    .on('done', () => {
        dressData(); // 从 JSON 对象中获取数据点
        performRegression(); 
    });

第三步. 将数据加以装饰,以准备开始执行

保存在csvData变量中的 JSON 对象已经准备好了,同时还分别需要一个数组,用来存储输入点数据和输出点数据。然后将通过dressData函数来运行数据,且dressData函数将会计算出XY变量。

function dressData() {
    /**
     * 一个数据对象应该这样:
     * {
     *   TV: "10",
     *   Radio: "100",
     *   Newspaper: "20",
     *   "Sales": "1000"
     * }
     *
     * 因此,在添加数据点的同时,
     * 我们需要将 String 类型的值解析为 Float 类型。
     */
    csvData.forEach((row) => {
        X.push(f(row.Radio));
        y.push(f(row.Sales));
    });
}
function f(s) {
    return parseFloat(s);
}

第四步. 训练模型,并开始进行预测

现在数据已经装饰好了,是时候来训练模型了。

为了实现这一目标,我们需要一个performRegression函数:

function performRegression() {
    regressionModel = new SLR(X, y); // 基于训练数据来训练模型
    console.log(regressionModel.toString(3));
    predictOutput();
}

regressionModel有一个toString方法,它所接收的参数代表输出值浮点数的精度。

predictOutput方法能够接收所输入的值,并且向终端输出所预测的值。

以下就是这个函数的代码:(这里使用了node.jsreadline模块)

function predictOutput() {
    rl.question('Enter input X for prediction (Press CTRL+C to exit) : ', (answer) => {
        console.log(`At X = ${answer}, y =  ${regressionModel.predict(parseFloat(answer))}`);
        predictOutput();
    });
}

以下代码读取了用户的输入值:

const readline = require('readline'); // 同时预测用户的输入值
const rl = readline.createInterface({
    input: process.stdin, 
    output: process.stdout
});

第五步. 恭喜你!做到了。

如果你跟着我一步一步的做,现在你的index.js文件应该是这样子的:

const ml = require('ml-regression');
const csv = require('csvtojson');
const SLR = ml.SLR; // 简单线性回归
const csvFilePath = 'advertising.csv'; // 数据
let csvData = [], // 已解析的数据
    X = [], // 输入
    y = []; // 输出
let regressionModel;
const readline = require('readline'); // 同时预测用户的输入值
const rl = readline.createInterface({
    input: process.stdin, 
    output: process.stdout
});
csv()
    .fromFile(csvFilePath)
    .on('json', (jsonObj) => {
        csvData.push(jsonObj);
    })
    .on('done', () => {
        dressData(); // 从 JSON 对象中获取数据点
        performRegression(); 
    });
function performRegression() {
    regressionModel = new SLR(X, y); // 基于训练数据来训练模型
    console.log(regressionModel.toString(3));
    predictOutput();
}
function dressData() {
    /**
     * 一个数据对象应该这样:
     * {
     *   TV: "10",
     *   Radio: "100",
     *   Newspaper: "20",
     *   "Sales": "1000"
     * }
     *
     * 因此,在添加数据点的同时,
     * 我们需要将 String 类型的值解析为 Float 类型。
     */
    csvData.forEach((row) => {
        X.push(f(row.Radio));
        y.push(f(row.Sales));
    });
}
function f(s) {
    return parseFloat(s);
}
function predictOutput() {
    rl.question('Enter input X for prediction (Press CTRL+C to exit) : ', (answer) => {
        console.log(`At X = ${answer}, y =  ${regressionModel.predict(parseFloat(answer))}`);
        predictOutput();
    });
}

打开终端,输入并运行node index.js,它将会输出如下所示内容:

$ node index.js
f(x) = 0.202 * x + 9.31
Enter input X for prediction (Press CTRL+C to exit) : 151.5
At X = 151.5, y =  39.98974927911285
Enter input X for prediction (Press CTRL+C to exit) :

恭喜你!刚刚用 JavaScript 训练了你的第一个线性回归模型。(你有注意到它的速度么?)

PS: 我将使用 ml 和其他的库(上面所列出的那些)在各种数据集上执行目前比较流行的机器学习算法。请时刻关注我的动态,获取最新的机器学习教程。

感谢你的阅读! 如果你喜欢这篇文章的话,请为我点赞,以让别人知道 JavaScript 是多么的强大,以及为什么在机器学习领域中 JavaScript 不应该落后。

 英文原文链接

Machine Learning with JavaScript : Part 1

https://hackernoon.com/machine-learning-with-javascript-part-1-9b97f3ed4fe5


JS遇见tensorflow.js

阅读数 109

没有更多推荐了,返回首页