tensorflow.js采用了和Python中tensorflow类似的API,但目前还有许多Python中的接口并未支持,并且由于语言特性的限制,tensorflow.js与Python中tensorflow的使用方法并不完全一致。本篇笔记通过对比在Python及JavaScript环境下实现相同的功能,学习tensorflow.js的不同之处。
1、拟合空间平面
1.1 Python
import tensorflow as tf
import numpy as np
# 使用 NumPy 生成假数据100个
x_data = np.float32(np.random.rand(2, 100))
y_data = np.dot([0.100, 0.200], x_data) + 0.300
通过numpy生成100个点,y = 0.1 * x1 + 0.2 * x2 + 0.3计算y值。
# 构造一个线性模型
W = tf.Variable(tf.random_uniform([1, 2]))
b = tf.Variable(tf.zeros([1]))
y = tf.matmul(W, x_data) + b
# 最小化方差
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
W初始设定为一个随机1*2向量,b为0,y = Wx + b。之后设损失函数为均方差,学习率为0.5,优化器为梯度下降。
# 初始化变量
# 已弃用 init = tf.initialize_all_variables()
init = tf.global_variables_initializer()
# 启动图 (graph)
sess = tf.Session()
sess.run(init)
# 拟合平面
for step in range(0, 201):
sess.run(train)
if step % 10 == 0:
print(step, sess.run(W), sess.run(b))
通过tf.global_variables_initializer()初始化变量,启动图,并迭代训练200次,每10个点打印“步长”、“权值W”、“常数项b”,结果如下。
1.2 JavaScript
import * as tf from '@tensorflow/tfjs';
const w = tf.variable(tf.randomUniform([1, 2]));
const b = tf.variable(tf.scalar(Math.random()));
const numIterations = 201;
const learningRate = 0.5;
const optimizer = tf.train.sgd(learningRate);
随机初始化w、b,设定迭代次数、学习率、优化器。
function generateData(numPoints, coeff, sigma = 0.04) {
return tf.tidy(() => {
const [_w, _b] = [
tf.variable(tf.tensor2d(coeff.w, [1, 2])),
tf.scalar(coeff.b)
];
const xs = tf.variable(tf.randomUniform([2, numPoints]));
const ys = tf.matMul(_w, xs).add(_b);
return {xs, ys};
});
}
generateData返回随机生成的100个xs,及相应的ys。
function predict(x) {
return tf.tidy(() => {
return tf.matMul(w, x).add(b);
});
}
function loss(prediction, label) {
const error = prediction.sub(label).square().mean();
return error;
}
async function train(xs, ys, numIterations) {
for (let iter = 0; iter < numIterations; iter++) {
optimizer.minimize(() => {
const pred = predict(xs);
return loss(pred, ys);
});
if (iter % 10 === 0) {
console.log(iter, w.dataSync(), b.dataSync());
}
await tf.nextFrame();
}
}
predict函数计算输入的x对应的y值,loss函数计算predict函数预测的y值和实际值的均方差。train函数中optimizer.minimize传入损失函数loss,迭代训练201次并每隔10次在控制台上打印“步长”、“权值W”、“常数项b”。
async function learnCoefficients() {
const trueCoefficients = {w: [0.1, 0.2], b: 0.3};
// 生成有误差的训练数据
const trainingData = generateData(100, trueCoefficients);
// 训练模型
await train(trainingData.xs, trainingData.ys, numIterations);
}
learnCoefficients();
learnCoefficients调用相应函数生成数据并训练模型,结果如下。
完整程序见我的github。