线性回归
我们将解决一个简单的线性回归任务。线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。如果只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。
表达形式为 y = w•x+b
- 在这上图例子里面,x是独立变量,y随着x的改变而改变,大致符合
Y = 0.5 * X + 2
模组安装与引入
pip install numpy
pip install matplotlib
# 这里我们安装2.0版本,2.0具有更加友好的API
pip install tensorflow==2.0.0-beta1
# linear_regression.py
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
print(tf.__version__)
# 输出 2.0.0-beta1
生成模拟数据
这里生成一组符合 Y = 0.5 * X + 2 的数据,为了让数据稍微不规则一些,会加上一个噪点值(均值是0 、标准差0.05),如果标准差太大,数据会变得太散,会很难直观地看出X与Y的关系。
# 在返回(-1, 1)范围内的等差序列,生成200个数字
X = np.linspace(-1, 1, 200)
# 打乱顺序
np.random.shuffle(X)
# 生成Y并添加噪声
Y = 0.5 * X + 2 + np.random.normal(0, 0.05, 200))
# 画图
plt.scatter(X, Y)
plt.show()
创建模型
接下来,我们将创建训练模型(神经网络)来解决我们的线性回顾任务,以下几句就是我们的模型。
# 构建神经网络模型
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1, input_shape=[1])
])
我们这里使用了TensorFlow 集成的 Keras API来创建神经网络,tf.keras.Sequential()
方法是初始化神经网络。
- Keras 是神经网络的高阶API,友好、伸缩性强,可以适应所有模型的构建。在2017年推出的时候,被大众所拥戴,现在 Kears已经集成进了Tensorflow 。
- tf.keras.Sequential()方法接一组神经网络层作为参数。在我们的例子中,我们只有一个
稠密 (Dense)
连接层,Dense
层可以看作是一个线性操作者,将所有的X
输入值根据y = w•x+b
的规则转为输出值Y
,这里的w
称为权重(weight)
,b
称为偏置值(bias)
。因为每个节点只有一个输入,所以units=1
指定了只有一个输入。第二个参数input_shape=[1]
指定了输入的形状为一阶张量
,并只有一个值。 - 在我们的例子中,我们的神经网络只有一个输入节点,因为我们的线性回归问题,只是需要解决一个自变量
X
与一个因变量Y
的对应关系。我们这个模型只有一个神经网络层,以及一个神经元。
根据这个简单的神经网络例子,我们可以更加深入地理解神经网络的工作方式。每一次优化练习,每个神经元
都会改变他的权重(wieght)
。而经过神经元的数据,都会与他的权重相乘,在该神经元处理完之后,会再加上一个偏置值(bias)
,如下图所示。
现在我们可以看出,虽然这里只有一层神经网络,也只有一个神经元,但是却能够足以解决我的问题。模型经过训练之后,神经元
会计算出权重 0.5
和偏置值 2
,组成一个公式,根据输入值X计算输出值Y。
搭建完模型之后,我们就要编译我们的模型了(设置运行的规则)。目的是从训练组中找出对应的模型(规律),以及在测试组验证这个模型(规律)的时候,能得到较高的准确性。代码如下
# 选定loss函数和优化器
model.compile(loss='mean_squared_error',
optimizer=tf.keras.optimizers.Adam(0.1))
这里我们要指定用哪一个损失函数
和哪一个优化迭代器
损失函数
是机器学习中的一概念,用来测量预测值与真实数之间差距的函数。如果损失函数的值越小,代表预测的准确性越高,这里指定的损失函数是mean_squared_error
,也就是方差
,是预测值与真实值的方差,是比较常用的一个损失函数。优化器
是指在找出最小的损失函数实用的方法,这里用的是Adam
(short for Adaptive Moment Estimation),是随机梯度下降算法的扩展式,是个比较常用的优化算法。这里指定学习速率是0.1,默认的是0.001,学习很多次才能把损失值降到最低,所以提高学习速率,减少学习次数。
训练模型
现在模型已经准备就绪,下一步要做的事情就是用我们的训练数据,给模型进行训练了。(这里已经把训练数据与测试数据分开,这是为了避免在训练中学习到了测试数据,进而影响测试结果。就比如考卷和课本的题目不完全相同)代码如下。
history = model.fit(X_train, Y_train, epochs=100, verbose=1)
# 画出损失函数的图
plt.xlabel("Epoch Number")
plt.ylabel("Loss Magnidute")
plt.plot(history.history['loss'])
plt.show()
- 第一、第二个参数就是分别是我们的X和Y,第三个参数是训练次数,最后一个参数verbose是表示在训练过程中是否打印过程数据,1表示显示。
- 最后画出损失函数的图。
从上图可以看出,经过100次的训练之后,损失函数的值已经快接近0了,这表明我们的模型有很高的准确性。
预测
我们的模型现在已经训练完成,在训练数据中表现得不错,现在我们用我们的测试数据进行一次检验。
# 测试
lost = model.evaluate(X_test, Y_test, batch_size=40, verbose=0)
print('test lost:', lost)
# 将训练结果绘出
Y_pred = model.predict(X_test)
plt.scatter(X_test, Y_test)
plt.plot(X_test, Y_pred)
plt.show()
-
model.evaluate
方法是用于预测数据,并返回损失值,每次运行后的结果都大致相同。本次的损失值是test lost: 0.00303063599858433
,和训练是的损失值0.0028
非常接近,表明模型非常准确。
查看权重Weights与偏置值biases
我们可以查看神经网络中神经元的权重与偏置值,运行以下代码
W, b = model.layers[0].get_weights()
print('Weights=', W, '\nbiases=', b)
- 得到结果
Weights= [[0.49035308]]
biases= [1.9925859]
,
0.49035308
与1.9925859
跟我们定的公式Y = 0.5 * X + 2
相当接近,因为我们还有噪点值的存在,所以结果的值与我们预设的值稍微有点偏差。
参考文章
the-machine-learning-crash-course-part-2-linear-regression
線性回歸
张量
降低损失:迭代方法
降低损失:学习速率