## 2. TensorFlow 中的线性回归
在本章中,我将开始使用简单模型:线性回归来探索 TensorFlow 编程。基于这个例子,我将介绍一些代码基础知识,以及,如何调用学习过程中的各种重要组件,如函数函数或算法梯度下降。
### 变量之间的关系模型
线性回归是一种用于衡量变量之间关系的统计技术。它的有趣之处在于实现它的算法在概念上不复杂,并且还可以适应各种各样的情况。由于这些原因,我发现用线性回归的例子开始深入研究 TensorFlow 很有意思。
请记住,在两个变量(简单回归)和两个以上变量(多元回归)的情况下,线性回归拟合因变量和自变量之间的关系`xi`和随机项`b`。
在本节中,我将创建一个简单的示例来解释 TensorFlow 如何工作,假设我们的数据模型对应简单的线性回归`y = W * x + b`。为此,我使用一个简单的 Python 程序在二维空间中创建数据,然后我会要求 TensorFlow 在这些点上寻找最适合的直线。
首先要做的是导入我们将用于生成点的 NumPy 包。我们创建的代码如下:
```py
import numpy as np
num_points = 1000
vectors_set = []
for i in xrange(num_points):
x1= np.random.normal(0.0, 0.55)
y1= x1 * 0.1 + 0.3 + np.random.normal(0.0, 0.03)
vectors_set.append([x1, y1])
x_data = [v[0] for v in vectors_set]
y_data = [v[1] for v in vectors_set]
```
从代码中可以看出,我们根据关系`y = 0.1 * x + 0.3`生成了点,尽管有一些正态分布的变化,因此这些点并不完全对应一条线,让我们编写一个更有趣的例子。
在我们的例子中,所得到的点云是:
![](https://jorditorres.org/wp-content/uploads/2016/02/image014.png)
读者可以使用以下代码查看它们(这里,我们需要导入`matplotlib`包的一些函数,运行`pip install matplotlib` [13]):
```py
import matplotlib.pyplot as plt
plt.plot(x_data, y_data, 'ro', label='Original data')
plt.legend()
plt.show()
```
这些点是我们将考虑的模型的训练数据集的数据。
### 损失函数和梯度下降算法
下一步是训练我们的学习算法,以便能够获得从输入数据`x_data`估计的输出值`y`。在这种情况下,正如我们事先所知,它是线性回归,我们只能用两个参数表示我们的模型:`W`和`b`。
目标是生成 TensorFlow 代码,它能够找到最佳的参数`W`和`b`,它来自输入数据`x_data`,将其拟合到输出数据`y_data`,我们这里它是一条直线,由`y_data = W * x_data + b`定义。读者知道`W`应接近 0.1 且`b`为 0.3,但 TensorFlow 不知道它,必须自己实现。
解决此类问题的一种标准方法是,遍历数据集的每个值并修改参数`W`和`b`,以便每次都能获得更精确的答案。为了确定我们是否在这些迭代中有所改进,我们将定义一个损失函数(也称为“误差函数”)来衡量某条线有多“好”(实际上是有多“坏”)。
该函数接收参数`W`和`b`,并根据线与数据的拟合程度返回一个误差值。在我们的例子中,我们可以使用均方误差 [14] 作为损失函数。利用均方误差,我们得到“误差”的平均值,基于实际值与算法每次迭代估计值之间距离。
稍后,我将详细介绍损失函数及其替代方法,但对于这个介绍性示例,均方误差有助于我们一步一步向前推进。
现在是时候用 TensorFlow 编写我 解释过的所有内容了。为此,首先我们将使用以下语句创建三个变量:
```py
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b
```
现在,我们可以继续前进,只知道方法`Variable`的调用定义了一个变量,驻留在 TensorFlow 的内部图数据结构中,我在上面已经说过了。 稍后我们将回到方法参数的更多信息,但是现在我认为最好继续前进来推进第一种方法。
现在,通过定义这些变量,我们可以基于每个点与函数`y = W * x + b`计算的点之间的距离,来表示我们之前讨论的损失函数。之后,我们可以计算其平方和的平均值。 在 TensorFlow 中,此损失函数表示如下:
```py
loss = tf.reduce_mean(tf.square(y - y_data))
```
如我们所见,此表达式计算我们知道的`y_data`点与从输入`x_data`计算的点`y`之间的平方距离的平均值。
此时,读者可能已经怀疑最适合我们数据的直线是误差值较小的直线。 因此,如果我们使误差函数最小,我们将找到我们数据的最佳模型。
目前没有太多细节,这就是使函数最小的优化算法,称为梯度下降 [15]。 理论上,梯度下降是一种算法,它接受由一组参数定义的函数,它以一组初始参数值开始,并迭代地移向一组使函数最小的值。 在函数梯度 [16] 的负方向上移动来实现迭代式最小化。 通常计算距离平方来确保它是正的并且使误差函数可微分以便计算梯度。
算法从一组参数的初始值开始(在我们的例子中为`W`和`b`),然后算法以某种方式迭代地调整这些变量的值,在过程结束时,变量的值使成本函数最小。
要在 TensorFlow 中使用此算法,我们只需执行以下两个语句:
```py
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
```
现在,这足以让 TensorFlow 在其内部数据结构中创建相关数据,并且在这个结构中也实现了一个可以由`train`调用的优化器,它是针对定义的成本函数的梯度下降算法。稍后,我们将讨论名为学习率的函数参数(在我们的示例中,值为 0.5)。
### 运行算法
正如我们之前所见,在代码的这个位置上,特定于 TensorFlow 库的调用,只向其内部图添加了信息,而 TensorFlow 的运行时尚未运行任何算法。因此,与前一章的示例一样,我们必须创建会话,调用`run`方法并传递`train`作为参数。另外,因为在代码中我们已经指定了变量,所以我们必须先使用以下调用对它们进行初始化:
```py
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
```
现在我们可以开始迭代过程,这将允许我们找到`W`和`b`的值,它定义最适合输入点的模型直线。 训练过程一直持续到模型在训练数据上达到所需的准确度。 在我们的特定示例中,如果我们假设只有 8 次迭代就足够了,代码可能是:
```py
for step in xrange(8):
sess.run(train)
print step, sess.run(W), sess.run(b)
```
运行此代码的结果表明,`W`和`b`的值接近我们事先知道的值。 在我的例子中,`print`的结果是:
```py
(array([ 0.09150752], dtype=float32), array([ 0.30007562], dtype=float32))
```
并且,如果我们使用以下代码以图形方式显示结果:
```py
plt.plot(x_data, y_data, 'ro')
plt.plot(x_data, sess.run(W) * x_data + sess.run(b))
plt.legend()
plt.show()
```
我们可以用图形方式,看到参数`W = 0.0854`和`b = 0.299`定义的直线,只需 8 次迭代:
![](https://jorditorres.org/wp-content/uploads/2016/02/image016.png)
请注意,我们只执行了八次迭代来简化说明,但如果我们运行更多,参数值会更接近预期值。 我们可以使用以下语句来打印`W`和`b`的值:
```py
print(step, sess.run(W), sess.run(b))
```
在我们的例子中,`print`输出是:
```py
(0, array([-0.04841119], dtype=float32), array([ 0.29720169], dtype=float32))
(1, array([-0.00449257], dtype=float32), array([ 0.29804006], dtype=float32))
(2, array([ 0.02618564], dtype=float32), array([ 0.29869056], dtype=float32))
(3, array([ 0.04761609], dtype=float32), array([ 0.29914495], dtype=float32))
(4, array([ 0.06258646], dtype=float32), array([ 0.29946238], dtype=float32))
(5, array([ 0.07304412], dtype=float32), array([ 0.29968411], dtype=float32))
(6, array([ 0.08034936], dtype=float32), array([ 0.29983902], dtype=float32))
(7, array([ 0.08545248], dtype=float32), array([ 0.29994723], dtype=float32))
```
你可以观察到算法以`W = -0.0484`和`b = 0.2972`(在我们的例子中)的初始值开始,然后算法以一种方式迭代调整变量的值使损失函数最小。
你还可以检查损失函数是否随之减少
```py
print(step, sess.run(loss))
```
在这种情况下,`print`输出是:
```py
(0, 0.015878126)
(1, 0.0079048825)
(2, 0.0041520335)
(3, 0.0023856456)
(4, 0.0015542418)
(5, 0.001162916)
(6, 0.00097872759)
(7, 0.00089203351)
```
我建议读者在每次迭代时绘图,让我们可以直观地观察算法如何调整参数值。 在我们的例子中,8 个截图是:
![](https://jorditorres.org/wp-content/uploads/2016/02/image018.png)
正如读者可以看到的,在算法的每次迭代中,直线更适合数据。 梯度下降算法如何更接近最小化损失函数的参数值?
由于我们的误差函数由两个参数(`W`和`b`)组成,我们可以将它可视化为二维表面。 该二维空间中的每个点代表一条直线。 每个点的函数高度是该直线的误差值。 在该表面上,一些直线产生的误差值小于其他直线。 当 TensorFlow 运行梯度下降搜索时,它将从该表面上的某个位置开始(在我们的示例中,点`W = -0.04841119`和`b = 0.29720169`)并向下移动来查找具有最小误差的直线。
要在此误差函数上运行梯度下降,TensorFlow 会计算其梯度。 梯度将像指南针一样,总是引导我们向下走。 为了计算它,TensorFlow 将对误差函数微分,在我们的情况下意味着它需要计算`W`和`b`的偏导数,它表明每次迭代中要移动的方向。
之前提到的学习率参数控制每次迭代期间 TensorFlow 的每一步的下降程度。 如果我们引入的参数太大,我们可能会越过最小值。 但是,如果我们让 TensorFlow 采取较小步骤,则需要多次迭代才能达到最小值。 因此,使用良好的学习率至关重要。 有不同的技术来调整学习率参数的值,但它超出了本入门书的范围。 确保梯度下降算法正常工作的一种好方法,是确保每次迭代中的误差减小。
请记住,为了便于读者测试本章所述的代码,你可以从本书的 Github [17] 下载`regression.py`。 在这里,你将发现所有东西都在一起以便跟踪:
```py
import numpy as np
num_points = 1000
vectors_set = []
for i in xrange(num_points):
x1= np.random.normal(0.0, 0.55)
y1= x1 * 0.1 + 0.3 + np.random.normal(0.0, 0.03)
vectors_set.append([x1, y1])
x_data = [v[0] for v in vectors_set]
y_data = [v[1] for v in vectors_set]
import matplotlib.pyplot as plt
#Graphic display
plt.plot(x_data, y_data, 'ro')
plt.legend()
plt.show()
import tensorflow as tf
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
for step in xrange(8):
sess.run(train)
print(step, sess.run(W), sess.run(b))
print(step, sess.run(loss))
#Graphic display
plt.plot(x_data, y_data, 'ro')
plt.plot(x_data, sess.run(W) * x_data + sess.run(b))
plt.xlabel('x')
plt.xlim(-2,2)
plt.ylim(0.1,0.6)
plt.ylabel('y')
plt.legend()
plt.show()
```
在本章中,我们已经开始探索 TensorFlow 软件包的可能性,首先采用直观方法处理两个基本组件:损失函数和梯度下降算法,使用基本线性回归算法来介绍。 在下一章中,我们将详细介绍 TensorFlow 包使用的数据结构。
- TensorFlow 1.x 深度学习秘籍
- 零、前言
- 一、TensorFlow 简介
- 二、回归
- 三、神经网络:感知器
- 四、卷积神经网络
- 五、高级卷积神经网络
- 六、循环神经网络
- 七、无监督学习
- 八、自编码器
- 九、强化学习
- 十、移动计算
- 十一、生成模型和 CapsNet
- 十二、分布式 TensorFlow 和云深度学习
- 十三、AutoML 和学习如何学习(元学习)
- 十四、TensorFlow 处理单元
- 使用 TensorFlow 构建机器学习项目中文版
- 一、探索和转换数据
- 二、聚类
- 三、线性回归
- 四、逻辑回归
- 五、简单的前馈神经网络
- 六、卷积神经网络
- 七、循环神经网络和 LSTM
- 八、深度神经网络
- 九、大规模运行模型 -- GPU 和服务
- 十、库安装和其他提示
- TensorFlow 深度学习中文第二版
- 一、人工神经网络
- 二、TensorFlow v1.6 的新功能是什么?
- 三、实现前馈神经网络
- 四、CNN 实战
- 五、使用 TensorFlow 实现自编码器
- 六、RNN 和梯度消失或爆炸问题
- 七、TensorFlow GPU 配置
- 八、TFLearn
- 九、使用协同过滤的电影推荐
- 十、OpenAI Gym
- TensorFlow 深度学习实战指南中文版
- 一、入门
- 二、深度神经网络
- 三、卷积神经网络
- 四、循环神经网络介绍
- 五、总结
- 精通 TensorFlow 1.x
- 一、TensorFlow 101
- 二、TensorFlow 的高级库
- 三、Keras 101
- 四、TensorFlow 中的经典机器学习
- 五、TensorFlow 和 Keras 中的神经网络和 MLP
- 六、TensorFlow 和 Keras 中的 RNN
- 七、TensorFlow 和 Keras 中的用于时间序列数据的 RNN
- 八、TensorFlow 和 Keras 中的用于文本数据的 RNN
- 九、TensorFlow 和 Keras 中的 CNN
- 十、TensorFlow 和 Keras 中的自编码器
- 十一、TF 服务:生产中的 TensorFlow 模型
- 十二、迁移学习和预训练模型
- 十三、深度强化学习
- 十四、生成对抗网络
- 十五、TensorFlow 集群的分布式模型
- 十六、移动和嵌入式平台上的 TensorFlow 模型
- 十七、R 中的 TensorFlow 和 Keras
- 十八、调试 TensorFlow 模型
- 十九、张量处理单元
- TensorFlow 机器学习秘籍中文第二版
- 一、TensorFlow 入门
- 二、TensorFlow 的方式
- 三、线性回归
- 四、支持向量机
- 五、最近邻方法
- 六、神经网络
- 七、自然语言处理
- 八、卷积神经网络
- 九、循环神经网络
- 十、将 TensorFlow 投入生产
- 十一、更多 TensorFlow
- 与 TensorFlow 的初次接触
- 前言
- 1. TensorFlow 基础知识
- 2. TensorFlow 中的线性回归
- 3. TensorFlow 中的聚类
- 4. TensorFlow 中的单层神经网络
- 5. TensorFlow 中的多层神经网络
- 6. 并行
- 后记
- TensorFlow 学习指南
- 一、基础
- 二、线性模型
- 三、学习
- 四、分布式
- TensorFlow Rager 教程
- 一、如何使用 TensorFlow Eager 构建简单的神经网络
- 二、在 Eager 模式中使用指标
- 三、如何保存和恢复训练模型
- 四、文本序列到 TFRecords
- 五、如何将原始图片数据转换为 TFRecords
- 六、如何使用 TensorFlow Eager 从 TFRecords 批量读取数据
- 七、使用 TensorFlow Eager 构建用于情感识别的卷积神经网络(CNN)
- 八、用于 TensorFlow Eager 序列分类的动态循坏神经网络
- 九、用于 TensorFlow Eager 时间序列回归的递归神经网络
- TensorFlow 高效编程
- 图嵌入综述:问题,技术与应用
- 一、引言
- 三、图嵌入的问题设定
- 四、图嵌入技术
- 基于边重构的优化问题
- 应用
- 基于深度学习的推荐系统:综述和新视角
- 引言
- 基于深度学习的推荐:最先进的技术
- 基于卷积神经网络的推荐
- 关于卷积神经网络我们理解了什么
- 第1章概论
- 第2章多层网络
- 2.1.4生成对抗网络
- 2.2.1最近ConvNets演变中的关键架构
- 2.2.2走向ConvNet不变性
- 2.3时空卷积网络
- 第3章了解ConvNets构建块
- 3.2整改
- 3.3规范化
- 3.4汇集
- 第四章现状
- 4.2打开问题
- 参考
- 机器学习超级复习笔记
- Python 迁移学习实用指南
- 零、前言
- 一、机器学习基础
- 二、深度学习基础
- 三、了解深度学习架构
- 四、迁移学习基础
- 五、释放迁移学习的力量
- 六、图像识别与分类
- 七、文本文件分类
- 八、音频事件识别与分类
- 九、DeepDream
- 十、自动图像字幕生成器
- 十一、图像着色
- 面向计算机视觉的深度学习
- 零、前言
- 一、入门
- 二、图像分类
- 三、图像检索
- 四、对象检测
- 五、语义分割
- 六、相似性学习
- 七、图像字幕
- 八、生成模型
- 九、视频分类
- 十、部署
- 深度学习快速参考
- 零、前言
- 一、深度学习的基础
- 二、使用深度学习解决回归问题
- 三、使用 TensorBoard 监控网络训练
- 四、使用深度学习解决二分类问题
- 五、使用 Keras 解决多分类问题
- 六、超参数优化
- 七、从头开始训练 CNN
- 八、将预训练的 CNN 用于迁移学习
- 九、从头开始训练 RNN
- 十、使用词嵌入从头开始训练 LSTM
- 十一、训练 Seq2Seq 模型
- 十二、深度强化学习
- 十三、生成对抗网络
- TensorFlow 2.0 快速入门指南
- 零、前言
- 第 1 部分:TensorFlow 2.00 Alpha 简介
- 一、TensorFlow 2 简介
- 二、Keras:TensorFlow 2 的高级 API
- 三、TensorFlow 2 和 ANN 技术
- 第 2 部分:TensorFlow 2.00 Alpha 中的监督和无监督学习
- 四、TensorFlow 2 和监督机器学习
- 五、TensorFlow 2 和无监督学习
- 第 3 部分:TensorFlow 2.00 Alpha 的神经网络应用
- 六、使用 TensorFlow 2 识别图像
- 七、TensorFlow 2 和神经风格迁移
- 八、TensorFlow 2 和循环神经网络
- 九、TensorFlow 估计器和 TensorFlow HUB
- 十、从 tf1.12 转换为 tf2
- TensorFlow 入门
- 零、前言
- 一、TensorFlow 基本概念
- 二、TensorFlow 数学运算
- 三、机器学习入门
- 四、神经网络简介
- 五、深度学习
- 六、TensorFlow GPU 编程和服务
- TensorFlow 卷积神经网络实用指南
- 零、前言
- 一、TensorFlow 的设置和介绍
- 二、深度学习和卷积神经网络
- 三、TensorFlow 中的图像分类
- 四、目标检测与分割
- 五、VGG,Inception,ResNet 和 MobileNets
- 六、自编码器,变分自编码器和生成对抗网络
- 七、迁移学习
- 八、机器学习最佳实践和故障排除
- 九、大规模训练
- 十、参考文献