介绍
之前介绍了tfjs的核心功能,这次我们将使用TensorFlow.js将曲线拟合到合成数据集。
使用一个多项式生成数据,然后训练模型预测生成数据的系数
代码
运行的是tfjs官方的代码:下载链接
本地运行如果安装了yarn,直接执行:
1 2 | yarn yarn watch |
yarn 下载地址:链接
win10,yarn watch时如果出现错误显示:‘NODE_ENV’ 不是内部或外部命令,也不是可运行的程序
把package.json的内容:
1 2 3 4 | "scripts": { "watch": "NODE_ENV=development parcel --no-hmr --open index.html ", "build": "NODE_ENV=production parcel build index.html --no-minify --public-url ./" } |
修改为
1 2 3 4 | "scripts": { "watch": "set NODE_ENV=development && parcel --no-hmr --open index.html ", "build": "set NODE_ENV=production && parcel build index.html --no-minify --public-url ./" } |
可以直观看出曲线的拟合过程。
输入数据
这个图标的数据使用的是三次函数
我们任务是学习这个函数的系数:a,b,c和d最适合数据的值。
第1步:设置变量
首先,我们将为每个变量分配一个随机数:
1 2 3 4 | 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步:建立模型
用tfjs创建公式,构造一个predict
函数,x作为输入并返回y:
1 2 3 4 5 6 7 8 9 | 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 }); } |
第3步:训练模型
我们的最后一步是训练模型以学习系数的良好值。为了训练我们的模型,我们需要定义三件事情:
- 损失函数,衡量一个多项式符合程度的数据。损失值越低,多项式越拟合。
- 优化器,根据损失函数的输出执行修正我们的系数值的算法。优化器的目标是最小化损失函数的输出值。
- 循环训练,它将迭代地运行优化器以最小化损失。
定义损失函数
我们将使用均方误差(MSE)作为我们的损失函数。通过对我们的数据集中每个x值的实际y值和预测y值之间的差值进行平方,然后取所有结果项的平均值,计算MSE 。
我们可以在TensorFlow.js中定义一个MSE损失函数,如下所示:
1 2 3 4 5 | function loss(predictions, labels) { // 从预测中减去我们的标签(实际值),对结果进行平方,并取平均值。 const meanSquareError = predictions.sub(labels).square().mean(); return meanSquareError; } |
定义优化器
对于我们的优化器,我们将使用随机梯度下降(SGD)。SGD通过获取数据集中随机点的梯度并使用其值来通知是增加还是减少模型系数的值。
TensorFlow.js为执行SGD提供了一种便利功能,并且返回SGDOptimizer
可以被调用以优化损失函数的值的对象。
学习率控制了模型在改进预测时的调整量。低学习率会使学习过程运行得更慢(需要更多的训练迭代来学习好的系数),而高学习率会加速学习,但可能会导致模型围绕正确的值振荡,总是过度矫正。
以下代码构造了SGD优化器,学习率为0.5:
1 2 | const learningRate = 0.5; const optimizer = tf.train.sgd(learningRate); |
定义训练循环
现在我们已经定义了我们的损失函数和优化器,我们可以构建一个训练循环,迭代执行SGD以优化模型的系数以最小化损失(MSE):
1 2 3 4 5 6 7 8 9 10 11 12 | 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值以及指定的迭代次数作为输入:
1 2 3 | function train(xs, ys, numIterations) { ... } |
接下来,我们将定义学习率和SGD优化器,如前一节所述:
1 2 | const learningRate = 0.5; const optimizer = tf.train.sgd(learningRate); |
最后,我们建立一个for
运行numIterations
训练迭代的循环。在每次迭代中,我们都调用minimize
优化器:
1 2 3 4 5 6 | for (let iter = 0; iter < numIterations; iter++) { optimizer.minimize(() => { const predsYs = predict(xs); return loss(predsYs, ys); }); } |
minimize
需要一个可以做两件事的功能:
- 1.它使用我们前面在步骤2中定义的预测模型函数来预测所有x值的y值(predY)。
- 2.它使用我们在定义损失函数中定义的损失函数返回那些预测的均方误差损失。
minimize
然后自动调整此函数使用的任何变量(这里是系数a,b,c和d),以便将返回值(我们的损失)降至最低。
运行我们的训练循环之后,a,b,c和d将包含75次迭代SGD后由模型学习的系数值。
结果
程序结束运行,我们可以获取变量a,b,c和d的最终值,并使用它们绘制曲线:
- 本文链接: http://www.stevenke.com/2018/tensorflowjs-fitting.html
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!