前言
tensorflow 是Google的开源的深度学习框架,本次分享下利用该框架计算出一个线性回归参数的预测实践,以及训练后如何将模型转化为web端可以使用的模型。
TensorFlow的官方地址:https://www.tensorflow.org/ ;
js版本的官方地址: https://js.tensorflow.org/ ;
转化为web端可以使用的工具地址:https://github.com/tensorflow/tfjs-converter ;
构造数据
机器学习中,训练模型需要大量的数据,本文为了演示,我们通过代码生成数据。
1. 从 [0, 10]之间提取出30个均匀间隔的数字,作为x轴数据;
2. 通过一个线性函数生成y轴数据,其中参数w、参数b就是我们要预测的数据;
实现如下:
import numpy as np
data_x = np.linspace(0,10,30)
// w=3、b=7+np.random.normal(0,1,30) ;这里我们加个噪声,更加接近真实数据
data_y = data_x * 3 + 7 + np.random.normal(0,1,30)
我们可以绘制下该数据集:
import matplotlib.pyplot as plt
#%matplotlib inline
plt.scatter(data_x, data_y)
运行后可以看到,是一条由多个点组成的按照一定斜率生成的直线。
实现
一般我们实现机器学习的过程,有以下几个步骤:
1. 定义参数。参数就是我们要预测的目标;
2. 输入训练数据。一般我们会预先定义占位符,用来输入训练数据;
3. 执行推断。我们通过绘制图形可以推断出,是个一次函数;
4. 计算损失。损失函数用来评估模型的预测值跟真实值不一样的程度,一般对分类或者回归模型进行评估时,需要使得模型在训练数据上使得损失函数值最小。为减少预测失误,线性回归的损失函数一般为平方差损失;
5. 训练模型,减少损失。一般我们的模型用梯度下降算法,这个是tensorFlow的核心算法,tensorflow提供了多个梯度下降算法,这里我们就使用最简单的tf.train.GradientDescentOptimizer方法。梯度下降算法理论介绍
6. 评估效果。
定义参数
上面我们已经讲解过,该步骤我们需要定义w
和b
两个变量。
示例:
import tensorflow as tf
w = tf.Variable(1.,name='quanzhong')
b = tf.Variable(0.,name='pianzhi')
定义占位符,作为输入训练数据
x、y 数据类型我们定义为float32,其中x为、y为一维数组结构。
示例:
x = tf.placeholder(tf.float32, shape=[None])
y = tf.placeholder(tf.float32, shape=[None])
执行推断
这里我们可以通过绘制数据集的图形来推断值为: pred = x*w+b;
示例:
pred = tf.multiply(x, w) + b
计算损失
上面我们讲过,对回归模型进行评估时,需要使得模型在训练数据上使得损失函数值最小。为减少预测失误,线性回归的损失函数一般为平方差损失。tensorflow提供了 tf.squared_difference
方法计算平方差,计算后我们还要调用tf.reduce_sum
对结果进行矩阵降维求和。
loss = tf.reduce_sum(tf.squared_difference(pred, y))
训练模型,减少损失
首先我们手动定义一个学习速率,该值越大训练数据越快,同时精度会降低;越小,精度会提升,但训练数据越慢;
learn_rate = 0.0001
调用 GradientDescentOptimizer 梯度下降算法,目标为最小化loss
train_step = tf.train.GradientDescentOptimizer(learn_rate).minimize(loss)
训练
TensorFlow中,当运行时,我们需要创建一个会话,且为了性能,整个过程最好只有一个会话。
sess = tf.Session()
TensorFlow中,我们还需要初始化之前定义的变量。
sess.run(tf.global_variables_initializer())
接下来我们开始训练, 训练执行:sess.run(train_step, feed_dict={x:data_x,y:data_y})
, 其中 train_step为我们要训练的模型,我们通过feed_dict
传入之前构造的训练数据。
训练一万步
for i in range(10000):
sess.run(train_step, feed_dict={x:data_x,y:data_y})
if i%1000 == 0:
print(sess.run([loss,w,b], feed_dict={x:data_x,y:data_y}))
评估效果
这里我们就预测当x=12时,根据训练推断的y值是否接近真实值。
print(sess.run(12*w+b))
根据打印结果,训练效果还是很接近真实值的。
模型保存和转化
为了在web端使用训练好的模型,我们需要将模型保存下来,我们使用官方提供的tf.saved_model
实现。
builder = tf.saved_model.builder.SavedModelBuilder('E:\program\Learn\机器学习\实践\线性回归\Model\saved_model')
builder.add_meta_graph_and_variables(sess, ['tag_string'])
builder.save()
上面我们将模型保存到本地,且模型标签为 tag_string
;
我们还可以打印出上面模型的图节点
graph = sess.graph
print([node.name for node in graph.as_graph_def().node])
接下来我们将模型转化为 tensorflowjs可以使用的格式。我们使用官方提供了 tfjs-converter 工具,详情请参考官方文档。
dos下我们进入项目目录,执行命令:tensorflowjs_converter --input_format=tf_saved_model --output_node_names='add_1' saved_model_tags='tag_string' Model/saved_model Model/model_web
;
然后我们在web项目中新增导入模型的js:
import * as tf from '@tensorflow/tfjs';
import {loadFrozenModel} from '@tensorflow/tfjs-converter';
const MODEL_URL = '../model_web/tensorflowjs_model.pb';
const WEIGHTS_URL = '../model_web/weights_manifest.json';
(async () => {
const tf = window.tf;
const model = await loadFrozenModel(MODEL_URL, WEIGHTS_URL);
console.log(model)
})();
访问页面后,控制台将打印出模型数据。