提交 7109d04a 编写于 作者: W wizardforcel

2020-08-02 17:37:06

上级 6416c507
# 第 1 章 探索和转换数据
TensorFlow 是用于使用数据流图进行数值计算的开源软件库。 图中的节点表示数学运算,而图的边缘表示在它们之间传递的多维数据数组(张量)。
该库包含各种函数,使您能够实现和探索用于图像和文本处理的最先进的卷积神经网络(CNN)和循环神经网络(RNN)架构。 由于复杂的计算以图的形式排列,因此 TensorFlow 可用作框架,使您能够轻松开发自己的模型并将其用于机器学习领域。
它还能够在从 CPU 到移动处理器(包括高度并行的 GPU 计算)的大多数异构环境中运行,并且新的服务架构可以在所有指定选项的非常复杂的混合环境中运行:
![Exploring and Transforming Data](img/00002.jpg)
\ No newline at end of file
# TensorFlow 的主要数据结构 -- 张量
TensorFlow 的数据管理基于张量。 张量是来自数学领域的概念,并且是作为向量和矩阵的线性代数项的概括而开发的。
专门讨论 TensorFlow 时,张量只是在张量对象中建模的带类型的多维数组,带有其他操作。
## 张量属性 -- 阶数,形状和类型
如前所述,TensorFlow 使用张量数据结构表示所有数据。 任何张量都具有静态类型和动态尺寸,因此您可以实时更改张量的内部组织。
张量的另一个特性是,只有张量类型的对象才能在计算图中的节点之间传递。
现在让我们看一下张量的属性是什么(从现在开始,每次使用张量这个词时,我们都将引用 TensorFlow 的张量对象)。
### 张量阶数
张量阶数表示张量的维度方面,但与矩阵阶数不同。 它表示张量所处的维数,而不是行/列或等效空间中张量扩展的精确度量。
秩张量等于向量,秩张量是矩阵。 对于第二张量,您可以使用语法 t [i,j]访问任何元素。 对于三阶张量,您将需要使用 t [i,j,k]来寻址元素,依此类推。
在下面的示例中,我们将创建一个张量,并访问其分量之一:
```py
>>> import tensorflow as tf
>>> tens1 = tf.constant([[[1,2],[2,3]],[[3,4],[5,6]]])
>>> print sess.run(tens1)[1,1,0]
5
```
这是三阶张量,因为在包含矩阵的每个元素中都有一个向量元素:
| 秩 | 数学实体 | 代码定义示例 |
| --- | --- | --- |
| 0 | 标量 | `scalar = 1000` |
| 1 | 向量 | `vector = [2, 8, 3]` |
| 2 | 矩阵 | `matrix = [[4, 2, 1], [5, 3, 2], [5, 5, 6]]` |
| 3 | 3 阶张量 | `tensor = [[[4], [3], [2]], [[6], [100], [4]], [[5], [1], [4]]]` |
| n | n 阶张量 | ... |
### 张量形状
TensorFlow 文档使用三种符号约定来描述张量维数:阶数,形状和维数。 下表显示了它们之间的相互关系:
| 秩 | 形状 | 维度数量 | 例 |
| --- | --- | --- | --- |
| 0 | `[]` | 0 | `4` |
| 1 | `[D0]` | 1 | `[2]` |
| 2 | `[D0,D1]` | 2 | `[6, 2]` |
| 3 | `[D0,D1,D2]` | 3 | `[7, 3, 2]` |
| n | `[D0,D1,... Dn-1]` | d | 形状为`[D0, D1, ..., Dn-1]`的张量。 |
在下面的示例中,我们创建一个样本阶数三张量,并打印其形状:
![Tensor shape](img/00003.jpg)
### 张量数据类型
除了维数外,张量还具有固定的数据类型。 您可以将以下任意一种数据类型分配给张量:
| 数据类型 | Python 类型 | 描述 |
| --- | --- | --- |
| `DT_FLOAT` | `tf.float32` | 32 位浮点。 |
| `DT_DOUBLE` | `tf.float64` | 64 位浮点。 |
| `DT_INT8` | `tf.int8` | 8 位有符号整数。 |
| `DT_INT16` | `tf.int16` | 16 位有符号整数。 |
| `DT_INT32` | `tf.int32` | 32 位有符号整数。 |
| `DT_INT64` | `tf.int64` | 64 位有符号整数。 |
| `DT_UINT8` | `tf.uint8` | 8 位无符号整数。 |
| `DT_STRING` | `tf.string` | 可变长度字节数组。 张量的每个元素都是一个字节数组。 |
| `DT_BOOL` | `tf.bool` | 布尔。 |
## 创建新的张量
我们可以创建自己的张量,也可以从著名的 numpy 库派生它们。 在以下示例中,我们创建一些 numpy 数组,并对其进行一些基本数学运算:
```py
import tensorflow as tf
import numpy as np
x = tf.constant(np.random.rand(32).astype(np.float32))
y= tf.constant ([1,2,3])
```
### 从 numpy 到张量,以及反向
TensorFlow 可与 numpy 互操作,通常`eval()`函数调用将返回一个 numpy 对象,准备与标准数值工具一起使用。
### 提示
我们必须注意,张量对象是操作结果的符号句柄,因此它不保存其包含的结构的结果值。 因此,我们必须运行`eval()`方法来获取实际值,该值等于`Session.run(tensor_to_eval)`
在此示例中,我们构建了两个 numpy 数组,并将它们转换为张量:
```py
import tensorflow as tf #we import tensorflow
import numpy as np #we import numpy
sess = tf.Session() #start a new Session Object
x_data = np.array([[1.,2.,3.],
[3.,2.,6.]]) # 2x3 matrix
x = tf.convert_to_tensor(x_data, dtype=tf.float32) #Finally, we create the tensor, starting from the fload 3x matrix
```
#### 有用的方法
`tf.convert_to_tensor`:此函数将各种类型的 Python 对象转换为张量对象。 它接受 tensorobjects,numpy 数组,Python 列表和 Python 标量。
## 完成工作 -- 与 TensorFlow 交互
与大多数 Python 模块一样,TensorFlow 允许使用 Python 的交互式控制台:
![Getting things done - interacting with TensorFlow](img/00004.jpg)
与 Python 的解释器和 TensorFlow 库轻松交互
在上图中,我们调用 Python 解释器(通过简单地调用 Python)并创建常量类型的张量。 然后我们再次调用它,Python 解释器显示张量的形状和类型。
我们还可以使用 IPython 解释器,该解释器将允许我们采用与笔记本样式工具(例如 Jupyter)更兼容的格式:
![Getting things done - interacting with TensorFlow](img/00005.jpg)
IPython 提示
在谈论以交互方式运行 TensorFlow 会话时,最好使用`InteractiveSession`对象。
与普通的`tf.Session`类不同,`tf.InteractiveSession`类将自身安装为构造时的默认会话。 因此,当您尝试评估张量或运行操作时,将不需要传递`Session`对象来指示它所引用的会话。
\ No newline at end of file
# k 最近邻
k 最近邻(k-nn)是一种简单的经典聚类方法,它将很好地介绍此类技术,着眼于每个样本的附近,并假设每个新样本都应属于的类别。 已经知道的数据点。
![k-nearest neighbors](img/00029.jpg)
## k 最近邻的力学
k-nn 可以在我们的多种配置中实现,但是在本章中,我们将使用“半监督”方法。 我们将从一定数量的已分配样本开始,稍后我们将根据训练集的特征猜测集群成员。
![Mechanics of k-nearest neighbors](img/00030.jpg)
最近邻算法
在上图中,我们可以看到该算法的细分。 可以通过以下步骤进行总结:
1. 我们将先前已知的样本放在数据结构上。
2. 然后,我们读取要分类的下一个样本,并计算从新样本到训练集的每个样本的欧几里得距离。
3. 我们通过根据欧几里得距离选择最近的样本的类别来确定新元素的类别。 k-nn 方法需要对 k 个最接近的样本进行投票。
4. 我们重复该过程,直到没有剩余的样本为止。
### k-nn 的优缺点
这种方法的优点是:
* 简单; 无需调整参数
* 没有正规训练; 我们只需要更多的训练实例来改进模型
缺点:
* 计算昂贵(必须计算点与每个新样本之间的所有距离)
## 有用库的实用示例
在以下各节中,我们将讨论一些有用的库。
### matplotlib 绘图库
数据绘图是数据科学学科不可或缺的一部分。 因此,我们需要一个非常强大的框架来绘制结果。 对于此任务,我们没有在 TensorFlow 中实现的通用解决方案,我们将使用 matplotlib 库。
在 matplotlib 站点(`http://matplotlib.org/`)中,定义为:
> “ matplotlib 是一个 Python 2D 绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版物质量的图形。”
#### 合成样本的数据绘图
在此示例中,我们将生成一个包含 100 个随机数的列表,生成样本图,并将结果保存在图形文件中:
```py
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
with tf.Session() as sess:
fig, ax = plt.subplots()
ax.plot(tf.random_normal([100]).eval(), tf.random_normal([100] ).eval(),'o')
ax.set_title('Sample random plot for TensorFlow')
plt.savefig("result.png")
```
这是结果图像:
![Sample synthetic data plotting](img/00031.jpg)
使用 TensorFlow 和 matplotlib 生成的示例图
### 提示
为了查看 scikit 数据集模块的更一般的解释,请参考 [matplotlib.org](http://matplotlib.org/)
### scikit-learn 数据集模块
TensorFlow 当前未实现用于轻松生成合成数据集的方法。 因此,我们将使用`sklearn`库作为帮助程序。
#### 关于 scikit-learn 库
[从其网站](http://scikit-learn.org/stable/)
> “ scikit-learn(以前为 scikits.learn)是针对 Python 编程语言的开源机器学习库。它具有各种分类,回归和聚类模型,旨在与 Python 数字和科学库 NumPy 和 SciPy 互操作。”
在此示例中,我们将使用数据集模块,该模块处理许多众所周知的合成和现场提取的数据集的生成和加载。
### 提示
为了查看 scikit 数据集模块的更一般的解释,请参考[此链接](http://scikit-learn.org/stable/datasets/)
### 合成数据集类型
我们将使用一些生成的数据集类型:
![Synthetic dataset types](img/00032.jpg)
Blob,圆和月亮数据集类型
### Blob 数据集
该数据集是测试简单聚类算法的理想选择。 不会出现问题,因为数据是一致地分组的,并且类别的分离很明确。
#### 采用的方法
以下方法用于所采用的方法:
```py
sklearn.datasets.make_blobs(n_samples=100, n_features=2, centers=3, cluster_std=1.0, center_box=(-10.0, 10.0), shuffle=True, random_state=None)
```
在这里,`n_samples`是数据总数,`n_features`是数据的列数或特征数,`centers`是中心列表或许多随机中心,`cluster_std`是标准偏差,`center_box`是随机生成中心时每个聚类中心的边界框,`shuffle`指示是否必须对样本进行混洗,`random_state`是随机种子。
### 圆圈数据集
这是在其他圆圈中具有圆圈的数据集。 这是一个非线性的,可分离的问题,因此需要通过非线性模型来解决。 这排除了诸如 k 均值的简单算法。 在本章中,我们将尝试使用它来阐明观点。
#### 采用的方法
以下方法用于所采用的方法:
```py
sklearn.datasets.make_circles(n_samples=100,shuffle=True,noise=None, random_state=None,factor=0.8)
```
在这里,`n_samples`是数据总数,`shuffle`表示是否必须对样本进行混洗,`noise`是要应用于循环数据的随机量的数量,`random_state`是随机种子,并且`factor`是圆之间的比例因子。
### 月亮数据集
这是另一个非线性问题,但是具有另一种类型的类分离,因为没有诸如圆环之类的闭合。
\ No newline at end of file
# 项目 2 -- 综合数据集上的最近邻
在这个项目中,我们将加载一个数据集,使用该数据集,以前的算法(k 均值)在分离类时遇到问题。
## 数据集生成
该数据集是第一个示例中具有两个类的相同循环类数据集,但是这次我们将通过增加一些噪声(从`0.01``0.12`)来增加错误概率:
```py
data, features = make_circles(n_samples=N, shuffle=True, noise=0.12,factor=0.4)
```
这是生成的训练数据图:
![Dataset generation](img/00038.jpg)
## 模型架构
将保留数据的变量只是原始数据和测试列表,其中将包含计算出的测试数据类:
```py
data, features = make_circles(n_samples=N, shuffle=True, noise= 0.12, factor=0.4)
tr_data, tr_features= data[:cut], features[:cut]
te_data,te_features=data[cut:], features[cut:]
test=[]
```
## 损失函数说明
在聚类中,我们将使用函数来优化为欧式距离,与第 1 章,探索和转换数据相同。 它是在集群分配循环上计算的,获取从新点到现有训练点的距离,要求最小值的索引,然后使用该索引搜索最近的邻居的类:
```py
distances = tf.reduce_sum(tf.square(tf.sub(i , tr_data)),reduction_indices=1)
neighbor = tf.arg_min(distances,0)
```
## 停止条件
在这个简单的示例中,一旦访问了测试分区的所有元素,我们将完成操作。
## 结果描述
这是测试数据类分布的图形,在这里我们可以看到清晰分开的类。 我们可以观察到,至少在此有限的数据集范围内,此方法比非重叠,斑点优化,k 均值方法更好。
![Results description](img/00039.jpg)
## 完整源代码
以下是完整的源代码:
```py
import tensorflow as tf
import numpy as np
import time
import matplotlib
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_circles
N=210
K=2
# Maximum number of iterations, if the conditions are not met
MAX_ITERS = 1000
cut=int(N*0.7)
start = time.time()
data, features = make_circles(n_samples=N, shuffle=True, noise= 0.12, factor=0.4)
tr_data, tr_features= data[:cut], features[:cut]
te_data,te_features=data[cut:], features[cut:]
test=[]
fig, ax = plt.subplots()
ax.scatter(tr_data.transpose()[0], tr_data.transpose()[1], marker = 'o', s = 100, c = tr_features, cmap=plt.cm.coolwarm )
plt.plot()
sess = tf.Session()
sess.run(tf.initialize_all_variables())
for i, j in zip(te_data, te_features):
distances = tf.reduce_sum(tf.square(tf.sub(i , tr_data)),reduction_indices=1)
neighbor = tf.arg_min(distances,0)
test.append(tr_features[sess.run(neighbor)])
print test
fig, ax = plt.subplots()
ax.scatter(te_data.transpose()[0], te_data.transpose()[1], marker = 'o', s = 100, c = test, cmap=plt.cm.coolwarm )
plt.plot()
end = time.time()
print ("Found in %.2f seconds" % (end-start))
print "Cluster assignments:", test
```
\ No newline at end of file
# 总结
在本章中,我们简单地概述了一些我们可以实现的最基本的模型,但是尝试在解释中尽可能地详细。
从现在开始,我们将能够生成综合数据集,从而使我们能够快速测试模型对于不同数据配置的适当性,从而评估它们的优缺点,而不必加载具有大量未知特征的模型。
此外,我们已经实现了第一个迭代方法并测试了收敛性,该任务将以类似的方式在后续章节中继续进行,但是将使用更精细,更精确的方法。
在下一章中,我们将使用线性函数解决分类问题,并且首次使用训练集中的先前数据来学习其特征。 这是监督学习技术的目标,通常对于解决许多现实生活中的问题更有用。
\ No newline at end of file
# 第 3 章 线性回归
在本章中,我们将开始应用机器学习项目中使用的所有标准步骤,以便使用一条使误差和损失函数最小化的线来拟合先前给定的数据。
在上一章中,我们看到了范围有限和许多可能解决方案的问题。 这些类型的模型还与定性评估类型相关,即基于先前的标签为样本分配标签。 通常在与社会领域有关的问题中发现该结果。
我们还可能对预测(先前建模的)函数的确切数字输出值感兴趣。 这种方法类似于物理领域,可用于在事先了解一系列历史值的情况下预测温度或湿度或某种商品的价值,这称为回归分析。
在线性回归的情况下,我们在输入变量和输出变量之间寻找线性关系表示的确定关系。
\ No newline at end of file
# 单变量线性建模函数
如前所述,在线性回归中,我们尝试找到一个线性方程,以最小化数据点和建模线之间的距离。
此关系可以用以下标准线性函数表示:
![Univariate linear modelling function](img/00040.jpg)
模型函数采用以下形式:
在这里,`ss0``bias`是截距,`x`的函数值为零,`ss1`是建模线的斜率。 变量`x`通常被称为自变量,`y`被称为因变量,但它们也可以分别称为回归变量和响应变量。
## 样本数据生成
在下面的示例中,我们将基于`ss0` = `2.0`的线,加上最大幅度为`0.4`的垂直噪声,生成近似样本随机分布。
```py
In[]:
#Indicate the matplotlib to show the graphics inline
%matplotlib inline
import matplotlib.pyplot as plt # import matplotlib
import numpy as np # import numpy
trX = np.linspace(-1, 1, 101) # Linear space of 101 and [-1,1]
#Create The y function based on the x axis
trY = 2 * trX + np.random.randn(*trX.shape) * 0.4 + 0.2
plt.figure() # Create a new figure
plt.scatter(trX,trY) #Plot a scatter draw of the random datapoints
# Draw one line with the line function
plt.plot (trX, .2 + 2 * trX)
```
结果图将如下所示:
![Sample data generation](img/00041.jpg)
加噪声线性采样和线性函数
\ No newline at end of file
# 成本函数的确定
与所有机器学习技术一样,我们必须确定一个误差函数,我们需要将其最小化,这表明解决问题的适当性。
用于线性回归的最常用的`cost`函数称为最小二乘。
## 最小二乘
为了计算函数的最小二乘误差,我们通常会寻找一种测量点与建模线的接近程度的方法。 因此,我们定义了一个函数,用于测量每个元组`x[n]``y[n]`与建模线的对应值之间的距离。
对于 2D 回归,我们有一个数字元组`(X[0],Y[0]),(X[1],Y[1])...(X[n],Y[n])`的列表,通过最小化以下函数,可以找到`β[0]``β[1]`的值:
![Least squares](img/00042.jpg)
简单来说,求和代表预测值与实际值之间的欧几里得距离之和。
进行运算的原因是,平方误差的总和为我们提供了一个唯一且简单的全局数,预期数与实数之差为我们提供了适当的距离,平方幂为我们提供了一个正数,这会惩罚一个整数。 多于线性的时尚。
\ No newline at end of file
# 最小化成本函数
下一步是设置最小化`cost`函数的方法。 在线性演算中,定位极小值任务的基本特征之一被简化为计算函数的导数并寻找其零点。 为此,该函数必须具有导数,最好是凸的。 可以证明最小二乘函数符合这两个条件。 这对于避免已知的局部极小问题非常有用。
![Minimizing the cost function](img/00043.jpg)
损失函数表示
## 最小二乘的一般最小值
我们尝试解决的问题(最小二乘)可以用矩阵形式表示:
![General minima for least squares](img/00044.jpg)
在此,`J`是成本函数,具有以下解决方案:
![General minima for least squares](img/00045.jpg)
在本章中,我们将使用迭代方法梯度下降,该方法将在以后的章节中以更通用的方式使用。
## 迭代方法 -- 梯度下降
梯度下降本身就是一种迭代方法,并且是机器学习领域中最常用的优化算法。 考虑到可以用它优化的参数组合的复杂性,它结合了简单的方法和良好的收敛速度。
2D 线性回归从具有随机定义的权重或线性系数乘数的函数开始。 定义第一个值后,第二步是以以下形式应用递归函数:
![Iterative methods - gradient descent](img/00046.jpg)
在该方程式中,我们可以轻松推导该方法的机理。 我们从一组初始系数开始,然后朝函数最大变化的相反方向移动。 `α`变量被称为 step,将影响我们在梯度搜索方向上移动最小的距离。
最后一步是可选地测试迭代之间的更改,并查看更改是否大于 epsilon 或检查是否达到了迭代次数。
如果函数不是凸函数,建议使用随机值多次运行梯度下降,然后选择成本值最低的系数。 在非凸函数的情况下,梯度下降最终以最小值出现,这可能是局部的。 因此,对于非凸函数,结果取决于初始值,建议将它们随机设置多次,并在所有解决方案中选择成本最低的解决方案。
\ No newline at end of file
# 示例部分
现在让我们讨论有用的库和模块。
## TensorFlow 中的优化器方法 -- 训练模块
训练或参数优化阶段是机器学习工作流程的重要组成部分。
为此,TensorFlow 具有一个`tf.train`模块,该模块是一组对象的帮助程序,致力于实现数据科学家所需的各种不同优化策略。 此模块提供的主要对象称为优化器。
### `tf.train.Optimizer`类
`Optimizer`类允许您为`loss`函数计算梯度并将其应用于模型的不同变量。 在最著名的算法子类中,我们找到了梯度下降,Adam 和 Adagrad。
关于该类的一个主要提示是`Optimizer`类本身无法实例化。 子类之一。
如前所述,TensorFlow 允许您以符号方式定义函数,因此梯度也将以符号方式应用,从而提高了结果的准确率以及要应用于数据的操作的通用性。
为了使用`Optimizer`类,我们需要执行以下步骤:
1. 创建具有所需参数的`Optimizer`(在这种情况下为梯度下降)。
```py
opt = GradientDescentOptimizer(learning_rate= [learning rate])
```
2.`cost`函数创建一个调用`minimize`方法的操作。
```py
optimization_op = opt.minimize(cost, var_list=[variables list])
```
`minimize`方法具有以下形式:
```py
tf.train.Optimizer.minimize(loss, global_step=None, var_list=None, gate_gradients=1, aggregation_method=None, colocate_gradients_with_ops=False, name=None)
```
主要参数如下:
* `loss`:这是一个张量,其中包含要最小化的值。
* `global_step``Optimizer`工作后,此变量将增加 1。
* `var_list`:包含要优化的变量。
### 提示
实际上,`optimize`方法结合了对`compute_gradients()``apply_gradients()`的调用。 如果要在应用梯度之前对其进行处理,请显式调用`compute_gradients()``apply_gradients()`,而不要使用此函数。 如果我们只想进行一步训练,就必须以`opt_op.run().`的形式执行`run`方法
### 其他优化器实例类型
以下是其他`Optimizer`实例类型:
* `tf.train.AdagradOptimizer`:这是一种基于参数频率的自适应方法,学习率单调下降。
* `tf.train.AdadeltaOptimizer`:这是对 Adagrad 的改进,它的学习率没有下降。
* `tf.train.MomentumOptimizer`:这是一种适应性方法,可解决尺寸之间的不同变化率。
* 并且还有其他更具体的参数,例如`tf.train.AdamOptimizer``tf.train.FtrlOptimizer``tf.train.RMSPropOptimizer`
\ No newline at end of file
# 示例 1 -- 单变量线性回归
现在,我们将在一个项目中工作,在该项目中,我们将应用前面几页中简要介绍的所有概念。 在此示例中,我们将创建一个近似线性分布; 之后,我们将创建一个回归模型,该模型试图拟合线性函数以最小化误差函数(由最小二乘法定义)。
给定一个新样本,该模型将使我们能够预测输入值的结果。
## 数据集说明
对于此示例,我们将生成一个包含线性函数并添加噪声的合成数据集:
```py
import TensorFlow as tf
import numpy as np
trX = np.linspace(-1, 1, 101)
trY = 2 * trX + np.random.randn(*trX.shape) * 0.4 + 0.2 # create a y value which is approximately linear but with some random noise
```
使用这些线,我们可以将线表示为散点图和理想线函数。
```py
import matplotlib.pyplot as plt
plt.scatter(trX,trY)
plt.plot (trX, .2 + 2 * trX)
```
![Dataset description](img/00047.jpg)
生成的样本和原始线性函数无噪声
## 模型架构
1. 现在,我们创建一个变量来保存`x``y`轴中的值。 然后,我们将模型定义为`X`和权重`w`的乘积。
2. 然后,我们生成一些变量,并为其分配初始值以启动模型:
```py
In[]:
X = tf.placeholder("float", name="X") # create symbolic variables
Y = tf.placeholder("float", name = "Y")
```
3. 现在,我们通过将`name_scope`声明为`Model`来定义模型。 此作用域将其包含的所有变量分组,以形成具有同类实体的唯一实体。 在此范围内,我们首先定义一个函数,该函数接收`x`轴坐标,权重(斜率)和偏差的变量。 然后,我们创建一个新变量`objects,`来保存不断变化的参数,并使用`y_model`变量实例化该模型:
```py
with tf.name_scope("Model"):
def model(X, w, b):
return tf.mul(X, w) + b # just define the line as X*w + b0
w = tf.Variable(-1.0, name="b0") # create a shared variable
b = tf.Variable(-2.0, name="b1") # create a shared variable
y_model = model(X, w, b)
```
在仪表板上,您可以看到我们一直在收集的损失函数的图像。 在图部分中,放大模型时,您可以看到求和与乘法运算,参数变量`b0``b1`以及应用于模型的梯度运算,如下所示:
![Model architecture](img/00048.jpg)
## 成本函数描述和优化器循环
1.`Cost Function`中,我们创建了一个新的范围以包括该组的所有操作,并使用先前创建的`y_model`来说明用于计算损失的计算出的`y`轴值。
```py
with tf.name_scope("CostFunction"):
cost = (tf.pow(Y-y_model, 2)) # use sqr error for cost
```
2. 为了定义选择的`optimizer,`,我们初始化一个`GradientDescentOptimizer`,步骤将是`0.01`,这似乎是收敛的合理起点。
```py
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost)
```
3. 现在是时候创建会话并初始化要保存在 TensorBoard 中进行查看的变量了。 在此示例中,我们将为每个迭代保存一个标量变量以及最后一个样本的误差结果。 我们还将图结构保存在文件中以供查看。
```py
sess = tf.Session()
init = tf.initialize_all_variables()
tf.train.write_graph(sess.graph,
'/home/ubuntu/linear','graph.pbtxt')
cost_op = tf.scalar_summary("loss", cost)
merged = tf.merge_all_summaries()
sess.run(init)
writer = tf.train.SummaryWriter('/home/ubuntu/linear',
sess.graph)
```
4. 对于模型训练,我们将目标设置为 100 次迭代,然后将每个样本发送到梯度下降的`train`操作。 每次迭代后,我们绘制建模线并将最后一个误差的值添加到`summary`中。
```py
In[]:
for i in range(100):
for (x, y) in zip(trX, trY):
sess.run(train_op, feed_dict={X: x, Y: y})
summary_str = sess.run(cost_op, feed_dict={X: x, Y: y})
writer.add_summary(summary_str, i)
b0temp=b.eval(session=sess)
b1temp=w.eval(session=sess)
plt.plot (trX, b0temp + b1temp * trX )
```
结果图如下: 我们可以看到初始行如何迅速收敛为更合理的结果:
![Cost function description and Optimizer loop](img/00049.jpg)
放大 CostFunction 范围后,我们可以看到幂和减法运算以及书面摘要,如下图所示:
![Cost function description and Optimizer loop](img/00050.jpg)
## 停止条件
## 结果描述
现在让我们检查参数结果,打印`w``b`变量的`run`输出:
```py
printsess.run(w) # Should be around 2
printsess.run(b) #Should be around 0.2
2.09422
0.256044
```
现在是时候再次以图形方式查看数据和建议的最后一行。
```py
plt.scatter(trX,trY)
plt.plot (trX, testb + trX * testw)
```
![Results description](img/00051.jpg)
## 使用 TensorBoard 查看结果
现在,让我们回顾一下保存在 TensorBoard 中的数据。
为了启动 TensorBoard,您可以转到 logs 目录并执行以下行:
```py
$ tensorboard --logdir=.
```
TensorBoard 将加载事件和图形文件,并且将在`6006`端口上监听。 然后,您可以从浏览器转到`localhost:6000`,然后查看 TensorBoard 仪表板,如下图所示:
![Reviewing results with TensorBoard](img/00052.jpg)
## 完整源代码
以下是完整的源代码:
```py
import matplotlib.pyplot as plt # import matplotlib
import numpy as np # import numpy
import tensorflow as tf
import numpy as np
trX = np.linspace(-1, 1, 101) #Create a linear space of 101 points between 1 and 1
trY = 2 * trX + np.random.randn(*trX.shape) * 0.4 + 0.2 #Create The y function based on the x axis
plt.figure() # Create a new figure
plt.scatter(trX,trY) #Plot a scatter draw of the random datapoints
plt.plot (trX, .2 + 2 * trX) # Draw one line with the line function
get_ipython().magic(u'matplotlib inline')
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
trX = np.linspace(-1, 1, 101)
trY = 2 * trX + np.random.randn(*trX.shape) * 0.4 + 0.2 # create a y value which is approximately linear but with some random noise
plt.scatter(trX,trY)
plt.plot (trX, .2 + 2 * trX)
X = tf.placeholder("float", name="X") # create symbolic variables
Y = tf.placeholder("float", name = "Y")
withtf.name_scope("Model"):
def model(X, w, b):
returntf.mul(X, w) + b # We just define the line as X*w + b0
w = tf.Variable(-1.0, name="b0") # create a shared variable
b = tf.Variable(-2.0, name="b1") # create a shared variable
y_model = model(X, w, b)
withtf.name_scope("CostFunction"):
cost = (tf.pow(Y-y_model, 2)) # use sqr error for cost function
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost)
sess = tf.Session()
init = tf.initialize_all_variables()
tf.train.write_graph(sess.graph, '/home/ubuntu/linear','graph.pbtxt')
cost_op = tf.scalar_summary("loss", cost)
merged = tf.merge_all_summaries()
sess.run(init)
writer = tf.train.SummaryWriter('/home/ubuntu/linear', sess.graph)
fori in range(100):
for (x, y) in zip(trX, trY):
sess.run(train_op, feed_dict={X: x, Y: y})
summary_str = sess.run(cost_op, feed_dict={X: x, Y: y})
writer.add_summary(summary_str, i)
b0temp=b.eval(session=sess)
b1temp=w.eval(session=sess)
plt.plot (trX, b0temp + b1temp * trX )
printsess.run(w) # Should be around 2
printsess.run(b) #Should be around 0.2
plt.scatter(trX,trY)
plt.plot (trX, sess.run(b) + trX * sess.run(w))
```
![Full source code](img/00053.jpg)
![Full source code](img/00051.jpg)
\ No newline at end of file
# 处理计算工作流程 -- TensorFlow 的数据流程图
TensorFlow 的数据流图是模型计算如何工作的符号表示:
![Handling the computing workflow - TensorFlow's data flow graph](img/00006.jpg)
在 TensorBoard 上绘制的简单数据流图表示
简而言之,数据流图是一个完整的 TensorFlow 计算,表示为一个图,其中节点是操作,边是操作之间的数据流。
通常,节点执行数学运算,但也表示连接以输入数据或变量,或推出结果。
边缘描述节点之间的输入/输出关系。 这些数据边仅传输张量。 节点被分配给计算设备,并且一旦它们进入边缘上的所有张量都可用,就会异步并行执行。
所有运算都有一个名称,并表示一个抽象计算(例如,矩阵求逆或乘积)。
## 计算图构建
通常在库用户创建张量和模型将支持的操作时构建计算图,因此无需直接构建`Graph()`对象。 Python 张量构造函数,例如`tf.constant()`,会将必要的元素添加到默认图。 TensorFlow 操作也会发生同样的情况。
例如,`c = tf.matmul(a, b)`创建一个`MatMul`类型的操作,该操作将张量`a``b`作为输入并产生`c`作为输出。
### 有用的操作对象方法
* `tf.Operation.type`:返回操作的类型(例如`MatMul`
* `tf.Operation.inputs`:返回代表操作输入的张量对象列表
* `tf.Graph.get_operations()`:返回图中的操作列表
* `tf.Graph.version`:返回图的自动数字版本
## 馈送
TensorFlow 还提供了一种馈送机制,可将张量直接修补到图中的任何操作中。
提要用张量值临时替换操作的输出。 您将提要数据作为`run()`调用的参数提供。 提要仅用于传递给它的运行调用。 最常见的用例涉及通过使用`tf.placeholder()`创建特定的操作,使其指定为`feed`操作。
## 变量
在大多数计算中,图执行多次。 大多数张量都无法通过图的一次执行而幸存。 但是,变量是一种特殊的操作,它可以将句柄返回到持久可变的张量,该张量在图执行过程中仍然存在。 对于 TensorFlow 的机器学习应用,模型的参数通常存储在变量中保存的张量中,并在运行模型的训练图时进行更新。
### 变量初始化
要初始化变量,只需使用张量作为参数调用`Variable`对象构造函数。
在此示例中,我们使用`1000`零数组初始化了一些变量:
```py
b = tf.Variable(tf.zeros([1000]))
```
## 保存数据流程图
数据流图是使用 Google 的协议缓冲区编写的,因此以后可以使用多种语言进行读取。
### 图序列化语言 -- 协议缓冲区
协议缓冲区是一种不依赖语言,不依赖平台的可扩展机制,用于序列化结构化数据。 首先定义数据结构,然后可以使用专门生成的代码来使用多种语言进行读写。
#### 有用的方法
`tf.Graph.as_graph_def(from_version=None, add_shapes=False)`:返回此图的序列化`GraphDef`表示形式。
参数:
* `from_version`:如果设置了此选项,它将返回带有从该版本添加的节点的`GraphDef`
* `add_shapes`:如果`true`,则向每个节点添加一个 shape 属性
### 建立图的示例
在此示例中,我们将构建一个非常简单的数据流图,并观察生成的 protobuffer 文件的概述:
```py
import tensorflow as tf
g = tf.Graph()
with g.as_default():
import tensorflow as tf
sess = tf.Session()
W_m = tf.Variable(tf.zeros([10, 5]))
x_v = tf.placeholder(tf.float32, [None, 10])
result = tf.matmul(x_v, W_m)
print g.as_graph_def()
```
生成的 protobuffer(摘要)为:
```py
node {
name: "zeros"
op: "Const"
attr {
key: "dtype"
value {
type: DT_FLOAT
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 10
}
dim {
size: 5
}
}
float_val: 0.0
}
}
}
}
...
node {
name: "MatMul"
op: "MatMul"
input: "Placeholder"
input: "Variable/read"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
...
}
versions {
producer: 8
}
```
\ No newline at end of file
# 总结
在本章中,我们使用 TensorFlow 的训练实用程序构建了第一个具有标准损失函数的完整模型。 我们还建立了一个多元模型来说明多个维度来计算回归。 除此之外,我们使用 TensorBoard 在训练阶段观察变量的行为。
在下一章中,我们将开始使用非线性模型,通过它我们将更接近神经网络领域,这是 TensorFlow 的主要支持领域,其效用提供了巨大价值。
\ No newline at end of file
# 第 4 章 逻辑回归
在上一章中,我们已经看到了一种将现实的一部分建模为线性函数的方法,该函数具有独立变量,并且偏差最小化了误差函数。
除了某些非常明确定义的问题(预期结果是连续的变量和函数)之外,这种特殊的分析还不够。
但是,如果我们面对具有定性因变量的数据,将会发生什么? 例如,是否存在确定的特征; 受试者有金色的头发吗? 病人以前有病吗?
这些是我们将在本章中处理的问题。
\ No newline at end of file
# 问题描述
线性回归旨在解决的问题不是基于连续函数的值预测,这一次,我们想知道样本属于确定类别的可能性。
在本章中,我们将依靠线性模型的一般化来解决回归问题,但最终目标是解决分类问题,我们必须应用标签或将观察集中的所有元素分配给预定义的组。
![Problem description](img/00058.jpg)
在上图中,我们可以看到如何对旧问题和新问题进行分类。 第一个(线性回归)可以想象为价值不断增长的连续体。
另一个是基于`x`值的输出只能具有两个不同值的域。 在第二张图的特定情况下,我们可以看到对其中一个选项的特定偏向极端:在左侧,偏向 0 `y`值,在右侧偏向某个值。 共 1。
鉴于即使在进行回归从而寻找连续值的情况下,这种项也可能有些棘手,实际上,最终目标是为具有离散变量的分类问题建立预测。
此处的关键是要了解我们将获得与类有关的项目的概率,而不是完全离散的值。
\ No newline at end of file
# sigmoid 函数的前身 -- Logit 函数
在研究逻辑函数之前,我们将回顾该函数所基于的原始函数,并为其提供一些更一般的属性。
本质上,当我们谈论`logit`函数时,我们正在使用随机变量`p`的函数,更具体地说,是与伯努利分布相对应的函数。
## 伯努利分布
在解释理论细节之前,值得注意的是伯努利分布是一个随机变量,它具有:
* 取值为 0 且失败概率为`q = 1 - p`
* 取值为 1,成功概率为`p`
可以表示如下(对于具有伯努利分布的随机变量`X`):
![Bernoulli distribution](img/00059.jpg)
这是一种概率分布,它将以二元选项的形式表示事件的发生概率,就像我们要表示自己的变量(特征的存在,事件的发生,现象的因果关系等)一样。
## 链接函数
在尝试建立广义线性模型时,我们要从线性函数开始,并从因变量开始,获取到概率分布的映射。
由于选项具有二元性质,因此通常选择的分布是最近提到的 Bernoulli 分布,而倾向于 logistic 函数的链接函数是`logit`函数。
## Logit 函数
我们可以利用的可能变量之一是`p`等于 1 的几率的自然对数。 此函数称为`logit`函数:
![Logit function](img/00060.jpg)
我们也可以将`logit`函数称为对数奇数函数,因为对于给定的概率`p`,我们正在计算赔率的对数`(p/1-p)`
![Logit function](img/00061.jpg)
因此,正如我们可以直观地推断出的那样,用自变量的组合替换`X`,无论它们的值是什么,用从负无穷大到无穷大的任何出现替换`X`,我们将响应缩放到`0``1`
## Logit 反函数的重要性
假设我们计算`logit`函数的逆。 这将使我们编写以下函数:
![The importance of the logit inverse](img/00062.jpg)
此函数是`sigmoid`函数。
\ No newline at end of file
# sigmoid 函数
逻辑函数将帮助我们在新的回归任务中表示二元类别。
在下图中,您将找到`sigmoid`函数的图形表示:
![The logistic function](img/00063.jpg)
逻辑函数或 Sigmoid 的图形表示
## Logistic 函数作为线性建模概括
逻辑函数`δ(t)`定义如下:
![Logistic function as a linear modeling generalization](img/00064.jpg)
该方程式的正常解释是`t`代表一个简单的自变量。 但是,我们将改进此模型,并假定`t`是单个解释变量`x`的线性函数(对 t 是多个解释变量的线性组合的情况进行类似处理)。
然后,我们将`t`表示为:
![Logistic function as a linear modeling generalization](img/00065.jpg)
### 最终估计的回归方程
因此,我们从以下等式开始:
![Final estimated regression equation](img/00066.jpg)
使用所有这些元素,我们可以计算回归方程,这将为我们提供回归概率:
![Final estimated regression equation](img/00067.jpg)
下图将显示如何将从任意范围的映射最终转换为范围`[0, 1]`,该范围可以解释为表示事件发生的概率 p:
![Final estimated regression equation](img/00068.jpg)
什么影响会改变线性函数的参数? 它们是将更改`sigmoid`函数的中心斜率和从零开始的位移的值,从而使其可以更精确地减小回归值与实际数据点之间的误差。
## 逻辑函数的属性
函数空间中的每条曲线都可以通过可能适用的目标来描述。 对于 logistic 函数,它们是:
* 根据一个或多个独立变量对事件的概率`p`进行建模。 例如,鉴于先前的资格,被授予奖品的可能性。
* 对确定的观测值进行估计(这是回归部分)`p`,与事件未发生的可能性有关。
* 预测自变量变化对二元响应的影响。
* 通过计算某项属于确定类别的概率对观察进行分类。
### 损失函数
在上一节中,我们看到了近似的`p^`函数,该函数将对样本属于特定类别的概率进行建模。 为了衡量我们对解的近似程度,我们将寻找精心选择的损失函数。
该损失函数表示为:
![Loss function](img/00069.jpg)
该损失函数的主要特性是它不会以类似的方式惩罚误差,当误差增加到远远超过 0.5 时,误差惩罚因子会渐近增长。
## 多类应用 -- softmax 回归
到目前为止,我们仅针对两个类的情况进行分类,或者以概率语言对事件发生概率`p`进行分类。
在要决定两个以上类别的情况下,有两种主要方法: 一对一,一对全。
* 第一种技术包括计算许多模型,这些模型代表每个类别相对于所有其他类别的概率。
* 第二个由一组概率组成,其中我们代表一个类别相对于所有其他类别的概率。
* 第二种方法是`softmax`回归的输出格式,它是 n 个类的逻辑回归的概括。
因此,为了训练样本,我们将使用句柄`y(i)ε{1,...,K},`将二元标签`( y(i)ε{0,1})`更改为向量标签,其中`K`是类别数,标签 Y 可以采用`K`不同的值, 而不是只有两个。
因此,对于这种特定技术,给定测试输入`X`,我们想要针对`k=1,...,K`的每个值估计`P``y=k|x`)的概率。 `softmax`回归将输出`K`维向量(其元素总和为 1),从而为我们提供了`K`估计的概率。
在下图中,我们表示在单类和多类逻辑回归的概率映射上发生的映射:
![Multiclass application - softmax regression](img/00070.jpg)
### 成本函数
`softmax`函数的成本函数是自适应的交叉熵函数,该函数不是线性的,因此对大阶函数差异的惩罚要比对小阶函数的惩罚更大。
![Cost function](img/00071.jpg)
在这里,`c`是类别编号,`I`是各个训练样本索引,`yc`对于期望的类别为 1,对于其余类别为 0。
扩展这个方程,我们得到以下结果:
![Cost function](img/00072.jpg)
### 迭代方法的数据标准化
正如我们将在以下各节中看到的那样,对于逻辑回归,我们将使用`gradient descent`方法来最小化成本函数。
![Data normalization for iterative methods](img/00073.jpg)
此方法对特征数据的形式和分布非常敏感。
因此,我们将进行一些预处理,以便获得更好,更快的收敛结果。
我们将把这种方法的理论原因留给其他书籍,但我们将总结其原因,即通过归一化可以平滑误差表面,使迭代`gradient descent`更快地达到最小误差。
### 输出的单热表示
为了将`softmax`函数用作回归函数,我们必须使用一种称为单热编码的编码。 这种编码形式只是将变量的数字整数值转换为数组,其中将值列表转换为数组列表,每个数组的长度与该列表的最大值相同,并且每个数组的表示方式是在值的索引上添加 1,其余元素保持为 0。
例如,这将是单热编码形式的列表[1、3、2、4]的表示形式:
```py
[[0 1 0 0 0]
[0 0 0 1 0]
[0 0 1 0 0]
[0 0 0 0 1]]
```
\ No newline at end of file
# 示例 2 -- 使用 skflow 的单变量 logistic 回归
在此示例中,我们将探索单变量示例域,但是这次我们将使用来自新库的帮助,该库为我们简化了模型构建,称为`skflow`
## 有用的库和方法
在机器学习库领域中,有很多选择。 最知名的之一是`sklearn`,我们在第 2 章聚类中讨论过。
在 TensorFlow 发布之后的很早,一个新的贡献库就出现了,叫做`skflow`,其主要目的是模拟`sklearn`的界面和工作流程,在这个 TensorFlow 会话环境中工作更简洁。
在下面的示例中,我们将使用`skflow`界面重复先前回归的分析。
在示例中,我们还将看到 skflow 如何为回归模型自动生成详细且组织良好的图,只需将日志目录设置为参数即可。
## 数据集说明
使用`pandas`库,数据集加载阶段与前面的示例相同:
```py
import pandas as pd
df = pd.read_csv("data/CHD.csv", header=0)
print df.describe()
```
## 模型架构
这是`my_model`的代码段:
```py
def my_model(X, y):
return skflow.models.logistic_regression(X, y)
X1 =a.fit_transform(df['age'].astype(float))
y1 = df['chd'].values
classifier = skflow.TensorFlowEstimator(model_fn=my_model, n_classes=2)
```
在这里,我们可以使用`softmax`分类器查看逻辑回归阶段的详细视图:
![Model architecture](img/00077.jpg)
![Model architecture](img/00078.jpg)
## 结果描述
```py
score = metrics.accuracy_score(df['chd'].astype(float), classifier.predict(X))
print("Accuracy: %f" % score)
```
输出结果可观(为了简化模型)74%的准确率:
```py
Accuracy: 0.740000
```
## 完整源代码
这是完整的源代码:
```py
import tensorflow.contrib.learn as skflow
from sklearn import datasets, metrics, preprocessing
import numpy as np
import pandas as pd
df = pd.read_csv("data/CHD.csv", header=0)
print df.describe()
def my_model(X, y):
return skflow.models.logistic_regression(X, y)
a = preprocessing.StandardScaler()
X1 =a.fit_transform(df['age'].astype(float))
y1 = df['chd'].values
classifier = skflow.TensorFlowEstimator(model_fn=my_model, n_classes=2)
classifier.fit(X1,y1 , logdir='/tmp/logistic')
score = metrics.accuracy_score(df['chd'].astype(float), classifier.predict(X))
print("Accuracy: %f" % score)
```
\ No newline at end of file
# 总结
在本章中,我们学习了一种新的建模技术,即逻辑函数,并从一种简单的分类任务入手。
我们还学习了一种通过`pandas`库读取基于文本的数据的新方法。
此外,我们还看到了与`skflow`库一起使用的经典工作流的一种补充方法。
在下一章中,我们将开始处理更复杂的架构,并进入 TensorFlow 库擅长的领域:训练,测试和最终实现神经网络以解决实际问题。
\ No newline at end of file
# 第 5 章 简单的前馈神经网络
神经网络确实是 Tensorflow 擅长的机器学习领域。 可以用它实现多种类型的架构和算法,以及结合了符号引擎的其他优点,这实际上将有助于训练更复杂的设置。
在本章中,我们开始利用高表现原语的功能来解决大量支持输入变量的日益复杂的问题。
在本章中,我们将介绍以下主题:
* 神经网络的初步概念
* 非线性综合函数回归的神经网络项目
* 利用非线性回归预测汽车燃油效率的项目
* 学习葡萄酒的分类和多分类
\ No newline at end of file
# 运行我们的程序 -- 会话
客户端程序通过创建会话与 TensorFlow 系统交互。 会话对象表示将在其中运行计算的环境。 Session 对象开始为空,并且当程序员创建不同的操作和张量时,它们将被自动添加到 Session 中,在调用`Run()`方法之前,该对象不会进行任何计算。
`Run()`方法采用一组需要计算的输出名称,以及一组可选的张量,以代替节点的某些输出输入到图中。
如果调用此方法,并且命名操作依赖于某些操作,则 Session 对象将执行所有这些操作,然后继续执行命名操作。
这条简单的线是创建会话所需的唯一一行:
```py
s = tf.Session()
Sample command line output:
tensorflow/core/common_runtime/local_session.cc:45]Localsessioninteropparallelism threads:6
```
\ No newline at end of file
# 第一个项目 -- 非线性合成函数回归
人工神经网络示例通常包含绝大多数分类问题,但实际上有大量应用可以表示为回归。
用于回归的网络架构与用于分类问题的网络架构没有很大不同:它们可以采用多变量输入,也可以使用线性和非线性激活函数。
在某些情况下,唯一必要的情况是仅在层的末尾删除类似于 S 形的函数,以允许出现所有选项。
在第一个示例中,我们将对一个简单的,有噪声的二次函数进行建模,并将尝试通过单个隐藏层网络对其进行回归,并查看我们可以多么接近地预测从测试总体中得出的值。
## 数据集说明和加载
在这种情况下,我们将使用生成的数据集,该数据集与第 3 章的线性回归中的数据集非常相似。
我们将使用常见的 Numpy 方法生成二次函数,然后添加随机噪声,这将有助于我们了解线性回归如何推广。
核心样本创建例程如下:
```py
import numpy as np
trainsamples = 200
testsamples = 60
dsX = np.linspace(-1, 1, trainsamples + testsamples).transpose()
dsY = 0.4* pow(dsX,2) +2 * dsX + np.random.randn(*dsX.shape) * 0.22 + 0.8
```
## 数据集预处理
该数据集在生成时不需要进行预处理,并且具有良好的属性,例如居中并具有-1,1 x 样本分布。
## 建模架构 -- 损失函数描述
此设置的损耗将简单地用均方根误差表示,如下所示:
```py
cost = tf.pow(py_x-Y, 2)/(2)
```
## 损失函数优化器
在这种情况下,我们将使用 Gradient Descent 成本优化器,可以通过以下代码调用该优化器:
```py
train_op = tf.train.AdamOptimizer(0.5).minimize(cost)
```
## 准确率和收敛性测试
`predict_op = tf.argmax(py_x, 1)`
```py
cost1 += sess.run(cost, feed_dict={X: [[x1]], Y: y1}) / testsamples
```
### 示例代码
让我们看一下下面显示的示例代码:
```py
import tensorflow as tf
import numpy as np
from sklearn.utils import shuffle
%matplotlib inline
import matplotlib.pyplot as plt
trainsamples = 200
testsamples = 60
#Here we will represent the model, a simple imput, a hidden layer of sigmoid activation
def model(X, hidden_weights1, hidden_bias1, ow):
hidden_layer = tf.nn.sigmoid(tf.matmul(X, hidden_weights1)+ b)
return tf.matmul(hidden_layer, ow)
dsX = np.linspace(-1, 1, trainsamples + testsamples).transpose()
dsY = 0.4* pow(dsX,2) +2 * dsX + np.random.randn(*dsX.shape) * 0.22 + 0.8
plt.figure() # Create a new figure
plt.title('Original data')
plt.scatter(dsX,dsY) #Plot a scatter draw of the datapoints
```
![Example code](img/00086.jpg)
```py
X = tf.placeholder("float")
Y = tf.placeholder("float")
# Create first hidden layer
hw1 = tf.Variable(tf.random_normal([1, 10], stddev=0.1))
# Create output connection
ow = tf.Variable(tf.random_normal([10, 1], stddev=0.0))
# Create bias
b = tf.Variable(tf.random_normal([10], stddev=0.1))
model_y = model(X, hw1, b, ow)
# Cost function
cost = tf.pow(model_y-Y, 2)/(2)
# construct an optimizer
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost)
# Launch the graph in a session
with tf.Session() as sess:
tf.initialize_all_variables().run() #Initialize all variables
for i in range(1,100):
dsX, dsY = shuffle (dsX.transpose(), dsY) #We randomize the samples to mplement a better training
trainX, trainY =dsX[0:trainsamples], dsY[0:trainsamples]
for x1,y1 in zip (trainX, trainY):
sess.run(train_op, feed_dict={X: [[x1]], Y: y1})
testX, testY = dsX[trainsamples:trainsamples + testsamples], dsY[0:trainsamples:trainsamples+testsamples]
cost1=0.
for x1,y1 in zip (testX, testY):
cost1 += sess.run(cost, feed_dict={X: [[x1]], Y: y1}) / testsamples
if (i%10 == 0):
print "Average cost for epoch " + str (i) + ":" + str(cost1)
```
## 结果描述
这是不同周期的结果的副本。请注意,由于这是一个非常简单的函数,因此即使第一次迭代也具有非常好的结果:
```py
Average cost for epoch 1:[[ 0.00753353]]
Average cost for epoch 2:[[ 0.00381996]]
Average cost for epoch 3:[[ 0.00134867]]
Average cost for epoch 4:[[ 0.01020064]]
Average cost for epoch 5:[[ 0.00240157]]
Average cost for epoch 6:[[ 0.01248318]]
Average cost for epoch 7:[[ 0.05143405]]
Average cost for epoch 8:[[ 0.00621457]]
Average cost for epoch 9:[[ 0.0007379]]
```
\ No newline at end of file
# 第二个项目 -- 使用非线性回归建模汽车的燃油效率
在此示例中,我们将进入一个区域,其中神经网络可提供大部分附加价值; 解决非线性问题。 为了开始这一旅程,我们将基于几个变量对几种汽车模型的燃油效率建模一个回归模型,该变量可以更好地用非线性函数表示。
## 数据集说明和加载
对于这个问题,我们将分析一个非常著名的,标准的,格式正确的数据集,该数据集将使我们能够分析一个多变量问题:根据离散和连续的一些相关变量来猜测汽车的 mpg。
这可以被认为是一个玩具,并且有些过时了,但是它将为更复杂的问题铺平道路,并且具有已经被众多书目分析的优势。
属性信息
该数据集具有以下数据列:
* `mpg`:连续
* `cylinders`:多值离散
* `displacement`:连续
* `horsepower`:连续
* `weight`:连续
* `acceleration`:连续
* `model year:`多值离散
* `origin`:多值离散
* `car name`:字符串(将不使用)
我们将不对数据进行详细的分析,但是我们可以非正式地推断出所有连续变量都与增加或减少目标变量相关:
![Dataset description and loading](img/00087.jpg)
## 数据集预处理
对于此任务,我们将使用来自 sklearn 的上述缩放器对象:
* `scaler = preprocessing.StandardScaler()`
* `X_train = scaler.fit_transform(X_train)`
## 建模架构
我们将要构建的是一个前馈神经网络,具有多变量输入和简单输出:
![Modeling architecture](img/00088.jpg)
## 收敛性测试
```py
score = metrics.mean_squared_error(regressor.predict(scaler.transform(X_test)), y_test)
print('MSE: {0:f}'.format(score))
```
## 结果描述
```py
Step #99, avg. train loss: 182.33624
Step #199, avg. train loss: 25.09151
Step #300, epoch #1, avg. train loss: 11.92343
Step #400, epoch #1, avg. train loss: 11.20414
Step #500, epoch #1, avg. train loss: 5.14056
Total Mean Squared Error: 15.0792258911
```
```py
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
from sklearn import datasets, cross_validation, metrics
from sklearn import preprocessing
from tensorflow.contrib import skflow
# Read the original dataset
df = pd.read_csv("data/mpg.csv", header=0)
# Convert the displacement column as float
df['displacement']=df['displacement'].astype(float)
# We get data columns from the dataset
# First and last (mpg and car names) are ignored for X
X = df[df.columns[1:8]]
y = df['mpg']
plt.figure() # Create a new figure
for i in range (1,8):
number = 420 + i
ax1.locator_params(nbins=3)
ax1 = plt.subplot(number)
plt.title(list(df)[i])
ax1.scatter(df[df.columns[i]],y) #Plot a scatter draw of the datapoints
plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)
# Split the datasets
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y,
test_size=0.25)
# Scale the data for convergency optimization
scaler = preprocessing.StandardScaler()
# Set the transform parameters
X_train = scaler.fit_transform(X_train)
# Build a 2 layer fully connected DNN with 10 and 5 units respectively
regressor = skflow.TensorFlowDNNRegressor(hidden_units=[10, 5],
steps=500, learning_rate=0.051, batch_size=1)
# Fit the regressor
regressor.fit(X_train, y_train)
# Get some metrics based on the X and Y test data
score = metrics.mean_squared_error(regressor.predict(scaler.transform(X_test)), y_test)
print(" Total Mean Squared Error: " + str(score))
```
\ No newline at end of file
# 第三个项目 -- 学习葡萄酒分类:多类分类
在本节中,我们将使用更复杂的数据集,尝试根据产地对葡萄酒进行分类。
## 数据集说明和加载
该数据包含对来自意大利同一地区但来自三个不同品种的葡萄酒进行化学分析的结果。 分析确定了三种葡萄酒中每种所含 13 种成分的数量。
数据变量:
*
* 苹果酸
*
* 灰的碱度
*
* 总酚
* 黄酮
* 非类黄酮酚
* 花青素
* 色彩强度
* 色调
* 稀释酒的 OD280 / OD315
* 脯氨酸
要读取数据集,我们将仅使用提供的 CSV 文件和熊猫:
```py
df = pd.read_csv("./wine.csv", header=0)
```
![Dataset description and loading](img/00089.jpg)
## 数据集预处理
随着 csv 上的值从 1 开始,我们将归一化带有偏差的值:
```py
y = df['Wine'].values-1
```
对于结果,我们将这些选项表示为一个数组的热门列表:
```py
Y = tf.one_hot(indices = y, depth=3, on_value = 1., off_value = 0., axis = 1 , name = "a").eval()
```
我们还将预先洗净值:
```py
X, Y = shuffle (X, Y)
scaler = preprocessing.StandardScaler()
X = scaler.fit_transform(X)
```
## 建模架构
这个特定的模型将由一个单层,全连接的神经网络组成:
* `x` = `tf.placeholder(tf.float32, [None, 12])`
* `W` = `tf.Variable(tf.zeros([12, 3]))`
* `b` = `tf.Variable(tf.zeros([3]))`
* `y` = `tf.nn.softmax(tf.matmul(x, W) + b)`
## 损失函数说明
我们将使用交叉熵函数来衡量损失:
```py
y_ = tf.placeholder(tf.float32, [None, 3])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
```
## 损失函数优化器
同样,将使用“梯度下降”方法来减少损失函数:
```py
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(cross_entropy)
```
## 收敛测试
在收敛性测试中,我们将每个良好的回归均转换为 1,将每个错误的回归均转换为 0,然后获取值的平均值来衡量模型的准确率:
```py
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x: Xt, y_: Yt}))
```
## 结果描述
如我们所见,随着历时的发展,我们具有可变精度,但是它总是优于 90%的精度,具有 30%的随机基数(如果我们生成 0 到 3 之间的随机数来猜测结果)。
```py
0.973684
0.921053
0.921053
0.947368
0.921053
```
## 完整源代码
让我们看一下完整的源代码:
```py
sess = tf.InteractiveSession()
import pandas as pd
# Import data
from tensorflow.examples.tlutorials.mnist import input_data
from sklearn.utils import shuffle
import tensorflow as tf
from sklearn import preprocessing
flags = tf.app.flags
FLAGS = flags.FLAGS
df = pd.read_csv("./wine.csv", header=0)
print (df.describe())
#df['displacement']=df['displacement'].astype(float)
X = df[df.columns[1:13]].values
y = df['Wine'].values-1
Y = tf.one_hot(indices = y, depth=3, on_value = 1., off_value = 0., axis = 1 , name = "a").eval()
X, Y = shuffle (X, Y)
scaler = preprocessing.StandardScaler()
X = scaler.fit_transform(X)
# Create the model
x = tf.placeholder(tf.float32, [None, 12])
W = tf.Variable(tf.zeros([12, 3]))
b = tf.Variable(tf.zeros([3]))
y = tf.nn.softmax(tf.matmul(x, W) + b)
# Define loss and optimizer
y_ = tf.placeholder(tf.float32, [None, 3])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(cross_entropy)
# Train
tf.initialize_all_variables().run()
for i in range(100):
X,Y =shuffle (X, Y, random_state=1)
Xtr=X[0:140,:]
Ytr=Y[0:140,:]
Xt=X[140:178,:]
Yt=Y[140:178,:]
Xtr, Ytr = shuffle (Xtr, Ytr, random_state=0)
#batch_xs, batch_ys = mnist.train.next_batch(100)
batch_xs, batch_ys = Xtr , Ytr
train_step.run({x: batch_xs, y_: batch_ys})
cost = sess.run (cross_entropy, feed_dict={x: batch_xs, y_: batch_ys})
# Test trained model
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x: Xt, y_: Yt}))
```
\ No newline at end of file
# 总结
在本章中,我们已经开始着手实现 TensorFlow 能力的真正替代物:神经网络模型。
我们还看到了在回归和分类任务中使用简单神经网络,简单生成模型和实验模型的情况。
在下一章中,我们将以卷积神经网络的形式提高新架构的知识以及将神经网络范式应用于其他知识领域(例如计算机视觉)的方式。
\ No newline at end of file
# 第 6 章 卷积神经网络
卷积神经网络是当前使用的许多最高级模型的一部分。 它们被用于许多领域,但是主要的应用领域是图像分类和特征检测领域。
我们将在本章中介绍的主题如下:
* 了解卷积函数和卷积网络如何工作以及构建它们的主要操作类型
* 将卷积运算应用于图像数据并学习一些应用于图像的预处理技术,以提高方法的准确率
* 使用 CNN 的简单设置对 MNIST 数据集的数字进行分类
* 使用应用于彩色图像的 CNN 模型对 CIFAR 数据集的真实图像进行分类
\ No newline at end of file
# 示例 1 -- MNIST 数字分类
在本节中,我们将首次使用最知名的模式识别数据集中的一个。 它最初是为了训练神经网络来对支票上的手写数字进行字符识别而开发的。
原始数据集有 60,000 个不同的数字用于训练和 10,000 个用于测试,并且在使用时是原始使用的数据集的子集。
在下图中,我们显示了 LeNet-5 架构,这是有关该问题发布的第一个著名的卷积架构。
在这里,您可以看到层的尺寸和最后的结果表示:
![Example 1 - MNIST digit classification](img/00099.jpg)
## 数据集说明和加载
MNIST 是易于理解和阅读但难以掌握的数据集。 当前,有很多好的算法可以解决这个问题。 在我们的案例中,我们将寻求建立一个足够好的模型,以使其与 10%的随机结果相去甚远。
为了访问 MNIST 数据集,我们将使用为 TensorFlow 的 MNIST 教程开发的一些实用工具类。
这两条线是我们拥有完整的 MNIST 数据集所需的全部工作。
在下图中,我们可以看到数据集对象的数据结构的近似值:
![Dataset description and loading](img/00100.jpg)
通过此代码,我们将打开并探索 MNIST 数据集:
![Dataset description and loading](img/00101.jpg)
要打印字符(在 Jupyter Notebook 中),我们将重塑表示图像的线性方式,形成`28x28`的方矩阵,分配灰度色图,并使用以下行绘制所得的数据结构:
```py
plt.imshow(mnist.train.images[0].reshape((28, 28), order='C'), cmap='Greys', interpolation='nearest')
```
下图显示了此行应用于不同数据集元素的结果:
![Dataset description and loading](img/00102.jpg)
## 数据集预处理
在此示例中,我们将不进行任何预处理; 我们只会提到,仅通过使用线性变换的现有样本(例如平移,旋转和倾斜的样本)扩展数据集示例,就可以实现更好的分类评分。
## 建模架构
在这里,我们将研究为该特定架构选择的不同层。
它开始生成带有名称的权重字典:
```py
'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
'out': tf.Variable(tf.random_normal([1024, n_classes]))
```
对于每个权重,还将添加一个`bias`以说明常数。
然后我们定义连接的层,一层又一层地集成:
```py
conv_layer_1 = conv2d(x_in, weights['wc1'], biases['bc1'])
conv_layer_1 = subsampling(conv_layer_1, k=2)
conv_layer_2 = conv2d(conv_layer_1, weights['wc2'], biases['bc2'])
conv_layer_2 = subsampling(conv_layer_2, k=2)
fully_connected_layer = tf.reshape(conv_layer_2, [-1, weights['wd1'].get_shape().as_list()[0]])
fully_connected_layer = tf.add(tf.matmul(fully_connected_layer, weights['wd1']), biases['bd1'])
fully_connected_layer = tf.nn.relu(fully_connected_layer)
fully_connected_layer = tf.nn.dropout(fully_connected_layer, dropout)
prediction_output = tf.add(tf.matmul(fully_connected_layer, weights['out']), biases['out'])
```
## 损失函数说明
损失函数将是交叉熵误差函数的平均值,该函数通常是用于分类的 softmax 函数。
```py
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))
```
## 损失函数优化器
对于此示例,我们将使用改进的`AdamOptimizer`,其学习率可配置,我们将其定义为 0.001。
```py
optimizer = tf.train.AdamOptimizer
(learning_rate=learning_rate).minimize(cost)
```
## 准确率测试
准确率测试计算标签和结果之间比较的平均值,以获得`0``1`之间的值。
```py
correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
```
## 结果说明
此示例的结果简洁明了,并且假设我们仅训练 10,000 个样本,则准确率不是一流的,但与十分之一的随机采样结果明显分开:
```py
Optimization Finished!
Testing Accuracy: 0.382812
```
## 完整源代码
以下是源代码:
```py
import tensorflow as tf
%matplotlib inline
import matplotlib.pyplot as plt
# Import MINST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)
# Parameters
learning_rate = 0.001
training_iters = 2000
batch_size = 128
display_step = 10
# Network Parameters
n_input = 784 # MNIST data input (img shape: 28*28)
n_classes = 10 # MNIST total classes (0-9 digits)
dropout = 0.75 # Dropout, probability to keep units
# tf Graph input
x = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_classes])
keep_prob = tf.placeholder(tf.float32) #dropout (keep probability)
#plt.imshow(X_train[1202].reshape((20, 20), order='F'), cmap='Greys', interpolation='nearest')
# Create some wrappers for simplicity
def conv2d(x, W, b, strides=1):
# Conv2D wrapper, with bias and relu activation
x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
x = tf.nn.bias_add(x, b)
return tf.nn.relu(x)
def maxpool2d(x, k=2):
# MaxPool2D wrapper
return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],
padding='SAME')
# Create model
def conv_net(x, weights, biases, dropout):
# Reshape input picture
x = tf.reshape(x, shape=[-1, 28, 28, 1])
# Convolution Layer
conv1 = conv2d(x, weights['wc1'], biases['bc1'])
# Max Pooling (down-sampling)
conv1 = maxpool2d(conv1, k=2)
# Convolution Layer
conv2 = conv2d(conv1, weights['wc2'], biases['bc2'])
# Max Pooling (down-sampling)
conv2 = maxpool2d(conv2, k=2)
# Fully connected layer
# Reshape conv2 output to fit fully connected layer input
fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]])
fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1'])
fc1 = tf.nn.relu(fc1)
# Apply Dropout
fc1 = tf.nn.dropout(fc1, dropout)
# Output, class prediction
out = tf.add(tf.matmul(fc1, weights['out']), biases['out'])
return out
# Store layers weight & bias
weights = {
# 5x5 conv, 1 input, 32 outputs
'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
# 5x5 conv, 32 inputs, 64 outputs
'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
# fully connected, 7*7*64 inputs, 1024 outputs
'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
# 1024 inputs, 10 outputs (class prediction)
'out': tf.Variable(tf.random_normal([1024, n_classes]))
}
biases = {
'bc1': tf.Variable(tf.random_normal([32])),
'bc2': tf.Variable(tf.random_normal([64])),
'bd1': tf.Variable(tf.random_normal([1024])),
'out': tf.Variable(tf.random_normal([n_classes]))
}
# Construct model
pred = conv_net(x, weights, biases, keep_prob)
# Define loss and optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
# Evaluate model
correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
# Initializing the variables
init = tf.initialize_all_variables()
# Launch the graph
with tf.Session() as sess:
sess.run(init)
step = 1
# Keep training until reach max iterations
while step * batch_size < training_iters:
batch_x, batch_y = mnist.train.next_batch(batch_size)
test = batch_x[0]
fig = plt.figure()
plt.imshow(test.reshape((28, 28), order='C'), cmap='Greys',
interpolation='nearest')
print (weights['wc1'].eval()[0])
plt.imshow(weights['wc1'].eval()[0][0].reshape(4, 8), cmap='Greys', interpolation='nearest')
# Run optimization op (backprop)
sess.run(optimizer, feed_dict={x: batch_x, y: batch_y,
keep_prob: dropout})
if step % display_step == 0:
# Calculate batch loss and accuracy
loss, acc = sess.run([cost, accuracy], feed_dict={x: batch_x,
y: batch_y,
keep_prob: 1.})
print "Iter " + str(step*batch_size) + ", Minibatch Loss= " + \
"{:.6f}".format(loss) + ", Training Accuracy= " + \
"{:.5f}".format(acc)
step += 1
print "Optimization Finished!"
# Calculate accuracy for 256 mnist test images
print "Testing Accuracy:", \
sess.run(accuracy, feed_dict={x: mnist.test.images[:256],
y: mnist.test.labels[:256],
keep_prob: 1.})
```
\ No newline at end of file
# 示例 2 -- 使用 CIFAR10 数据集进行图像分类
在此示例中,我们将研究图像理解中使用最广泛的数据集之一,该数据集用作简单但通用的基准。 在此示例中,我们将构建一个简单的 CNN 模型,以了解解决此类分类问题所需的一般计算结构。
## 数据集说明和加载
该数据集包含 40,000 个`32x32`像素的图像,代表以下类别:飞机,汽车,鸟类,猫,鹿,狗,青蛙,马,船和卡车。 在此示例中,我们将只处理 10,000 个图像包中的第一个。
以下是您可以在数据集中找到的一些图像示例:
![Dataset description and loading](img/00103.jpg)
## 数据集预处理
我们必须对原始数据集进行一些数据结构调整,首先将其转换为`[10000, 3, 32, 32]`多维数组,然后将通道维移动到最后一个顺序。
```py
datadir='data/cifar-10-batches-bin/'
plt.ion()
G = glob.glob (datadir + '*.bin')
A = np.fromfile(G[0],dtype=np.uint8).reshape([10000,3073])
labels = A [:,0]
images = A [:,1:].reshape([10000,3,32,32]).transpose (0,2,3,1)
plt.imshow(images[14])
print labels[11]
images_unroll = A [:,1:]
```
## 建模架构
在这里,我们将定义我们的建模函数,该函数是一系列卷积和池化操作,并使用最终的平坦层和逻辑回归来确定当前样本的分类概率。
```py
def conv_model (X, y):
X= tf. reshape(X, [-1, 32, 32, 3])
with tf.variable_scope('conv_layer1'):
h_conv1=tf.contrib.layers.conv2d(X, num_outputs=16, kernel_size=[5,5], activation_fn=tf.nn.relu)#print (h_conv1)
h_pool1=max_pool_2x2(h_conv1)#print (h_pool1)
with tf.variable_scope('conv_layer2'):
h_conv2=tf.contrib.layers.conv2d(h_pool1, num_outputs=16, kernel_size=[5,5], activation_fn=tf.nn.relu)
#print (h_conv2)
h_pool2=max_pool_2x2(h_conv2)
h_pool2_flat = tf.reshape(h_pool2, [-1,8*8*16 ])
h_fc1 = tf.contrib.layers.stack(h_pool2_flat, tf.contrib.layers.fully_connected ,[96,48], activation_fn=tf.nn.relu )
return skflow.models.logistic_regression(h_fc1,y)
```
## 损失函数说明和优化器
以下是函数:
```py
classifier = skflow.TensorFlowEstimator(model_fn=conv_model, n_classes=10, batch_size=100, steps=2000, learning_rate=0.01)
```
### 训练和准确率测试
使用以下两个命令,我们开始使用图像集对模型进行拟合并生成训练后模型的评分:
```py
%time classifier.fit(images, labels, logdir='/tmp/cnn_train/')
%time score =metrics.accuracy_score(labels, classifier.predict(images))
```
## 结果描述
结果如下:
| 参数 | 结果 1 | 结果 2 |
| --- | --- | --- |
| CPU 时间 | 用户 35 分钟 6 秒 | 用户 39.8 秒 |
| 系统 | 1 分钟 50 秒 | 7.19 秒 |
| 总时间 | 36 分钟 57 秒 | 47 秒 |
| 墙上时间 | 25 分钟 3 秒 | 32.5 秒 |
| 准确率 | 0.612200 | |
### 完整源代码
以下是完整的源代码:
```py
import glob
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import tensorflow.contrib.learn as skflow
from sklearn import metrics
from tensorflow.contrib import learn
datadir='data/cifar-10-batches-bin/'
plt.ion()
G = glob.glob (datadir + '*.bin')
A = np.fromfile(G[0],dtype=np.uint8).reshape([10000,3073])
labels = A [:,0]
images = A [:,1:].reshape([10000,3,32,32]).transpose (0,2,3,1)
plt.imshow(images[15])
print labels[11]
images_unroll = A [:,1:]
def max_pool_2x2(tensor_in):
return tf.nn.max_pool(tensor_in, ksize= [1,2,2,1], strides= [1,2,2,1], padding='SAME')
def conv_model (X, y):
X= tf. reshape(X, [-1, 32, 32, 3])
with tf.variable_scope('conv_layer1'):
h_conv1=tf.contrib.layers.conv2d(X, num_outputs=16, kernel_size=[5,5], activation_fn=tf.nn.relu)#print (h_conv1)
h_pool1=max_pool_2x2(h_conv1)#print (h_pool1)
with tf.variable_scope('conv_layer2'):
h_conv2=tf.contrib.layers.conv2d(h_pool1, num_outputs=16, kernel_size=[5,5], activation_fn=tf.nn.relu)
#print (h_conv2)
h_pool2=max_pool_2x2(h_conv2)
h_pool2_flat = tf.reshape(h_pool2, [-1,8*8*16 ])
h_fc1 = tf.contrib.layers.stack(h_pool2_flat, tf.contrib.layers.fully_connected ,[96,48], activation_fn=tf.nn.relu )
return skflow.models.logistic_regression(h_fc1,y)
images = np.array(images,dtype=np.float32)
classifier = skflow.TensorFlowEstimator(model_fn=conv_model, n_classes=10, batch_size=100, steps=2000, learning_rate=0.01)
%time classifier.fit(images, labels, logdir='/tmp/cnn_train/')
%time score =metrics.accuracy_score(labels, classifier.predict(images))
```
\ No newline at end of file
# 总结
在本章中,我们了解了最先进的神经网络架构的组成部分之一:卷积神经网络。 使用此新工具,我们可以处理更复杂的数据集和概念抽象,因此我们将能够了解最新的模型。
在下一章中,我们将使用另一种新形式的神经网络以及更新的神经网络架构的一部分:循环神经网络。
\ No newline at end of file
# 第 7 章 循环神经网络和 LSTM
回顾我们对更传统的神经网络模型的了解后,我们发现训练阶段和预测阶段通常以静态方式表示,其中输入作为输入,而我们得到输出,但我们不仅考虑了事件发生的顺序。与到目前为止回顾的预测模型不同,循环神经网络的预测取决于当前的输入向量以及先前的输入向量。
我们将在本章中介绍的主题如下:
* 了解循环神经网络的工作原理以及构建它们的主要操作类型
* 解释在更高级的模型(例如 LSTM)中实现的想法
* 在 TensorFlow 中应用 LSTM 模型来预测能耗周期
* 撰写新音乐,从 J.S Bach 的一系列研究开始
\ No newline at end of file
# 循环神经网络
知识通常不会从虚无中出现。 许多新的想法是先前知识的结合而诞生的,因此这是一种有用的模仿行为。 传统的神经网络不包含任何将先前看到的元素转换为当前状态的机制。
为了实现这一概念,我们有循环神经网络,即 RNN。 可以将循环神经网络定义为神经网络的顺序模型,该模型具有重用已给定信息的特性。 他们的主要假设之一是,当前信息依赖于先前的数据。 在下图中,我们观察到称为单元的 RNN 基本元素的简化图:
![Recurrent neural networks](img/00104.jpg)
单元的主要信息元素是输入(`Xt`),状态和输出(`ht`)。 但是正如我们之前所说,单元没有独立的状态,因此它还存储状态信息。 在下图中,我们将显示一个“展开”的 RNN 单元,显示其从初始状态到输出最终`h[n]`值的过程,中间有一些中间状态。
![Recurrent neural networks](img/00105.jpg)
一旦我们定义了单元的动态性,下一个目标就是研究制造或定义 RNN 单元的内容。 在标准 RNN 的最常见情况下,仅存在一个神经网络层,该神经网络层将输入和先前状态作为输入,应用 tanh 操作,并输出新状态`h(t+1).`
![Recurrent neural networks](img/00106.jpg)
这种简单的设置能够随着周期的过去而对信息进行汇总,但是进一步的实验表明,对于复杂的知识而言,序列距离使得难以关联某些上下文(例如,建筑师知道设计漂亮的建筑物)似乎是一种简单的结构, 请记住,但是将它们关联所需的上下文需要增加顺序才能将两个概念关联起来。 这也带来了爆炸和消失梯度的相关问题。
## 梯度爆炸和消失
循环神经网络的主要问题之一发生在反向传播阶段,鉴于其递归性质,误差反向传播所具有的步骤数与一个非常深的网络相对应。 梯度计算的这种级联可能在最后阶段导致非常不重要的值,或者相​​反,导致不断增加且不受限制的参数。 这些现象被称为消失和爆炸梯度。 这是创建 LSTM 架构的原因之一。
## LSTM 神经网络
长短期内存(LSTM)是一种特定的 RNN 架构,其特殊的架构使它们可以表示长期依赖性。 而且,它们是专门为记住长时间的信息模式和信息而设计的。
## 门操作 -- 基本组件
为了更好地理解 lstm 单元内部的构造块,我们将描述 LSTM 的主要操作块:gate 操作。
此操作基本上有一个多元输入,在此块中,我们决定让一些输入通过,将其他输入阻塞。 我们可以将其视为信息过滤器,并且主要有助于获取和记住所需的信息元素。
为了实现此操作,我们采用了一个多元控制向量(标有箭头),该向量与具有 S 型激活函数的神经网络层相连。 应用控制向量并通过 S 型函数,我们将得到一个类似于二元的向量。
我们将用许多开关符号来表示此操作:
![The gate operation - a fundamental component](img/00107.jpg)
定义了二元向量后,我们将输入函数与向量相乘,以便对其进行过滤,仅让部分信息通过。 我们将用一个三角形来表示此操作,该三角形指向信息行进的方向。
![The gate operation - a fundamental component](img/00108.jpg)
LSTM 单元格的一般结构
在下面的图片中,我们代表了 LSTM Cell 的一般结构。 它主要由上述三个门操作组成,以保护和控制单元状态。
此操作将允许丢弃(希望不重要)低状态数据,并且将新数据(希望重要)合并到状态中。
![The gate operation - a fundamental component](img/00109.jpg)
上一个图试图显示一个 LSTM Cell 的运行中发生的所有概念。
作为输入,我们有:
* 单元格状态将存储长期信息,因为它从一开始就从单元格训练的起点进行优化的权重,并且
* 短期状态`h(t)`,将在每次迭代中直接与当前输入结合使用,因此,其状态将受输入的最新值的影响更大
作为输出,我们得到了结合所有门操作的结果。
## 操作步骤
在本节中,我们将描述信息将对其操作的每个循环步骤执行的所有不同子步骤的概括。
### 第 1 部分 -- 设置要忘记的值(输入门)
在本节中,我们将采用来自短期的值,再加上输入本身,并且这些值将由多元 S 型表示的二元函数的值设置。 根据输入和短期记忆值,S 形输出将允许或限制一些先前的知识或单元状态中包含的权重。
![Part 1 - set values to forget (input gate)](img/00110.jpg)
### 第 2 部分 -- 设置要保留的值,更改状态
然后是时候设置过滤器了,该过滤器将允许或拒绝将新的和短期的内存合并到单元半永久状态。
因此,在此阶段,我们将确定将多少新信息和半新信息合并到新单元状态中。 此外,我们最终将通过我们一直在配置的信息过滤器,因此,我们将获得更新的长期状态。
为了规范新的和短期的信息,我们通过具有`tanh`激活的神经网络传递新的和短期的信息,这将允许在正则化(`-1,1`)范围内提供新信息。
![Part 2 - set values to keep, change state](img/00111.jpg)
### 第 3 部分 -- 输出已过滤的单元状态
现在轮到短期状态了。 它还将使用新的和先前的短期状态来允许新信息通过,但是输入将是长期状态,点乘以 tanh 函数,再一次将输入标准化为(`-1,1`)范围。
![Part 3 - output filtered cell state](img/00112.jpg)
## 其他 RNN 架构
通常,在本章中,假设 RNN 的领域更为广泛,我们将集中讨论 LSTM 类型的循环神经网络单元。 例如,还采用了 RNN 的其他变体,并为该领域增加了优势。
* 具有窥孔的 LSTM:在此网络中,单元门连接到单元状态
* Gate Recurring Unit:这是一个更简单的模型,它结合了忘记门和输入门,合并了单元的状态和隐藏状态,因此大大简化了网络的训练
## TensorFlow LSTM 有用的类和方法
在本节中,我们将回顾可用于构建 LSTM 层的主要类和方法,我们将在本书的示例中使用它们。
### 类`tf.nn.rnn_cell.BasicLSTMCell`
此类基本的 LSTM 递归网络单元,具有遗忘偏差,并且没有其他相关类型(如窥孔)的奇特特性,即使在不应影响的阶段,它也可以使单元查看所得状态。
以下是主要参数:
* `num_units`:整数,LSTM 单元的单元数
* `forget_bias`:浮动,此偏差(默认为`1`)被添加到忘记门,以便允许第一次迭代以减少初始训练步骤的信息丢失。
* `activation`:内部状态的激活函数(默认为标准`tanh`
### 类`MultiRNNCell`(`RNNCell`)
在将用于此特定示例的架构中,我们将不会使用单个单元来考虑历史值。 在这种情况下,我们将使用一组连接的单元格。 因此,我们将实例化`MultiRNNCell`类。
```py
MultiRNNCell(cells, state_is_tuple=False)
```
这是`multiRNNCell`的构造函数,此方法的主要参数是单元格,它将是我们要堆栈的`RNNCells`的实例。
![class MultiRNNCell(RNNCell)](img/00113.jpg)
### `learning.ops.split_squeeze(dim, num_split, tensor_in)`
此函数将输入拆分为一个维度,然后压缩拆分后的张量所属的前一个维度。 它需要切割的尺寸,切割方式的数量,然后是张量的切割。 它返回相同的张量,但缩小一维。
\ No newline at end of file
# 示例 1 -- 能耗数据的单变量时间序列预测
在此示例中,我们将解决回归域的问题。 我们将要处理的数据集是一个周期内对一个家庭的许多功耗量度的汇总。 正如我们可以推断的那样,这种行为很容易遵循以下模式(当人们使用微波炉准备早餐时,这种行为会增加,醒来后的电脑数量会有所增加,下午可能会有所减少,而到了晚上,一切都会增加。 灯,从午夜开始直到下一个起床时间减少为零)。
因此,让我们尝试在一个示例案例中对此行为进行建模。
## 数据集说明和加载
在此示例中,我们将使用 [Artur Trindade](https://archive.ics.uci.edu/ml/datasets/ElectricityLoadDiagrams20112014) 的电力负荷图数据集。
这是原始数据集的描述:
> 数据集没有缺失值。 每 15 分钟以 kW 为单位的值。 要以 kWh 为单位转换值,必须将值除以 4。每一列代表一个客户端。 在 2011 年之后创建了一些客户。在这些情况下,消费被视为零。 所有时间标签均以葡萄牙语小时为单位。 但是,整天呈现 96 个小节(24 * 15)。 每年 3 月的时间更改日(只有 23 小时),所有时间点的凌晨 1:00 和 2:00 之间均为零。 每年 10 月的时间变更日(有 25 个小时),上午 1:00 和凌晨 2:00 之间的值合计消耗两个小时。
为了简化我们的模型描述,我们仅对一位客户进行了完整的测量,并将其格式转换为标准 CSV。 它位于本章代码文件夹的数据子文件夹中
使用以下代码行,我们将打开并表示客户的数据:
```py
import pandas as pd
from matplotlib import pyplot as plt
df = pd.read_csv("data/elec_load.csv", error_bad_lines=False)
plt.subplot()
plot_test, = plt.plot(df.values[:1500], label='Load')
plt.legend(handles=[plot_test])
```
![Dataset description and loading](img/00114.jpg)
我看一下这种表示形式(我们看一下前 1500 个样本),我们看到了一个初始瞬态状态,可能是在进行测量时可能出现的状态,然后我们看到了一个清晰的高,低功耗水平的循环。
从简单的观察中,我们还可以看到冰柱或多或少是 100 个样本的,非常接近该数据集每天的 96 个样本。
## 数据集预处理
为了确保反向传播方法更好的收敛性,我们应该尝试对输入数据进行正则化。
因此,我们将应用经典的缩放和居中技术,减去平均值,然后按最大值的底数进行缩放。
为了获得所需的值,我们使用熊猫`describe()`方法。
```py
Load
count 140256.000000
mean 145.332503
std 48.477976
min 0.000000
25% 106.850998
50% 151.428571
75% 177.557604
max 338.218126
```
![Dataset preprocessing](img/00115.jpg)
## 建模架构
在这里,我们将简要描述将尝试对电力消耗变化进行建模的架构:
最终的架构基本上由 10 个成员串联的 LSTM 多单元组成,该单元的末尾具有线性回归或变量,对于给定的历史记录,它将线性单元数组输出的结果转换为最终的实数。 值(在这种情况下,我们必须输入最后 5 个值才能预测下一个)。
```py
def lstm_model(time_steps, rnn_layers, dense_layers=None):
def lstm_cells(layers):
return [tf.nn.rnn_cell.BasicLSTMCell(layer['steps'],state_is_tuple=True)
for layer in layers]
def dnn_layers(input_layers, layers):
return input_layers
def _lstm_model(X, y):
stacked_lstm = tf.nn.rnn_cell.MultiRNNCell(lstm_cells(rnn_layers), state_is_tuple=True)
x_ = learn.ops.split_squeeze(1, time_steps, X)
output, layers = tf.nn.rnn(stacked_lstm, x_, dtype=dtypes.float32)
output = dnn_layers(output[-1], dense_layers)
return learn.models.linear_regression(output, y)
return _lstm_model
```
下图显示了主要模块,随后由学习模块进行了补充,您可以在其中看到 RNN 阶段,优化器以及输出之前的最终线性回归。
![Modelling architecture](img/00116.jpg)
在这张图片中,我们看了 RNN 阶段,在那里我们可以观察到各个 LSTM 单元的级联,输入的挤压以及该学习包所添加的所有互补操作。
![Modelling architecture](img/00117.jpg)
然后,我们将使用回归器完成模型的定义:
```py
regressor = learn.TensorFlowEstimator(model_fn=lstm_model(
TIMESTEPS, RNN_LAYERS, DENSE_LAYERS), n_classes=0,
verbose=2, steps=TRAINING_STEPS, optimizer='Adagrad',
learning_rate=0.03, batch_size=BATCH_SIZE)
```
## 损失函数说明
对于损失函数,经典回归参数均方误差将:
```py
rmse = np.sqrt(((predicted - y['test']) ** 2).mean(axis=0))
```
## 收敛性测试
在这里,我们将为当前模型运行拟合函数:
```py
regressor.fit(X['train'], y['train'], monitors=[validation_monitor], logdir=LOG_DIR)
```
并将获得以下内容(很好)! 错误率。 我们可以做的一项工作是避免对数据进行标准化,并查看平均误差是否相同(注意:不是,差很多)
这是我们将获得的简单控制台输出:
```py
MSE: 0.001139
```
这是生成的损耗/均值图形,它告诉我们误差在每次迭代中如何衰减:
![Convergency test](img/00118.jpg)
## 结果描述
现在我们可以得到真实测试值和预测值的图形,在图形中我们可以看到平均误差表明我们的递归模型具有很好的预测能力:
![Results description](img/00119.jpg)
## 完整源代码
以下是完整的源代码:
```py
import numpy as np
import pandas as pd
import tensorflow as tf
from matplotlib import pyplot as plt
from tensorflow.python.framework import dtypes
from tensorflow.contrib import learn
import logging
logging.basicConfig(level=logging.INFO)
from tensorflow.contrib import learn
from sklearn.metrics import mean_squared_error
LOG_DIR = './ops_logs'
TIMESTEPS = 5
RNN_LAYERS = [{'steps': TIMESTEPS}]
DENSE_LAYERS = None
TRAINING_STEPS = 10000
BATCH_SIZE = 100
PRINT_STEPS = TRAINING_STEPS / 100
def lstm_model(time_steps, rnn_layers, dense_layers=None):
def lstm_cells(layers):
return [tf.nn.rnn_cell.BasicLSTMCell(layer['steps'],state_is_tuple=True)
for layer in layers]
def dnn_layers(input_layers, layers):
return input_layers
def _lstm_model(X, y):
stacked_lstm = tf.nn.rnn_cell.MultiRNNCell(lstm_cells(rnn_layers), state_is_tuple=True)
x_ = learn.ops.split_squeeze(1, time_steps, X)
output, layers = tf.nn.rnn(stacked_lstm, x_, dtype=dtypes.float32)
output = dnn_layers(output[-1], dense_layers)
return learn.models.linear_regression(output, y)
return _lstm_model
regressor = learn.TensorFlowEstimator(model_fn=lstm_model(TIMESTEPS, RNN_LAYERS, DENSE_LAYERS), n_classes=0,
verbose=2, steps=TRAINING_STEPS, optimizer='Adagrad',
learning_rate=0.03, batch_size=BATCH_SIZE)
df = pd.read_csv("data/elec_load.csv", error_bad_lines=False)
plt.subplot()
plot_test, = plt.plot(df.values[:1500], label='Load')
plt.legend(handles=[plot_test])
print df.describe()
array=(df.values- 147.0) /339.0
plt.subplot()
plot_test, = plt.plot(array[:1500], label='Normalized Load')
plt.legend(handles=[plot_test])
listX = []
listy = []
X={}
y={}
for i in range(0,len(array)-6):
listX.append(array[i:i+5].reshape([5,1]))
listy.append(array[i+6])
arrayX=np.array(listX)
arrayy=np.array(listy)
X['train']=arrayX[0:12000]
X['test']=arrayX[12000:13000]
X['val']=arrayX[13000:14000]
y['train']=arrayy[0:12000]
y['test']=arrayy[12000:13000]
y['val']=arrayy[13000:14000]
# print y['test'][0]
# print y2['test'][0]
#X1, y2 = generate_data(np.sin, np.linspace(0, 100, 10000), TIMESTEPS, seperate=False)
# create a lstm instance and validation monitor
validation_monitor = learn.monitors.ValidationMonitor(X['val'], y['val'],
every_n_steps=PRINT_STEPS,
early_stopping_rounds=1000)
regressor.fit(X['train'], y['train'], monitors=[validation_monitor], logdir=LOG_DIR)
predicted = regressor.predict(X['test'])
rmse = np.sqrt(((predicted - y['test']) ** 2).mean(axis=0))
score = mean_squared_error(predicted, y['test'])
print ("MSE: %f" % score)
#plot_predicted, = plt.plot(array[:1000], label='predicted')
plt.subplot()
plot_predicted, = plt.plot(predicted, label='predicted')
plot_test, = plt.plot(y['test'], label='test')
plt.legend(handles=[plot_predicted, plot_test])
```
\ No newline at end of file
# 总结
在本章中,我们回顾了一种最新的神经网络架构,即循环神经网络,从而完善了机器学习领域主流方法的全景。
在下一章中,我们将研究在最先进的实现中出现的不同的神经网络层类型组合,并涵盖一些新的有趣的实验模型。
\ No newline at end of file
# 第 8 章 深度神经网络
在本章中,我们将回顾机器学习,深度神经网络中最先进的技术,也是研究最多的领域之一。
\ No newline at end of file
# 深度神经网络定义
这是一个新闻技术领域蓬勃发展的领域,每天我们都听到成功地将 DNN 用于解决新问题的实验,例如计算机视觉,自动驾驶,语音和文本理解等。
在前几章中,我们使用了与 DNN 相关的技术,尤其是在涉及卷积神经网络的技术中。
出于实际原因,我们将指深度学习和深度神经网络,即其中层数明显优于几个相似层的架构,我们将指代具有数十个层的神经网络架构,或者复杂结构的组合。
\ No newline at end of file
# 穿越时空的深度网络架构
在本节中,我们将回顾从 LeNet5 开始在整个深度学习历史中出现的里程碑架构。
## LeNet 5
在 1980 年代和 1990 年代,神经网络领域一直保持沉默。 尽管付出了一些努力,但是架构非常简单,并且需要大的(通常是不可用的)机器力量来尝试更复杂的方法。
1998 年左右,在 Bells 实验室中,在围绕手写校验数字分类的研究中,Ian LeCun 开始了一种新趋势,该趋势实现了所谓的“深度学习-卷积神经网络”的基础,我们已经在第 5 章,简单的前馈神经网络中对其进行了研究。
在那些年里,SVM 和其他更严格定义的技术被用来解决这类问题,但是有关 CNN 的基础论文表明,与当时的现有方法相比,神经网络的表现可以与之媲美或更好。
\ No newline at end of file
# Alexnet
经过几年的中断(即使 LeCun 继续将其网络应用到其他任务,例如人脸和物体识别),可用结构化数据和原始处理能力的指数增长,使团队得以增长和调整模型, 在某种程度上被认为是不可能的,因此可以增加模型的复杂性,而无需等待数月的训练。
来自许多技术公司和大学的计算机研究团队开始竞争一些非常艰巨的任务,包括图像识别。 对于以下挑战之一,即 Imagenet 分类挑战,开发了 Alexnet 架构:
![Alexnet](img/00125.jpg)
Alexnet 架构
## 主要功能
从其第一层具有卷积运算的意义上讲,Alexnet 可以看作是增强的 LeNet5。 但要添加未使用过的最大池化层,然后添加一系列密集的连接层,以建立最后的输出类别概率层。 视觉几何组(VGG)模型
图像分类挑战的其他主要竞争者之一是牛津大学的 VGG。
VGG 网络架构的主要特征是它们将卷积滤波器的大小减小到一个简单的 3x3,并按顺序组合它们。
微小的卷积内核的想法破坏了 LeNet 及其后继者 Alexnet 的最初想法,后者最初使用的过滤器高达 11x11 过滤器,但复杂得多且表现低下。 过滤器大小的这种变化是当前趋势的开始:
![Main features](img/00126.jpg)
VGG 中每层的参数编号摘要
然而,使用一系列小的卷积权重的积极变化,总的设置是相当数量的参数(数以百万计的数量级),因此它必须受到许多措施的限制。
## 原始的初始模型
在由 Alexnet 和 VGG 主导的两个主要研究周期之后,Google 凭借非常强大的架构 Inception 打破了挑战,该架构具有多次迭代。
这些迭代的第一个迭代是从其自己的基于卷积神经网络层的架构版本(称为 GoogLeNet)开始的,该架构的名称让人想起了始于网络的方法。
## GoogLenet(Inception V1)
![GoogLenet (Inception V1)](img/00127.jpg)
1 启动模块
GoogLeNet 是这项工作的第一个迭代,如下图所示,它具有非常深的架构,但是它具有九个链式初始模块的令人毛骨悚然的总和,几乎没有或根本没有修改:
![GoogLenet (Inception V1)](img/00128.jpg)
盗梦空间原始架构
与两年前发布的 Alexnet 相比,它是如此复杂,但它设法减少了所需的参数数量并提高了准确率。
但是,由于几乎所有结构都由相同原始结构层构建块的确定排列和重复组成,因此提高了此复杂架构的理解和可伸缩性。
## 批量归一化初始化(V2)
2015 年最先进的神经网络在提高迭代效率的同时,还存在训练不稳定的问题。
为了理解问题的构成,首先我们将记住在前面的示例中应用的简单正则化步骤。 它主要包括将这些值以零为中心,然后除以最大值或标准偏差,以便为反向传播的梯度提供良好的基线。
在训练非常大的数据集的过程中,发生的事情是,经过大量训练示例之后,不同的值振荡开始放大平均参数值,就像在共振现象中一样。 我们非常简单地描述的被称为协方差平移。
![Batch normalized inception (V2)](img/00129.jpg)
有和没有批量归一化的表现比较
这是开发批归一化技术的主要原因。
再次简化了过程描述,它不仅包括对原始输入值进行归一化,还对每一层上的输出值进行了归一化,避免了在层之间出现不稳定性之前就开始影响或漂移这些值。
这是 Google 在 2015 年 2 月发布的改进版 GoogLeNet 实现中提供的主要功能,也称为 Inception V2。
\ No newline at end of file
# Inception v3
快进到 2015 年 12 月,Inception 架构有了新的迭代。 两次发行之间月份的不同使我们对新迭代的开发速度有了一个想法。
此架构的基本修改如下:
* 将卷积数减少到最大 3x3
* 增加网络的总体深度
* 在每一层使用宽度增加技术来改善特征组合
下图说明了如何解释改进的启动模块:
![Inception v3](img/00130.jpg)
Inception V3 基本模块
这是整个 V3 架构的表示形式,其中包含通用构建模块的许多实例:
![Inception v3](img/00131.jpg)
Inception V3 总体图
\ No newline at end of file
# 总结
在本章中,我们学习了可应用于数据的主要数据结构和简单操作,并对计算图的各个部分进行了简要总结。
这些操作将成为即将出现的技术的基础。 通过这些类,数据科学家可以在查看当前数据的总体特征之后,确定类的分离或调整特征是否足够清晰,或者直接使用更复杂的工具,从而决定是否使用更简单的模型。
在下一章中,我们将开始构建和运行图,并使用本章中介绍的某些方法来解决问题。
\ No newline at end of file
# 残差网络(ResNet)
残差网络架构于 2015 年 12 月出现(与 Inception V3 几乎同时出现),它带来了一个简单而新颖的想法:不仅使用每个构成层的输出,还将该层的输出与原始输入结合。
在下图中,我们观察到 ResNet 模块之一的简化​​视图。 它清楚地显示了卷积层堆栈末尾的求和运算,以及最终的 relu 运算:
![Residual Networks (ResNet)](img/00132.jpg)
ResNet 一般架构
模块的卷积部分包括将特征从 256 个值减少到 64 个值,一个保留特征数的 3x3 过滤层以及一个从 64 x 256 个值增加 1x1 层的特征。 在最近的发展中,ResNet 的使用深度还不到 30 层,分布广泛。
## 其他深度神经网络架构
最近开发了很多神经网络架构。 实际上,这个领域是如此活跃,以至于我们每年或多或少都有新的杰出建筑外观。 最有前途的神经网络架构的列表是:
* SqueezeNet:此架构旨在减少 Alexnet 的参数数量和复杂性,声称减少了 50 倍的参数数量
* 高效神经网络(Enet):旨在构建更简单,低延迟的浮点运算数量,具有实时结果的神经网络
* Fractalnet:它的主要特征是非常深的网络的实现,不需要残留的架构,将结构布局组织为截断的分形
\ No newline at end of file
# 总结
在本章中,我们一直在学习不同的深度神经网络架构。
我们了解了如何构建近年来最著名的架构之一 VGG,以及如何使用它来生成可转换艺术风格的图像。
在下一章中,我们将使用机器学习中最有用的技术之一:图形处理单元。 我们将回顾安装具有 GPU 支持的 TensorFlow 所需的步骤并对其进行训练,并将执行时间与唯一运行的模型 CPU 进行比较。
\ No newline at end of file
# 第 9 章 大规模运行模型 -- GPU 和服务
到目前为止,我们一直在运行在主机的主 CPU 上运行的代码。 这意味着最多使用所有不同的处理器内核(低端处理器使用 2 或 4 个内核,高级处理器使用多达 16 个内核)。
在过去的十年中,通用处理单元(GPU)已成为所有高表现计算设置中无处不在的部分。 它的大量固有并行度非常适合于高维矩阵乘法以及机器学习模型训练和运行所需的其他运算。
尽管如此,即使拥有真正强大的计算节点,也存在许多任务,即使是最强大的单个服务器也无法应对。
因此,必须开发一种训练和运行模型的分布式方法。 这是分布式 TensorFlow 的原始功能。
在本章中,您将:
* 了解如何发现 TensorFlow 可用的计算资源
* 了解如何将任务分配给计算节点中的任何不同计算单元
* 了解如何记录 GPU 操作
* 了解如何不仅在主主机中而且在许多分布式单元的集群中分布计算
\ No newline at end of file
# TensorFlow 上的 GPU 支持
TensorFlow 对至少两种计算设备具有本机支持:CPU 和 GPU。 为此,它为支持的每种计算设备实现每个操作的一个版本:
![GPU support on TensorFlow](img/00136.jpg)
## 记录设备放置和设备能力
在尝试执行计算之前,TensorFlow 允许您记录所有可用资源。 这样,我们只能将操作应用于现有的计算类型。
### 查询计算能力
为了获取机器上计算元素的日志,我们可以在创建 TensorFlow 会话时使用`log_device_placement`标志,方法是:
```py
python
>>>Import tensorflow as tf
>>>sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
```
这是命令的输出:
![Querying the computing capabilities](img/00137.jpg)
选择 GPU 来运行代码
此长输出主要显示了所需的不同`CUDA`库的加载,然后显示了名称(`GRID K520`)和 GPU 的计算能力。
## 选择用于计算的 CPU
如果我们有可用的 GPU,但仍想继续使用 CPU,则可以通过`tf.Graph.device`方法选择一个。
方法调用如下:
```py
tf.Graph.device(device_name_or_function) :
```
该函数接收处理单元字符串,返回处理单元字符串的函数或不返回处理单元字符串,并返回分配了处理单元的上下文管理器。
如果参数是一个函数,则每个操作都将调用此函数来决定它将在哪个处理单元中执行,这是组合所有操作的有用元素。
### 设备命名
为了指定在指定设备时我们指的是哪个计算单元,TensorFlow 使用以下格式的简单方案:
![Device naming](img/00138.jpg)
设备 ID 格式
设备标识示例包括:
* `"/cpu:0"`:计算机的第一个 CPU
* `"/gpu:0"`:您计算机的 GPU(如果有)
* `"/gpu:1"`:计算机的第二个 GPU,依此类推
可用时,如果没有相反指示,则使用第一个 GPU 设备。
\ No newline at end of file
# 示例 1 -- 将操作分配给 GPU
在此示例中,我们将创建两个张量,将现有 GPU 定位为默认位置,并将在配置了 CUDA 环境的服务器上执行张量总和(您将在附录 A-库安装和其他中学习安装该张量) 提示)。
![Example 1 - assigning an operation to the GPU](img/00139.jpg)
在这里,我们看到常量和求和操作都是在`/gpu:0`服务器上构建的。 这是因为 GPU 是可用时首选的计算设备类型。
\ No newline at end of file
# 示例 2 -- 并行计算 Pi
该示例将作为并行处理的介绍,实现 Pi 的蒙特卡洛近似。
蒙特卡洛(Monte Carlo)利用随机数序列执行近似。
为了解决这个问题,我们将抛出许多随机样本,因为我们知道圆内的样本与正方形上的样本之比与面积比相同。
![Example 2 - calculating Pi number in parallel](img/00140.jpg)
随机区域计算技术
计算假设概率分布均匀,则分配的样本数与图形的面积成比例。
我们使用以下比例:
![Example 2 - calculating Pi number in parallel](img/00141.jpg)
Pi 的面积比例
从上述比例,我们可以推断出圆中的样本数/正方形的样本数也是`0.78`
另一个事实是,我们可以为计算生成的随机样本越多,答案就越近似。 这是在增加 GPU 数量时会给我们带来更多样本和准确率。
我们做的进一步减少是我们生成(X,Y)坐标,范围从(0..1),因此随机数生成更直接。 因此,我们需要确定样本是否属于圆的唯一标准是`distance = d &lt; 1.0`(圆的半径)。
## 解决方案实现
该解决方案将基于 CPU。 它将管理服务器中拥有的 GPU 资源(在本例中为`4`),然后我们将接收结果,并进行最终的样本求和。
### 提示
注意:此方法的收敛速度非常慢,为 O(n &lt;sup class="calibre32"&gt;1/2&lt;/sup&gt; ),但由于其简单性,将作为示例。
![Solution implementation](img/00142.jpg)
计算任务时间表
在上图中,我们看到了计算的并行行为,即样本生成和主要活动计数。
## 源代码
源代码如下:
```py
import tensorflow as tf
import numpy as np
c = []
#Distribute the work between the GPUs
for d in ['/gpu:0', '/gpu:1', '/gpu:2', '/gpu:3']:
#Generate the random 2D samples
i=tf.constant(np.random.uniform(size=10000), shape=[5000,2])
with tf.Session() as sess:
tf.initialize_all_variables()
#Calculate the euclidean distance to the origin
distances=tf.reduce_sum(tf.pow(i,2),1)
#Sum the samples inside the circle
tempsum = sess.run(tf.reduce_sum(tf.cast(tf.greater_equal(tf.cast(1.0,tf.float64),distances),tf.float64)))
#append the current result to the results array
c.append( tempsum)
#Do the final ratio calculation on the CPU
with tf.device('/cpu:0'):
with tf.Session() as sess:
sum = tf.add_n(c)
print (sess.run(sum/20000.0)*4.0)
```
\ No newline at end of file
# 分布式 TensorFlow
分布式 TensorFlow 是一项补充技术,旨在轻松高效地创建计算节点集群,并以无缝方式在节点之间分配作业。
这是创建分布式计算环境以及大规模执行模型的训练和运行的标准方法,因此能够完成生产,大量数据设置中的主要任务非常重要。
## 技术组件
在本节中,我们将描述分布式 TensorFlow 计算设置上的所有组件,从最细粒度的任务元素到整个集群描述。
### 作业
作业定义了一组同类任务,通常针对解决问题领域的同一子集。
区分作业的示例有:
* 参数服务器作业,它将模型参数存储在一个单独的作业中,并负责将初始和当前参数值分配给所有分布式节点
* 工作器作业,在其中执行所有计算密集型任务
### 任务
任务是工作的细分,执行不同的步骤或并行的工作单元以解决其工作的问题区域,并且通常附加到单个过程中。
每个作业都有许多任务,它们由索引标识。 通常,索引为 0 的任务被视为主要任务或协调者任务。
### 服务器
服务器是代表专用于实现任务的一组物理设备的逻辑对象。 服务器将专门分配给一个任务。
#### 组合概述
在下图中,我们将代表集群计算设置中的所有参与部分:
![Combined overview](img/00143.jpg)
TensorFlow 集群设置元素
该图包含由`ps`和 worker 作业代表的两个作业,以及可以从客户端为其创建的 grpc 通讯通道(在附录 A-库安装和附加提示中介绍)。 对于每种作业类型,都有服务器执行不同的任务,从而解决了作业域问题的子集。
### 创建一个 TensorFlow 集群
分布式集群程序的第一个任务是定义和创建一个 ClusterSpec 对象,该对象包含真实服务器实例的地址和端口,它们将成为集群的一部分。
定义此 ClusterSpec 的两种主要方法是:
* 创建一个`tf.train.ClusterSpec`对象,该对象指定所有群集任务
* 在创建`tf.train.Server`时,传递上述 ClusterSpec 对象,并将本地任务与作业名称和任务索引相关联
#### ClusterSpec 定义格式
ClusterSpec 对象是使用协议缓冲区格式定义的,该格式是基于 JSON 的特殊格式。
格式如下:
```py
{
"job1 name": [
"task0 server uri",
"task1 server uri"
...
]
...
"jobn name"[
"task0 server uri",
"task1 server uri"
]})
...
```
因此,这将是使用参数服务器任务服务器和三个工作者任务服务器创建集群的函数调用:
```py
tf.train.ClusterSpec({
"worker": [
"wk0.example.com:2222",
"wk1.example.com:2222",
"wk2.example.com:2222"
],
"ps": [
"ps0.example.com:2222",
]})
```
#### 创建`tf.Train.Server`
创建 ClusterSpec 之后,我们现在可以在运行时准确了解集群配置。 我们将继续创建本地服务器实例,并创建一个`tf.train.Server`实例:
这是一个示例服务器创建,它使用集群对象,作业名称和任务索引作为参数:
```py
server = tf.train.Server(cluster, job_name="local", task_index=[Number of server])
```
## 集群操作 -- 将计算方法发送到任务
为了开始学习集群的操作,我们需要学习计算资源的寻址。
首先,我们假设我们已经创建了一个集群,它具有不同的作业和任务资源。 任何资源的 ID 字符串具有以下形式:
![Cluster operation - sending computing methods to tasks](img/00144.jpg)
上下文管理器中资源的常规调用是 with 关键字,具有以下结构。
```py
with tf.device("/job:ps/task:1"):
[Code Block]
```
with 关键字指示在需要任务标识符时,将使用上下文管理器指令中指定的任务标识符。
下图说明了一个示例集群设置,其中包含设置的所有不同部分的地址名称:
![Cluster operation - sending computing methods to tasks](img/00145.jpg)
服务器元素命名
### 分布式示例代码结构
此示例代码将向您显示解决集群中不同任务的程序的大致结构,特别是参数服务器和辅助作业:
```py
#Address the Parameter Server task
with tf.device("/job:ps/task:1"):
weights = tf.Variable(...)
bias = tf.Variable(...)
#Address the Parameter Server task
with tf.device("/job:worker/task:1"):
#... Generate and train a model
layer_1 = tf.nn.relu(tf.matmul(input, weights_1) + biases_1)
logits = tf.nn.relu(tf.matmul(layer_1, weights_2) + biases_2)
train_op = ...
#Command the main task of the cluster
with tf.Session("grpc://worker1.cluster:2222") as sess:
for i in range(100):
sess.run(train_op)
```
\ No newline at end of file
# 示例 3 -- 分布式 Pi 计算
在此示例中,我们将更改视角,从一台具有多个计算资源的服务器变为一台具有多个资源的服务器集群。
分布式版本的执行将具有不同的设置,如下图所示:
![Example 3 - distributed Pi calculation](img/00146.jpg)
分布式协调运行
## 服务器脚本
该脚本将在每个计算节点上执行,这将生成一批样本,并通过可用服务器的数量增加生成的随机数的数量。 在这种情况下,我们将使用两台服务器,并假设我们在本地主机中启动它们,并在命令行中指示索引号。 如果要在单独的节点中运行它们,则只需替换 ClusterSpec 定义中的本地主机地址(如果希望它更具代表性,则可以替换名称)。
该脚本的源代码如下:
```py
import tensorflow as tf
tf.app.flags.DEFINE_string("index", "0","Server index")
FLAGS = tf.app.flags.FLAGS
print FLAGS.index
cluster = tf.train.ClusterSpec({"local": ["localhost:2222", "localhost:2223"]})
server = tf.train.Server(cluster, job_name="local", task_index=int(FLAGS.index))
server.join()
```
在 localhost 中执行此脚本的命令行如下:
```py
python start_server.py -index=0 #Server task 0
python start_server.py -index=1 #Server task 1
```
这是其中一台服务器的预期输出:
![Server script](img/00147.jpg)
单个服务器启动命令行
## 客户端脚本
然后,我们获得了客户端脚本,该脚本将向集群成员发送随机数创建任务,并将执行最终的 Pi 计算,几乎与 GPU 示例相同。
## 完整源代码
源代码如下:
```py
import tensorflow as tf
import numpy as np
tf.app.flags.DEFINE_integer("numsamples", "100","Number of samples per server")
FLAGS = tf.app.flags.FLAGS
print ("Sample number per server: " + str(FLAGS.numsamples) )
cluster = tf.train.ClusterSpec({"local": ["localhost:2222", "localhost:2223"]})
#This is the list containing the sumation of samples on any node
c=[]
def generate_sum():
i=tf.constant(np.random.uniform(size=FLAGS.numsamples*2), shape=[FLAGS.numsamples,2])
distances=tf.reduce_sum(tf.pow(i,2),1)
return (tf.reduce_sum(tf.cast(tf.greater_equal(tf.cast(1.0,tf.float64),distances),tf.int32)))
with tf.device("/job:local/task:0"):
test1= generate_sum()
with tf.device("/job:local/task:1"):
test2= generate_sum()
#If your cluster is local, you must replace localhost by the address of the first node
with tf.Session("grpc://localhost:2222") as sess:
result = sess.run(tf.cast(test1 + test2,tf.float64)/FLAGS.numsamples*2.0)
print(result)
```
\ No newline at end of file
# 示例 4 -- 在集群中运行分布式模型
这个非常简单的示例将为我们提供分布式 TensorFlow 设置工作原理的示例。
在此示例中,我们将执行一个非常简单的任务,尽管如此,它仍将在机器学习过程中采取所有必需的步骤。
![Example 4 - running a distributed model in a cluster](img/00148.jpg)
分布式训练集群设置
`Ps Server`将包含要求解的线性函数的不同参数(在本例中为`x``b0`),两个工作服务器将对变量进行训练,该变量将不断更新和改进。 最后一个,在协作模式下工作。
## 示例代码
示例代码如下:
```py
import tensorflow as tf
import numpy as np
from sklearn.utils import shuffle
# Here we define our cluster setup via the command line
tf.app.flags.DEFINE_string("ps_hosts", "",
"Comma-separated list of hostname:port pairs")
tf.app.flags.DEFINE_string("worker_hosts", "",
"Comma-separated list of hostname:port pairs")
# Define the characteristics of the cluster node, and its task index
tf.app.flags.DEFINE_string("job_name", "", "One of 'ps', 'worker'")
tf.app.flags.DEFINE_integer("task_index", 0, "Index of task within the job")
FLAGS = tf.app.flags.FLAGS
def main(_):
ps_hosts = FLAGS.ps_hosts.split(",")
worker_hosts = FLAGS.worker_hosts.split(",")
# Create a cluster following the command line paramaters.
cluster = tf.train.ClusterSpec({"ps": ps_hosts, "worker": worker_hosts})
# Create the local task.
server = tf.train.Server(cluster,
job_name=FLAGS.job_name,
task_index=FLAGS.task_index)
if FLAGS.job_name == "ps":
server.join()
elif FLAGS.job_name == "worker":
# Assigns ops to the local worker by default.
with tf.device(tf.train.replica_device_setter(
worker_device="/job:worker/task:%d" % FLAGS.task_index,
cluster=cluster)):
#Define the training set, and the model parameters, loss function and training operation
trX = np.linspace(-1, 1, 101)
trY = 2 * trX + np.random.randn(*trX.shape) * 0.4 + 0.2 # create a y value
X = tf.placeholder("float", name="X") # create symbolic variables
Y = tf.placeholder("float", name = "Y")
def model(X, w, b):
return tf.mul(X, w) + b # We just define the line as X*w + b0
w = tf.Variable(-1.0, name="b0") # create a shared variable
b = tf.Variable(-2.0, name="b1") # create a shared variable
y_model = model(X, w, b)
loss = (tf.pow(Y-y_model, 2)) # use sqr error for cost function
global_step = tf.Variable(0)
train_op = tf.train.AdagradOptimizer(0.8).minimize(
loss, global_step=global_step)
#Create a saver, and a summary and init operation
saver = tf.train.Saver()
summary_op = tf.merge_all_summaries()
init_op = tf.initialize_all_variables()
# Create a "supervisor", which oversees the training process.
sv = tf.train.Supervisor(is_chief=(FLAGS.task_index == 0),
logdir="/tmp/train_logs",
init_op=init_op,
summary_op=summary_op,
saver=saver,
global_step=global_step,
save_model_secs=600)
# The supervisor takes care of session initialization, restoring from
# a checkpoint, and closing when done or an error occurs.
with sv.managed_session(server.target) as sess:
# Loop until the supervisor shuts down
step = 0
while not sv.should_stop() :
# Run a training step asynchronously.
# See `tf.train.SyncReplicasOptimizer` for additional details on how to
# perform *synchronous* training.
for i in range(100):
trX, trY = shuffle (trX, trY, random_state=0)
for (x, y) in zip(trX, trY):
_, step = sess.run([train_op, global_step],feed_dict={X: x, Y: y})
#Print the partial results, and the current node doing the calculation
print ("Partial result from node: " + str(FLAGS.task_index) + ", w: " + str(w.eval(session=sess))+ ", b0: " + str(b.eval(session=sess)))
# Ask for all the services to stop.
sv.stop()
if __name__ == "__main__":
tf.app.run()
```
在参数服务器当前主机中:
```py
python trainer.py --ps_hosts=localhost:2222 --worker_hosts=localhost:2223,localhost:2224 --job_name=ps -task_index=0
he first
```
在工作器主机编号中:
```py
python trainer.py --ps_hosts=localhost:2222 --worker_hosts=localhost:2223,localhost:2224 --job_name=worker -task_index=0
```
在第二个工作者主机中:
```py
python trainer.py --ps_hosts=localhost:2222 --worker_hosts=localhost:2223,localhost:2224 --job_name=worker --task_index=1
```
\ No newline at end of file
# 第 2 章 聚类
在本章中,我们将开始应用在上一章中学到的数据转换操作,并开始使用聚类技术在某些给定信息中找到有趣的模式,发现数据组或集群。
在此过程中,我们还将获得两个新工具:能够通过 scikit-learn 库从一组代表性数据结构中生成合成样本集,并且能够通过 matplotlib 库以图形方式绘制我们的数据和模型结果 。
我们将在本章中介绍的主题如下:
* 了解群集的工作原理,并将其与替代的现有分类技术进行比较
* 使用 scikit-learn 和 matplotlib 丰富数据集选择的可能性,并获得看起来专业的数据图形表示
* 实现 k 均值聚类算法
* 实现最近邻法,并将结果与​​k 均值进行比较
\ No newline at end of file
# 总结
在本章中,我们回顾了 TensorFlow 工具箱中的两个主要元素,以在高表现环境中实现我们的模型,无论是在单服务器还是分布式集群环境中。
在下一章中,我们将查看有关如何在各种环境和工具下安装 TensorFlow 的详细说明。
\ No newline at end of file
# 第 10 章 库安装和其他提示
有多种安装 TensorFlow 的选项。 Google 已经为许多架构,操作系统和图形处理单元(GPU)准备了软件包。 尽管在 GPU 上机器学习任务的执行速度要快得多,但是两个安装选项都可用:
* CPU:它将在机器处理核心的所有处理单元中并行工作。
* GPU:此选项仅在使用多种架构之一的情况下才能使用,这些架构利用了非常强大的图形处理单元,即 NVIDIA 的 CUDA 架构。 还有许多其他架构/框架,例如 Vulkan,还没有达到成为标准的临界数量。
在本章中,您将学习:
* 如何在三种不同的操作系统(Linux,Windows 和 OSX)上安装 TensorFlow
* 如何测试安装以确保您能够运行示例,并从中开发自己的脚本
* 关于我们正在准备的其他资源,以简化您对机器学习解决方案进行编程的方式
\ No newline at end of file
# Windows 安装
现在轮到 Windows 操作系统了。 首先,我们必须说这不是 TensorFlow 生态系统的首选,但是我们绝对可以使用 Windows 操作系统进行开发。
## 经典 Docker 工具箱方法
此方法使用经典的工具箱方法,该方法可用于大多数最新的 Windows 版本(从 Windows 7 开始,始终使用 64 位操作系统)。
### 提示
为了使 Docker(特别是 VirtualBox)正常工作,您需要安装 VT-X 扩展。 这是您需要在 BIOS 级别执行的任务。
### 安装步骤
在这里,我们将列出在 Windows 中通过 Docker 安装`tensorflow`所需的不同步骤。
#### 下载 Docker 工具箱安装程序
安装程序的当前 URL 位于[此链接](https://github.com/docker/toolbox/releases/download/v1.12.0/DockerToolbox-1.12.0.exe)
执行安装程序后,我们将看到第一个安装屏幕:
![Downloading the Docker toolbox installer](img/00158.jpg)
Docker Toolbox 安装第一个屏幕
![Downloading the Docker toolbox installer](img/00159.jpg)
Docker 工具箱安装程序路径选择器
然后,选择安装中需要的所有组件:
![Downloading the Docker toolbox installer](img/00160.jpg)
Docker Toolbox 软件包选择屏幕
完成各种安装操作后,我们的 Docker 安装将准备就绪:
![Downloading the Docker toolbox installer](img/00161.jpg)
Docker 工具箱安装最终屏幕
#### 创建 Docker 机器
为了创建初始机器,我们将在 Docker Terminal 中执行以下命令:
```py
docker-machine create vdocker -d virtualbox
```
![Creating the Docker machine](img/00162.jpg)
Docker 初始映像安装
然后,在命令窗口中,键入以下内容:
```py
FOR /f "tokens=*" %i IN ('docker-machine env --shell cmd vdocker') DO %i docker run -it b.gcr.io/tensorflow/tensorflow
```
这将打印并读取运行最近创建的虚拟机所需的许多变量。
最后,要安装`tensorflow`容器,请像在 Linux 控制台上一样从同一控制台进行操作:
```py
docker run -it -p 8888:8888 gcr.io/tensorflow/tensorflow
```
### 提示
如果您不想执行 Jupyter,但想直接启动到控制台,则可以通过以下方式运行 Docker 映像:
```py
run -it -p 8888:8888 gcr.io/tensorflow/tensorflow bash
```
\ No newline at end of file
# MacOS X 安装
现在转到在 MacOS X 上进行安装。安装过程与 Linux 非常相似。 它们基于 OS X El Capitan 版本。 我们还将参考不支持 GPU 的 2.7 版 Python。
安装要求安装用户具有 sudo 特权。
## 安装点
在此步骤中,我们将使用`easy_install`软件包管理器安装 pip 软件包管理器,该软件包管理器包含在安装工具 Python 软件包中,并且默认情况下包含在操作系统中。
对于此安装,我们将在终端中执行以下操作:
```py
$ sudo easy_install pip
```
![Install pip](img/00163.jpg)
然后,我们将安装六个模块,这是一个兼容性模块,可帮助 Python 2 程序支持 Python 3 编程:
要安装`six`,我们执行以下命令:
```py
sudo easy_install --upgrade six
```
![Install pip](img/00164.jpg)
在安装`six`软件包之后,我们通过执行以下命令来继续安装`tensorflow`软件包:
```py
sudo pip install -ignore-packages six https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.10.0-py2-none-any.whl
```
![Install pip](img/00165.jpg)
然后我们调整`numpy`包的路径,这在 El Capitan 中是必需的:
```py
sudo easy_install numpy
```
![Install pip](img/00166.jpg)
现在我们准备导入`tensorflow`模块并运行一些简单的示例:
![Install pip](img/00167.jpg)
\ No newline at end of file
# 总结
在本章中,我们回顾了可以执行 TensorFlow 安装的一些主要方法。
即使可能性是有限的,每个月左右我们都会看到支持新的架构或处理器,因此我们只能期望该技术的应用领域越来越多。
\ No newline at end of file
# 从数据中学习 -- 无监督学习
在本章中,我们将回顾两种无监督学习的情况。
无监督学习基本上包括在先前的数据集中查找模式。 通常,很少或没有信息提供给该技术,并且该过程应该能够自动确定信息的组织方式,并识别数据组织中的不同结构。
\ No newline at end of file
# 聚类
最初可用于未标记数据集的最简单的操作之一是尝试了解数据集成员共同特征的可能组。
为此,可以将数据集划分为任意数量的段,其中每个段都可以表示为中心质量(质心)点,该点代表属于已确定组或聚类的点。
为了定义将同一组分配给不同组成员的标准,我们需要定义一个表示数据元素之间距离的概念,因此我们可以简单地说,所有类成员比任何其他质心更接近自己的质心 。
在下图中,我们可以看到典型聚类算法的结果以及聚类中心的表示形式:
![Clustering](img/00025.jpg)
样本聚类算法输出
\ No newline at end of file
# k 均值
k-means 是一种非常流行的聚类算法,可以轻松实现。 这非常简单,将它作为具有良好类分离性的数据集的第一个过程应用,可以对数据有很好的先验理解。
## k 均值的力学
k 均值尝试使用成员的平均值作为主要指标,将一组样本分成 k 个不相交的组或簇。 这一点通常称为质心,指代具有相同名称的算术实体,并表示为任意尺寸空间中的向量。
k 均值是一种幼稚的方法,因为它通过查找适当的质心而起作用,但是不知道先验簇的数量是多少。
为了评估多少簇能够很好地表示所提供的数据,Elbow 方法是一种比较流行的方法。
### 算法迭代准则
此方法的标准和目标是最小化从群集成员到所有包含群集的样本的实际质心的平方距离之和。 这也称为惯性最小化。
![Algorithm iteration criterion](img/00026.jpg)
k 均值的误差最小化准则
![](img/tex-1.gif)
## k 均值算法细分
k-means 算法的机制可以通过以下流程图总结:
![k-means algorithm breakdown](img/00027.jpg)
k 均值过程的简化流程图
该算法可以简化如下:
1. 我们从未分类的样本开始,以 k 个元素为起始质心。 为了简洁起见,也可以简化此算法,使元素列表中的第一个元素成为第一个元素。
2. 然后,我们计算样本与首先选择的样本之间的距离,并获得第一个计算出的质心(或其他代表值)。 您可以看到图中的质心向着更常识的质心移动。
3. 形心更改后,它们的位移将引起各个距离发生更改,因此群集成员身份可能会更改。
4. 这是我们重新计算质心并在不满足停止条件的情况下重复第一步的时候。
停止条件可以有多种类型:
* 在 N 次迭代之后,可能是要么我们选择了一个非常大的数,然后我们将进行不必要的计算,否则它可能会收敛得很慢,并且如果质心没有非常稳定的方法,我们将得到非常令人难以置信的结果。 如果我们有一个很长的迭代过程,那么这个停止条件也可以作为最后的手段。
* 参考先前的平均结果,可能的更好的迭代收敛标准是看重心的变化,无论是在总位移还是总簇元切换中。 最后一个通常被使用,因此一旦没有更多元素从其当前群集更改为另一个群集,我们将停止该过程。
![k-means algorithm breakdown](img/00028.jpg)
k 均值简化图形
### k 均值的优缺点
这种方法的优点是:
* 它可以很好地扩展(大多数计算可以并行运行)
* 它已经被用于很多应用中
但是,简单性也要付出代价(没有适用的规则):
* 它需要先验知识(可能的簇数应事先知道)
* 离群值可以推入质心的值,因为它们的值与任何其他样本相同
* 由于我们假设该图是凸且各向同性的,因此对于非圆形定界簇来说效果不佳
\ No newline at end of file
# 使用 TensorFlow 构建机器学习项目中文版
\ No newline at end of file
# 使用 TensorFlow 构建机器学习项目中文版
+ [使用 TensorFlow 构建机器学习项目中文版](README.md)
+ [第 1 章 探索和转换数据](0.md)
+ [TensorFlow 的主要数据结构 -- 张量](1.md)
+ [处理计算工作流程 -- TensorFlow 的数据流程图](2.md)
+ [运行我们的程序 -- 会话](3.md)
+ [基本张量方法](4.md)
+ [总结](5.md)
+ [第 2 章 聚类](6.md)
+ [从数据中学习 -- 无监督学习](7.md)
+ [聚类](8.md)
+ [k 均值](9.md)
+ [k 最近邻](10.md)
+ [项目 1 -- 在合成数据集上进行 k 均值聚类](11.md)
+ [项目 2 -- 综合数据集上的最近邻](12.md)
+ [总结](13.md)
+ [第 3 章 线性回归](14.md)
+ [单变量线性建模函数](15.md)
+ [成本函数的确定](16.md)
+ [最小化成本函数](17.md)
+ [示例部分](18.md)
+ [示例 1 -- 单变量线性回归](19.md)
+ [示例 2 -- 多元线性回归](20.md)
+ [总结](21.md)
+ [第 4 章 逻辑回归](22.md)
+ [问题描述](23.md)
+ [sigmoid 函数的前身 -- Logit 函数](24.md)
+ [sigmoid 函数](25.md)
+ [示例 1 -- 单变量 logistic 回归](26.md)
+ [示例 2 -- 使用 skflow 的单变量 logistic 回归](27.md)
+ [总结](28.md)
+ [第 5 章 简单的前馈神经网络](29.md)
+ [初步概念](30.md)
+ [第一个项目 -- 非线性合成函数回归](31.md)
+ [第二个项目 -- 使用非线性回归建模汽车的燃油效率](32.md)
+ [第三个项目 -- 学习葡萄酒分类:多类分类](33.md)
+ [总结](34.md)
+ [第 6 章 卷积神经网络](35.md)
+ [卷积神经网络的起源](36.md)
+ [示例 1 -- MNIST 数字分类](37.md)
+ [示例 2 -- 使用 CIFAR10 数据集进行图像分类](38.md)
+ [总结](39.md)
+ [第 7 章 循环神经网络和 LSTM](40.md)
+ [循环神经网络](41.md)
+ [示例 1 -- 能耗数据的单变量时间序列预测](42.md)
+ [示例 2 -- 编写音乐 “a la” Bach](43.md)
+ [总结](44.md)
+ [第 8 章 深度神经网络](45.md)
+ [深度神经网络定义](46.md)
+ [穿越时空的深度网络架构](47.md)
+ [Alexnet](48.md)
+ [Inception v3](49.md)
+ [残差网络(ResNet)](50.md)
+ [示例 -- 使用风格绘画 -- VGG 风格迁移](51.md)
+ [总结](52.md)
+ [第 9 章 大规模运行模型 -- GPU 和服务](53.md)
+ [TensorFlow 上的 GPU 支持](54.md)
+ [示例 1 -- 将操作分配给 GPU](55.md)
+ [示例 2 -- 并行计算 Pi](56.md)
+ [分布式 TensorFlow](57.md)
+ [示例 3 -- 分布式 Pi 计算](58.md)
+ [示例 4 -- 在集群中运行分布式模型](59.md)
+ [总结](60.md)
+ [第 10 章 库安装和其他提示](61.md)
+ [Linux 安装](62.md)
+ [Windows 安装](63.md)
+ [MacOS X 安装](64.md)
+ [总结](65.md)
+ [一、探索和转换数据](ch01.md)
+ [二、聚类](ch02.md)
+ [三、线性回归](ch03.md)
+ [四、逻辑回归](ch04.md)
+ [五、简单的前馈神经网络](ch05.md)
+ [六、卷积神经网络](ch06.md)
+ [七、循环神经网络和 LSTM](ch07.md)
+ [八、深度神经网络](ch08.md)
+ [九、大规模运行模型 -- GPU 和服务](ch09.md)
+ [十、库安装和其他提示](ch10.md)
# 一、探索和转换数据
TensorFlow 是用于使用数据流图进行数值计算的开源软件库。 图中的节点表示数学运算,而图的边缘表示在它们之间传递的多维数据数组(张量)。
该库包含各种函数,使您能够实现和探索用于图像和文本处理的最先进的卷积神经网络(CNN)和循环神经网络(RNN)架构。 由于复杂的计算以图的形式排列,因此 TensorFlow 可用作框架,使您能够轻松开发自己的模型并将其用于机器学习领域。
它还能够在从 CPU 到移动处理器(包括高度并行的 GPU 计算)的大多数异构环境中运行,并且新的服务架构可以在所有指定选项的非常复杂的混合环境中运行:
![Exploring and Transforming Data](img/00002.jpg)
# TensorFlow 的主要数据结构 -- 张量
TensorFlow 的数据管理基于张量。 张量是来自数学领域的概念,并且是作为向量和矩阵的线性代数项的概括而开发的。
专门讨论 TensorFlow 时,张量只是在张量对象中建模的带类型的多维数组,带有其他操作。
## 张量属性 -- 阶数,形状和类型
如前所述,TensorFlow 使用张量数据结构表示所有数据。 任何张量都具有静态类型和动态尺寸,因此您可以实时更改张量的内部组织。
张量的另一个特性是,只有张量类型的对象才能在计算图中的节点之间传递。
现在让我们看一下张量的属性是什么(从现在开始,每次使用张量这个词时,我们都将引用 TensorFlow 的张量对象)。
### 张量阶数
张量阶数表示张量的维度方面,但与矩阵阶数不同。 它表示张量所处的维数,而不是行/列或等效空间中张量扩展的精确度量。
秩张量等于向量,秩张量是矩阵。 对于第二张量,您可以使用语法 t [i,j]访问任何元素。 对于三阶张量,您将需要使用 t [i,j,k]来寻址元素,依此类推。
在下面的示例中,我们将创建一个张量,并访问其分量之一:
```py
>>> import tensorflow as tf
>>> tens1 = tf.constant([[[1,2],[2,3]],[[3,4],[5,6]]])
>>> print sess.run(tens1)[1,1,0]
5
```
这是三阶张量,因为在包含矩阵的每个元素中都有一个向量元素:
| 秩 | 数学实体 | 代码定义示例 |
| --- | --- | --- |
| 0 | 标量 | `scalar = 1000` |
| 1 | 向量 | `vector = [2, 8, 3]` |
| 2 | 矩阵 | `matrix = [[4, 2, 1], [5, 3, 2], [5, 5, 6]]` |
| 3 | 3 阶张量 | `tensor = [[[4], [3], [2]], [[6], [100], [4]], [[5], [1], [4]]]` |
| n | n 阶张量 | ... |
### 张量形状
TensorFlow 文档使用三种符号约定来描述张量维数:阶数,形状和维数。 下表显示了它们之间的相互关系:
| 秩 | 形状 | 维度数量 | 例 |
| --- | --- | --- | --- |
| 0 | `[]` | 0 | `4` |
| 1 | `[D0]` | 1 | `[2]` |
| 2 | `[D0,D1]` | 2 | `[6, 2]` |
| 3 | `[D0,D1,D2]` | 3 | `[7, 3, 2]` |
| n | `[D0,D1,... Dn-1]` | d | 形状为`[D0, D1, ..., Dn-1]`的张量。 |
在下面的示例中,我们创建一个样本阶数三张量,并打印其形状:
![Tensor shape](img/00003.jpg)
### 张量数据类型
除了维数外,张量还具有固定的数据类型。 您可以将以下任意一种数据类型分配给张量:
| 数据类型 | Python 类型 | 描述 |
| --- | --- | --- |
| `DT_FLOAT` | `tf.float32` | 32 位浮点。 |
| `DT_DOUBLE` | `tf.float64` | 64 位浮点。 |
| `DT_INT8` | `tf.int8` | 8 位有符号整数。 |
| `DT_INT16` | `tf.int16` | 16 位有符号整数。 |
| `DT_INT32` | `tf.int32` | 32 位有符号整数。 |
| `DT_INT64` | `tf.int64` | 64 位有符号整数。 |
| `DT_UINT8` | `tf.uint8` | 8 位无符号整数。 |
| `DT_STRING` | `tf.string` | 可变长度字节数组。 张量的每个元素都是一个字节数组。 |
| `DT_BOOL` | `tf.bool` | 布尔。 |
## 创建新的张量
我们可以创建自己的张量,也可以从著名的 numpy 库派生它们。 在以下示例中,我们创建一些 numpy 数组,并对其进行一些基本数学运算:
```py
import tensorflow as tf
import numpy as np
x = tf.constant(np.random.rand(32).astype(np.float32))
y= tf.constant ([1,2,3])
```
### 从 numpy 到张量,以及反向
TensorFlow 可与 numpy 互操作,通常`eval()`函数调用将返回一个 numpy 对象,准备与标准数值工具一起使用。
### 提示
我们必须注意,张量对象是操作结果的符号句柄,因此它不保存其包含的结构的结果值。 因此,我们必须运行`eval()`方法来获取实际值,该值等于`Session.run(tensor_to_eval)`
在此示例中,我们构建了两个 numpy 数组,并将它们转换为张量:
```py
import tensorflow as tf #we import tensorflow
import numpy as np #we import numpy
sess = tf.Session() #start a new Session Object
x_data = np.array([[1.,2.,3.],
[3.,2.,6.]]) # 2x3 matrix
x = tf.convert_to_tensor(x_data, dtype=tf.float32) #Finally, we create the tensor, starting from the fload 3x matrix
```
#### 有用的方法
`tf.convert_to_tensor`:此函数将各种类型的 Python 对象转换为张量对象。 它接受 tensorobjects,numpy 数组,Python 列表和 Python 标量。
## 完成工作 -- 与 TensorFlow 交互
与大多数 Python 模块一样,TensorFlow 允许使用 Python 的交互式控制台:
![Getting things done - interacting with TensorFlow](img/00004.jpg)
与 Python 的解释器和 TensorFlow 库轻松交互
在上图中,我们调用 Python 解释器(通过简单地调用 Python)并创建常量类型的张量。 然后我们再次调用它,Python 解释器显示张量的形状和类型。
我们还可以使用 IPython 解释器,该解释器将允许我们采用与笔记本样式工具(例如 Jupyter)更兼容的格式:
![Getting things done - interacting with TensorFlow](img/00005.jpg)
IPython 提示
在谈论以交互方式运行 TensorFlow 会话时,最好使用`InteractiveSession`对象。
与普通的`tf.Session`类不同,`tf.InteractiveSession`类将自身安装为构造时的默认会话。 因此,当您尝试评估张量或运行操作时,将不需要传递`Session`对象来指示它所引用的会话。
# 处理计算工作流程 -- TensorFlow 的数据流程图
TensorFlow 的数据流图是模型计算如何工作的符号表示:
![Handling the computing workflow - TensorFlow's data flow graph](img/00006.jpg)
在 TensorBoard 上绘制的简单数据流图表示
简而言之,数据流图是一个完整的 TensorFlow 计算,表示为一个图,其中节点是操作,边是操作之间的数据流。
通常,节点执行数学运算,但也表示连接以输入数据或变量,或推出结果。
边缘描述节点之间的输入/输出关系。 这些数据边仅传输张量。 节点被分配给计算设备,并且一旦它们进入边缘上的所有张量都可用,就会异步并行执行。
所有运算都有一个名称,并表示一个抽象计算(例如,矩阵求逆或乘积)。
## 计算图构建
通常在库用户创建张量和模型将支持的操作时构建计算图,因此无需直接构建`Graph()`对象。 Python 张量构造函数,例如`tf.constant()`,会将必要的元素添加到默认图。 TensorFlow 操作也会发生同样的情况。
例如,`c = tf.matmul(a, b)`创建一个`MatMul`类型的操作,该操作将张量`a``b`作为输入并产生`c`作为输出。
### 有用的操作对象方法
* `tf.Operation.type`:返回操作的类型(例如`MatMul`
* `tf.Operation.inputs`:返回代表操作输入的张量对象列表
* `tf.Graph.get_operations()`:返回图中的操作列表
* `tf.Graph.version`:返回图的自动数字版本
## 馈送
TensorFlow 还提供了一种馈送机制,可将张量直接修补到图中的任何操作中。
提要用张量值临时替换操作的输出。 您将提要数据作为`run()`调用的参数提供。 提要仅用于传递给它的运行调用。 最常见的用例涉及通过使用`tf.placeholder()`创建特定的操作,使其指定为`feed`操作。
## 变量
在大多数计算中,图执行多次。 大多数张量都无法通过图的一次执行而幸存。 但是,变量是一种特殊的操作,它可以将句柄返回到持久可变的张量,该张量在图执行过程中仍然存在。 对于 TensorFlow 的机器学习应用,模型的参数通常存储在变量中保存的张量中,并在运行模型的训练图时进行更新。
### 变量初始化
要初始化变量,只需使用张量作为参数调用`Variable`对象构造函数。
在此示例中,我们使用`1000`零数组初始化了一些变量:
```py
b = tf.Variable(tf.zeros([1000]))
```
## 保存数据流程图
数据流图是使用 Google 的协议缓冲区编写的,因此以后可以使用多种语言进行读取。
### 图序列化语言 -- 协议缓冲区
协议缓冲区是一种不依赖语言,不依赖平台的可扩展机制,用于序列化结构化数据。 首先定义数据结构,然后可以使用专门生成的代码来使用多种语言进行读写。
#### 有用的方法
`tf.Graph.as_graph_def(from_version=None, add_shapes=False)`:返回此图的序列化`GraphDef`表示形式。
参数:
* `from_version`:如果设置了此选项,它将返回带有从该版本添加的节点的`GraphDef`
* `add_shapes`:如果`true`,则向每个节点添加一个 shape 属性
### 建立图的示例
在此示例中,我们将构建一个非常简单的数据流图,并观察生成的 protobuffer 文件的概述:
```py
import tensorflow as tf
g = tf.Graph()
with g.as_default():
import tensorflow as tf
sess = tf.Session()
W_m = tf.Variable(tf.zeros([10, 5]))
x_v = tf.placeholder(tf.float32, [None, 10])
result = tf.matmul(x_v, W_m)
print g.as_graph_def()
```
生成的 protobuffer(摘要)为:
```py
node {
name: "zeros"
op: "Const"
attr {
key: "dtype"
value {
type: DT_FLOAT
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 10
}
dim {
size: 5
}
}
float_val: 0.0
}
}
}
}
...
node {
name: "MatMul"
op: "MatMul"
input: "Placeholder"
input: "Variable/read"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
...
}
versions {
producer: 8
}
```
# 运行我们的程序 -- 会话
客户端程序通过创建会话与 TensorFlow 系统交互。 会话对象表示将在其中运行计算的环境。 Session 对象开始为空,并且当程序员创建不同的操作和张量时,它们将被自动添加到 Session 中,在调用`Run()`方法之前,该对象不会进行任何计算。
`Run()`方法采用一组需要计算的输出名称,以及一组可选的张量,以代替节点的某些输出输入到图中。
如果调用此方法,并且命名操作依赖于某些操作,则 Session 对象将执行所有这些操作,然后继续执行命名操作。
这条简单的线是创建会话所需的唯一一行:
```py
s = tf.Session()
Sample command line output:
tensorflow/core/common_runtime/local_session.cc:45]Localsessioninteropparallelism threads:6
```
# 基本张量方法
在本节中,我们将探索 TensorFlow 支持的一些基本方法。 它们对于初始数据探索和为更好的并行计算准备数据很有用。
......@@ -497,4 +785,13 @@ file.close()
您可以编写一个获取数据的小程序,将其填充到示例协议缓冲区中,将协议缓冲区序列化为字符串,然后使用`tf.python_io.TFRecordWriter`类将字符串写入`TFRecords`文件。
要读取`TFRecords`的文件,请将`tf.TFRecordReader``tf.parse_single_example`解码器一起使用。 `parse_single_example` `op`将示例协议缓冲区解码为张量。
\ No newline at end of file
要读取`TFRecords`的文件,请将`tf.TFRecordReader``tf.parse_single_example`解码器一起使用。 `parse_single_example` `op`将示例协议缓冲区解码为张量。
# 总结
在本章中,我们学习了可应用于数据的主要数据结构和简单操作,并对计算图的各个部分进行了简要总结。
这些操作将成为即将出现的技术的基础。 通过这些类,数据科学家可以在查看当前数据的总体特征之后,确定类的分离或调整特征是否足够清晰,或者直接使用更复杂的工具,从而决定是否使用更简单的模型。
在下一章中,我们将开始构建和运行图,并使用本章中介绍的某些方法来解决问题。
# 二、聚类
在本章中,我们将开始应用在上一章中学到的数据转换操作,并开始使用聚类技术在某些给定信息中找到有趣的模式,发现数据组或集群。
在此过程中,我们还将获得两个新工具:能够通过 scikit-learn 库从一组代表性数据结构中生成合成样本集,并且能够通过 matplotlib 库以图形方式绘制我们的数据和模型结果 。
我们将在本章中介绍的主题如下:
* 了解群集的工作原理,并将其与替代的现有分类技术进行比较
* 使用 scikit-learn 和 matplotlib 丰富数据集选择的可能性,并获得看起来专业的数据图形表示
* 实现 k 均值聚类算法
* 实现最近邻法,并将结果与​​k 均值进行比较
# 从数据中学习 -- 无监督学习
在本章中,我们将回顾两种无监督学习的情况。
无监督学习基本上包括在先前的数据集中查找模式。 通常,很少或没有信息提供给该技术,并且该过程应该能够自动确定信息的组织方式,并识别数据组织中的不同结构。
# 聚类
最初可用于未标记数据集的最简单的操作之一是尝试了解数据集成员共同特征的可能组。
为此,可以将数据集划分为任意数量的段,其中每个段都可以表示为中心质量(质心)点,该点代表属于已确定组或聚类的点。
为了定义将同一组分配给不同组成员的标准,我们需要定义一个表示数据元素之间距离的概念,因此我们可以简单地说,所有类成员比任何其他质心更接近自己的质心 。
在下图中,我们可以看到典型聚类算法的结果以及聚类中心的表示形式:
![Clustering](img/00025.jpg)
样本聚类算法输出
# k 均值
k-means 是一种非常流行的聚类算法,可以轻松实现。 这非常简单,将它作为具有良好类分离性的数据集的第一个过程应用,可以对数据有很好的先验理解。
## k 均值的力学
k 均值尝试使用成员的平均值作为主要指标,将一组样本分成 k 个不相交的组或簇。 这一点通常称为质心,指代具有相同名称的算术实体,并表示为任意尺寸空间中的向量。
k 均值是一种幼稚的方法,因为它通过查找适当的质心而起作用,但是不知道先验簇的数量是多少。
为了评估多少簇能够很好地表示所提供的数据,Elbow 方法是一种比较流行的方法。
### 算法迭代准则
此方法的标准和目标是最小化从群集成员到所有包含群集的样本的实际质心的平方距离之和。 这也称为惯性最小化。
![Algorithm iteration criterion](img/00026.jpg)
k 均值的误差最小化准则
![](img/tex-1.gif)
## k 均值算法细分
k-means 算法的机制可以通过以下流程图总结:
![k-means algorithm breakdown](img/00027.jpg)
k 均值过程的简化流程图
该算法可以简化如下:
1. 我们从未分类的样本开始,以 k 个元素为起始质心。 为了简洁起见,也可以简化此算法,使元素列表中的第一个元素成为第一个元素。
2. 然后,我们计算样本与首先选择的样本之间的距离,并获得第一个计算出的质心(或其他代表值)。 您可以看到图中的质心向着更常识的质心移动。
3. 形心更改后,它们的位移将引起各个距离发生更改,因此群集成员身份可能会更改。
4. 这是我们重新计算质心并在不满足停止条件的情况下重复第一步的时候。
停止条件可以有多种类型:
* 在 N 次迭代之后,可能是要么我们选择了一个非常大的数,然后我们将进行不必要的计算,否则它可能会收敛得很慢,并且如果质心没有非常稳定的方法,我们将得到非常令人难以置信的结果。 如果我们有一个很长的迭代过程,那么这个停止条件也可以作为最后的手段。
* 参考先前的平均结果,可能的更好的迭代收敛标准是看重心的变化,无论是在总位移还是总簇元切换中。 最后一个通常被使用,因此一旦没有更多元素从其当前群集更改为另一个群集,我们将停止该过程。
![k-means algorithm breakdown](img/00028.jpg)
k 均值简化图形
### k 均值的优缺点
这种方法的优点是:
* 它可以很好地扩展(大多数计算可以并行运行)
* 它已经被用于很多应用中
但是,简单性也要付出代价(没有适用的规则):
* 它需要先验知识(可能的簇数应事先知道)
* 离群值可以推入质心的值,因为它们的值与任何其他样本相同
* 由于我们假设该图是凸且各向同性的,因此对于非圆形定界簇来说效果不佳
# k 最近邻
k 最近邻(k-nn)是一种简单的经典聚类方法,它将很好地介绍此类技术,着眼于每个样本的附近,并假设每个新样本都应属于的类别。 已经知道的数据点。
![k-nearest neighbors](img/00029.jpg)
## k 最近邻的力学
k-nn 可以在我们的多种配置中实现,但是在本章中,我们将使用“半监督”方法。 我们将从一定数量的已分配样本开始,稍后我们将根据训练集的特征猜测集群成员。
![Mechanics of k-nearest neighbors](img/00030.jpg)
最近邻算法
在上图中,我们可以看到该算法的细分。 可以通过以下步骤进行总结:
1. 我们将先前已知的样本放在数据结构上。
2. 然后,我们读取要分类的下一个样本,并计算从新样本到训练集的每个样本的欧几里得距离。
3. 我们通过根据欧几里得距离选择最近的样本的类别来确定新元素的类别。 k-nn 方法需要对 k 个最接近的样本进行投票。
4. 我们重复该过程,直到没有剩余的样本为止。
### k-nn 的优缺点
这种方法的优点是:
* 简单; 无需调整参数
* 没有正规训练; 我们只需要更多的训练实例来改进模型
缺点:
* 计算昂贵(必须计算点与每个新样本之间的所有距离)
## 有用库的实用示例
在以下各节中,我们将讨论一些有用的库。
### matplotlib 绘图库
数据绘图是数据科学学科不可或缺的一部分。 因此,我们需要一个非常强大的框架来绘制结果。 对于此任务,我们没有在 TensorFlow 中实现的通用解决方案,我们将使用 matplotlib 库。
在 matplotlib 站点(`http://matplotlib.org/`)中,定义为:
> “ matplotlib 是一个 Python 2D 绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版物质量的图形。”
#### 合成样本的数据绘图
在此示例中,我们将生成一个包含 100 个随机数的列表,生成样本图,并将结果保存在图形文件中:
```py
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
with tf.Session() as sess:
fig, ax = plt.subplots()
ax.plot(tf.random_normal([100]).eval(), tf.random_normal([100] ).eval(),'o')
ax.set_title('Sample random plot for TensorFlow')
plt.savefig("result.png")
```
这是结果图像:
![Sample synthetic data plotting](img/00031.jpg)
使用 TensorFlow 和 matplotlib 生成的示例图
### 提示
为了查看 scikit 数据集模块的更一般的解释,请参考 [matplotlib.org](http://matplotlib.org/)
### scikit-learn 数据集模块
TensorFlow 当前未实现用于轻松生成合成数据集的方法。 因此,我们将使用`sklearn`库作为帮助程序。
#### 关于 scikit-learn 库
[从其网站](http://scikit-learn.org/stable/)
> “ scikit-learn(以前为 scikits.learn)是针对 Python 编程语言的开源机器学习库。它具有各种分类,回归和聚类模型,旨在与 Python 数字和科学库 NumPy 和 SciPy 互操作。”
在此示例中,我们将使用数据集模块,该模块处理许多众所周知的合成和现场提取的数据集的生成和加载。
### 提示
为了查看 scikit 数据集模块的更一般的解释,请参考[此链接](http://scikit-learn.org/stable/datasets/)
### 合成数据集类型
我们将使用一些生成的数据集类型:
![Synthetic dataset types](img/00032.jpg)
Blob,圆和月亮数据集类型
### Blob 数据集
该数据集是测试简单聚类算法的理想选择。 不会出现问题,因为数据是一致地分组的,并且类别的分离很明确。
#### 采用的方法
以下方法用于所采用的方法:
```py
sklearn.datasets.make_blobs(n_samples=100, n_features=2, centers=3, cluster_std=1.0, center_box=(-10.0, 10.0), shuffle=True, random_state=None)
```
在这里,`n_samples`是数据总数,`n_features`是数据的列数或特征数,`centers`是中心列表或许多随机中心,`cluster_std`是标准偏差,`center_box`是随机生成中心时每个聚类中心的边界框,`shuffle`指示是否必须对样本进行混洗,`random_state`是随机种子。
### 圆圈数据集
这是在其他圆圈中具有圆圈的数据集。 这是一个非线性的,可分离的问题,因此需要通过非线性模型来解决。 这排除了诸如 k 均值的简单算法。 在本章中,我们将尝试使用它来阐明观点。
#### 采用的方法
以下方法用于所采用的方法:
```py
sklearn.datasets.make_circles(n_samples=100,shuffle=True,noise=None, random_state=None,factor=0.8)
```
在这里,`n_samples`是数据总数,`shuffle`表示是否必须对样本进行混洗,`noise`是要应用于循环数据的随机量的数量,`random_state`是随机种子,并且`factor`是圆之间的比例因子。
### 月亮数据集
这是另一个非线性问题,但是具有另一种类型的类分离,因为没有诸如圆环之类的闭合。
# 项目 1 -- 在合成数据集上进行 k 均值聚类
## 数据集说明和加载
......@@ -218,4 +438,115 @@ print "Cluster assignments:", assignments
k 均值应用于圆形综合数据集
如我们所见,初始中心向样本数量最集中的区域漂移,因此将数据线性划分。 这是我们现阶段使用的简单模型的局限性之一。 为了处理非线性可分离性样本,我们可以尝试本章范围以外的其他统计方法,例如基于密度的带噪应用空间聚类(DBSCAN)。
\ No newline at end of file
如我们所见,初始中心向样本数量最集中的区域漂移,因此将数据线性划分。 这是我们现阶段使用的简单模型的局限性之一。 为了处理非线性可分离性样本,我们可以尝试本章范围以外的其他统计方法,例如基于密度的带噪应用空间聚类(DBSCAN)。
# 项目 2 -- 综合数据集上的最近邻
在这个项目中,我们将加载一个数据集,使用该数据集,以前的算法(k 均值)在分离类时遇到问题。
## 数据集生成
该数据集是第一个示例中具有两个类的相同循环类数据集,但是这次我们将通过增加一些噪声(从`0.01``0.12`)来增加错误概率:
```py
data, features = make_circles(n_samples=N, shuffle=True, noise=0.12,factor=0.4)
```
这是生成的训练数据图:
![Dataset generation](img/00038.jpg)
## 模型架构
将保留数据的变量只是原始数据和测试列表,其中将包含计算出的测试数据类:
```py
data, features = make_circles(n_samples=N, shuffle=True, noise= 0.12, factor=0.4)
tr_data, tr_features= data[:cut], features[:cut]
te_data,te_features=data[cut:], features[cut:]
test=[]
```
## 损失函数说明
在聚类中,我们将使用函数来优化为欧式距离,与第 1 章,探索和转换数据相同。 它是在集群分配循环上计算的,获取从新点到现有训练点的距离,要求最小值的索引,然后使用该索引搜索最近的邻居的类:
```py
distances = tf.reduce_sum(tf.square(tf.sub(i , tr_data)),reduction_indices=1)
neighbor = tf.arg_min(distances,0)
```
## 停止条件
在这个简单的示例中,一旦访问了测试分区的所有元素,我们将完成操作。
## 结果描述
这是测试数据类分布的图形,在这里我们可以看到清晰分开的类。 我们可以观察到,至少在此有限的数据集范围内,此方法比非重叠,斑点优化,k 均值方法更好。
![Results description](img/00039.jpg)
## 完整源代码
以下是完整的源代码:
```py
import tensorflow as tf
import numpy as np
import time
import matplotlib
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_circles
N=210
K=2
# Maximum number of iterations, if the conditions are not met
MAX_ITERS = 1000
cut=int(N*0.7)
start = time.time()
data, features = make_circles(n_samples=N, shuffle=True, noise= 0.12, factor=0.4)
tr_data, tr_features= data[:cut], features[:cut]
te_data,te_features=data[cut:], features[cut:]
test=[]
fig, ax = plt.subplots()
ax.scatter(tr_data.transpose()[0], tr_data.transpose()[1], marker = 'o', s = 100, c = tr_features, cmap=plt.cm.coolwarm )
plt.plot()
sess = tf.Session()
sess.run(tf.initialize_all_variables())
for i, j in zip(te_data, te_features):
distances = tf.reduce_sum(tf.square(tf.sub(i , tr_data)),reduction_indices=1)
neighbor = tf.arg_min(distances,0)
test.append(tr_features[sess.run(neighbor)])
print test
fig, ax = plt.subplots()
ax.scatter(te_data.transpose()[0], te_data.transpose()[1], marker = 'o', s = 100, c = test, cmap=plt.cm.coolwarm )
plt.plot()
end = time.time()
print ("Found in %.2f seconds" % (end-start))
print "Cluster assignments:", test
```
# 总结
在本章中,我们简单地概述了一些我们可以实现的最基本的模型,但是尝试在解释中尽可能地详细。
从现在开始,我们将能够生成综合数据集,从而使我们能够快速测试模型对于不同数据配置的适当性,从而评估它们的优缺点,而不必加载具有大量未知特征的模型。
此外,我们已经实现了第一个迭代方法并测试了收敛性,该任务将以类似的方式在后续章节中继续进行,但是将使用更精细,更精确的方法。
在下一章中,我们将使用线性函数解决分类问题,并且首次使用训练集中的先前数据来学习其特征。 这是监督学习技术的目标,通常对于解决许多现实生活中的问题更有用。
# 三、线性回归
在本章中,我们将开始应用机器学习项目中使用的所有标准步骤,以便使用一条使误差和损失函数最小化的线来拟合先前给定的数据。
在上一章中,我们看到了范围有限和许多可能解决方案的问题。 这些类型的模型还与定性评估类型相关,即基于先前的标签为样本分配标签。 通常在与社会领域有关的问题中发现该结果。
我们还可能对预测(先前建模的)函数的确切数字输出值感兴趣。 这种方法类似于物理领域,可用于在事先了解一系列历史值的情况下预测温度或湿度或某种商品的价值,这称为回归分析。
在线性回归的情况下,我们在输入变量和输出变量之间寻找线性关系表示的确定关系。
# 单变量线性建模函数
如前所述,在线性回归中,我们尝试找到一个线性方程,以最小化数据点和建模线之间的距离。
此关系可以用以下标准线性函数表示:
![Univariate linear modelling function](img/00040.jpg)
模型函数采用以下形式:
在这里,`ss0``bias`是截距,`x`的函数值为零,`ss1`是建模线的斜率。 变量`x`通常被称为自变量,`y`被称为因变量,但它们也可以分别称为回归变量和响应变量。
## 样本数据生成
在下面的示例中,我们将基于`ss0` = `2.0`的线,加上最大幅度为`0.4`的垂直噪声,生成近似样本随机分布。
```py
In[]:
#Indicate the matplotlib to show the graphics inline
%matplotlib inline
import matplotlib.pyplot as plt # import matplotlib
import numpy as np # import numpy
trX = np.linspace(-1, 1, 101) # Linear space of 101 and [-1,1]
#Create The y function based on the x axis
trY = 2 * trX + np.random.randn(*trX.shape) * 0.4 + 0.2
plt.figure() # Create a new figure
plt.scatter(trX,trY) #Plot a scatter draw of the random datapoints
# Draw one line with the line function
plt.plot (trX, .2 + 2 * trX)
```
结果图将如下所示:
![Sample data generation](img/00041.jpg)
加噪声线性采样和线性函数
# 成本函数的确定
与所有机器学习技术一样,我们必须确定一个误差函数,我们需要将其最小化,这表明解决问题的适当性。
用于线性回归的最常用的`cost`函数称为最小二乘。
## 最小二乘
为了计算函数的最小二乘误差,我们通常会寻找一种测量点与建模线的接近程度的方法。 因此,我们定义了一个函数,用于测量每个元组`x[n]``y[n]`与建模线的对应值之间的距离。
对于 2D 回归,我们有一个数字元组`(X[0],Y[0]),(X[1],Y[1])...(X[n],Y[n])`的列表,通过最小化以下函数,可以找到`β[0]``β[1]`的值:
![Least squares](img/00042.jpg)
简单来说,求和代表预测值与实际值之间的欧几里得距离之和。
进行运算的原因是,平方误差的总和为我们提供了一个唯一且简单的全局数,预期数与实数之差为我们提供了适当的距离,平方幂为我们提供了一个正数,这会惩罚一个整数。 多于线性的时尚。
# 最小化成本函数
下一步是设置最小化`cost`函数的方法。 在线性演算中,定位极小值任务的基本特征之一被简化为计算函数的导数并寻找其零点。 为此,该函数必须具有导数,最好是凸的。 可以证明最小二乘函数符合这两个条件。 这对于避免已知的局部极小问题非常有用。
![Minimizing the cost function](img/00043.jpg)
损失函数表示
## 最小二乘的一般最小值
我们尝试解决的问题(最小二乘)可以用矩阵形式表示:
![General minima for least squares](img/00044.jpg)
在此,`J`是成本函数,具有以下解决方案:
![General minima for least squares](img/00045.jpg)
在本章中,我们将使用迭代方法梯度下降,该方法将在以后的章节中以更通用的方式使用。
## 迭代方法 -- 梯度下降
梯度下降本身就是一种迭代方法,并且是机器学习领域中最常用的优化算法。 考虑到可以用它优化的参数组合的复杂性,它结合了简单的方法和良好的收敛速度。
2D 线性回归从具有随机定义的权重或线性系数乘数的函数开始。 定义第一个值后,第二步是以以下形式应用递归函数:
![Iterative methods - gradient descent](img/00046.jpg)
在该方程式中,我们可以轻松推导该方法的机理。 我们从一组初始系数开始,然后朝函数最大变化的相反方向移动。 `α`变量被称为 step,将影响我们在梯度搜索方向上移动最小的距离。
最后一步是可选地测试迭代之间的更改,并查看更改是否大于 epsilon 或检查是否达到了迭代次数。
如果函数不是凸函数,建议使用随机值多次运行梯度下降,然后选择成本值最低的系数。 在非凸函数的情况下,梯度下降最终以最小值出现,这可能是局部的。 因此,对于非凸函数,结果取决于初始值,建议将它们随机设置多次,并在所有解决方案中选择成本最低的解决方案。
# 示例部分
现在让我们讨论有用的库和模块。
## TensorFlow 中的优化器方法 -- 训练模块
训练或参数优化阶段是机器学习工作流程的重要组成部分。
为此,TensorFlow 具有一个`tf.train`模块,该模块是一组对象的帮助程序,致力于实现数据科学家所需的各种不同优化策略。 此模块提供的主要对象称为优化器。
### `tf.train.Optimizer`类
`Optimizer`类允许您为`loss`函数计算梯度并将其应用于模型的不同变量。 在最著名的算法子类中,我们找到了梯度下降,Adam 和 Adagrad。
关于该类的一个主要提示是`Optimizer`类本身无法实例化。 子类之一。
如前所述,TensorFlow 允许您以符号方式定义函数,因此梯度也将以符号方式应用,从而提高了结果的准确率以及要应用于数据的操作的通用性。
为了使用`Optimizer`类,我们需要执行以下步骤:
1. 创建具有所需参数的`Optimizer`(在这种情况下为梯度下降)。
```py
opt = GradientDescentOptimizer(learning_rate= [learning rate])
```
2.`cost`函数创建一个调用`minimize`方法的操作。
```py
optimization_op = opt.minimize(cost, var_list=[variables list])
```
`minimize`方法具有以下形式:
```py
tf.train.Optimizer.minimize(loss, global_step=None, var_list=None, gate_gradients=1, aggregation_method=None, colocate_gradients_with_ops=False, name=None)
```
主要参数如下:
* `loss`:这是一个张量,其中包含要最小化的值。
* `global_step``Optimizer`工作后,此变量将增加 1。
* `var_list`:包含要优化的变量。
### 提示
实际上,`optimize`方法结合了对`compute_gradients()``apply_gradients()`的调用。 如果要在应用梯度之前对其进行处理,请显式调用`compute_gradients()``apply_gradients()`,而不要使用此函数。 如果我们只想进行一步训练,就必须以`opt_op.run().`的形式执行`run`方法
### 其他优化器实例类型
以下是其他`Optimizer`实例类型:
* `tf.train.AdagradOptimizer`:这是一种基于参数频率的自适应方法,学习率单调下降。
* `tf.train.AdadeltaOptimizer`:这是对 Adagrad 的改进,它的学习率没有下降。
* `tf.train.MomentumOptimizer`:这是一种适应性方法,可解决尺寸之间的不同变化率。
* 并且还有其他更具体的参数,例如`tf.train.AdamOptimizer``tf.train.FtrlOptimizer``tf.train.RMSPropOptimizer`
# 示例 1 -- 单变量线性回归
现在,我们将在一个项目中工作,在该项目中,我们将应用前面几页中简要介绍的所有概念。 在此示例中,我们将创建一个近似线性分布; 之后,我们将创建一个回归模型,该模型试图拟合线性函数以最小化误差函数(由最小二乘法定义)。
给定一个新样本,该模型将使我们能够预测输入值的结果。
## 数据集说明
对于此示例,我们将生成一个包含线性函数并添加噪声的合成数据集:
```py
import TensorFlow as tf
import numpy as np
trX = np.linspace(-1, 1, 101)
trY = 2 * trX + np.random.randn(*trX.shape) * 0.4 + 0.2 # create a y value which is approximately linear but with some random noise
```
使用这些线,我们可以将线表示为散点图和理想线函数。
```py
import matplotlib.pyplot as plt
plt.scatter(trX,trY)
plt.plot (trX, .2 + 2 * trX)
```
![Dataset description](img/00047.jpg)
生成的样本和原始线性函数无噪声
## 模型架构
1. 现在,我们创建一个变量来保存`x``y`轴中的值。 然后,我们将模型定义为`X`和权重`w`的乘积。
2. 然后,我们生成一些变量,并为其分配初始值以启动模型:
```py
In[]:
X = tf.placeholder("float", name="X") # create symbolic variables
Y = tf.placeholder("float", name = "Y")
```
3. 现在,我们通过将`name_scope`声明为`Model`来定义模型。 此作用域将其包含的所有变量分组,以形成具有同类实体的唯一实体。 在此范围内,我们首先定义一个函数,该函数接收`x`轴坐标,权重(斜率)和偏差的变量。 然后,我们创建一个新变量`objects,`来保存不断变化的参数,并使用`y_model`变量实例化该模型:
```py
with tf.name_scope("Model"):
def model(X, w, b):
return tf.mul(X, w) + b # just define the line as X*w + b0
w = tf.Variable(-1.0, name="b0") # create a shared variable
b = tf.Variable(-2.0, name="b1") # create a shared variable
y_model = model(X, w, b)
```
在仪表板上,您可以看到我们一直在收集的损失函数的图像。 在图部分中,放大模型时,您可以看到求和与乘法运算,参数变量`b0``b1`以及应用于模型的梯度运算,如下所示:
![Model architecture](img/00048.jpg)
## 成本函数描述和优化器循环
1.`Cost Function`中,我们创建了一个新的范围以包括该组的所有操作,并使用先前创建的`y_model`来说明用于计算损失的计算出的`y`轴值。
```py
with tf.name_scope("CostFunction"):
cost = (tf.pow(Y-y_model, 2)) # use sqr error for cost
```
2. 为了定义选择的`optimizer,`,我们初始化一个`GradientDescentOptimizer`,步骤将是`0.01`,这似乎是收敛的合理起点。
```py
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost)
```
3. 现在是时候创建会话并初始化要保存在 TensorBoard 中进行查看的变量了。 在此示例中,我们将为每个迭代保存一个标量变量以及最后一个样本的误差结果。 我们还将图结构保存在文件中以供查看。
```py
sess = tf.Session()
init = tf.initialize_all_variables()
tf.train.write_graph(sess.graph,
'/home/ubuntu/linear','graph.pbtxt')
cost_op = tf.scalar_summary("loss", cost)
merged = tf.merge_all_summaries()
sess.run(init)
writer = tf.train.SummaryWriter('/home/ubuntu/linear',
sess.graph)
```
4. 对于模型训练,我们将目标设置为 100 次迭代,然后将每个样本发送到梯度下降的`train`操作。 每次迭代后,我们绘制建模线并将最后一个误差的值添加到`summary`中。
```py
In[]:
for i in range(100):
for (x, y) in zip(trX, trY):
sess.run(train_op, feed_dict={X: x, Y: y})
summary_str = sess.run(cost_op, feed_dict={X: x, Y: y})
writer.add_summary(summary_str, i)
b0temp=b.eval(session=sess)
b1temp=w.eval(session=sess)
plt.plot (trX, b0temp + b1temp * trX )
```
结果图如下: 我们可以看到初始行如何迅速收敛为更合理的结果:
![Cost function description and Optimizer loop](img/00049.jpg)
放大 CostFunction 范围后,我们可以看到幂和减法运算以及书面摘要,如下图所示:
![Cost function description and Optimizer loop](img/00050.jpg)
## 停止条件
## 结果描述
现在让我们检查参数结果,打印`w``b`变量的`run`输出:
```py
printsess.run(w) # Should be around 2
printsess.run(b) #Should be around 0.2
2.09422
0.256044
```
现在是时候再次以图形方式查看数据和建议的最后一行。
```py
plt.scatter(trX,trY)
plt.plot (trX, testb + trX * testw)
```
![Results description](img/00051.jpg)
## 使用 TensorBoard 查看结果
现在,让我们回顾一下保存在 TensorBoard 中的数据。
为了启动 TensorBoard,您可以转到 logs 目录并执行以下行:
```py
$ tensorboard --logdir=.
```
TensorBoard 将加载事件和图形文件,并且将在`6006`端口上监听。 然后,您可以从浏览器转到`localhost:6000`,然后查看 TensorBoard 仪表板,如下图所示:
![Reviewing results with TensorBoard](img/00052.jpg)
## 完整源代码
以下是完整的源代码:
```py
import matplotlib.pyplot as plt # import matplotlib
import numpy as np # import numpy
import tensorflow as tf
import numpy as np
trX = np.linspace(-1, 1, 101) #Create a linear space of 101 points between 1 and 1
trY = 2 * trX + np.random.randn(*trX.shape) * 0.4 + 0.2 #Create The y function based on the x axis
plt.figure() # Create a new figure
plt.scatter(trX,trY) #Plot a scatter draw of the random datapoints
plt.plot (trX, .2 + 2 * trX) # Draw one line with the line function
get_ipython().magic(u'matplotlib inline')
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
trX = np.linspace(-1, 1, 101)
trY = 2 * trX + np.random.randn(*trX.shape) * 0.4 + 0.2 # create a y value which is approximately linear but with some random noise
plt.scatter(trX,trY)
plt.plot (trX, .2 + 2 * trX)
X = tf.placeholder("float", name="X") # create symbolic variables
Y = tf.placeholder("float", name = "Y")
withtf.name_scope("Model"):
def model(X, w, b):
returntf.mul(X, w) + b # We just define the line as X*w + b0
w = tf.Variable(-1.0, name="b0") # create a shared variable
b = tf.Variable(-2.0, name="b1") # create a shared variable
y_model = model(X, w, b)
withtf.name_scope("CostFunction"):
cost = (tf.pow(Y-y_model, 2)) # use sqr error for cost function
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost)
sess = tf.Session()
init = tf.initialize_all_variables()
tf.train.write_graph(sess.graph, '/home/ubuntu/linear','graph.pbtxt')
cost_op = tf.scalar_summary("loss", cost)
merged = tf.merge_all_summaries()
sess.run(init)
writer = tf.train.SummaryWriter('/home/ubuntu/linear', sess.graph)
fori in range(100):
for (x, y) in zip(trX, trY):
sess.run(train_op, feed_dict={X: x, Y: y})
summary_str = sess.run(cost_op, feed_dict={X: x, Y: y})
writer.add_summary(summary_str, i)
b0temp=b.eval(session=sess)
b1temp=w.eval(session=sess)
plt.plot (trX, b0temp + b1temp * trX )
printsess.run(w) # Should be around 2
printsess.run(b) #Should be around 0.2
plt.scatter(trX,trY)
plt.plot (trX, sess.run(b) + trX * sess.run(w))
```
![Full source code](img/00053.jpg)
![Full source code](img/00051.jpg)
# 示例 2 -- 多元线性回归
在此示例中,我们将处理涉及多个变量的回归问题。
......@@ -234,4 +621,11 @@ print (b0temp)
print (b1temp)
#plt.plot (trX, b0temp + b1temp * trX )
```
\ No newline at end of file
```
# 总结
在本章中,我们使用 TensorFlow 的训练实用程序构建了第一个具有标准损失函数的完整模型。 我们还建立了一个多元模型来说明多个维度来计算回归。 除此之外,我们使用 TensorBoard 在训练阶段观察变量的行为。
在下一章中,我们将开始使用非线性模型,通过它我们将更接近神经网络领域,这是 TensorFlow 的主要支持领域,其效用提供了巨大价值。
# 四、逻辑回归
在上一章中,我们已经看到了一种将现实的一部分建模为线性函数的方法,该函数具有独立变量,并且偏差最小化了误差函数。
除了某些非常明确定义的问题(预期结果是连续的变量和函数)之外,这种特殊的分析还不够。
但是,如果我们面对具有定性因变量的数据,将会发生什么? 例如,是否存在确定的特征; 受试者有金色的头发吗? 病人以前有病吗?
这些是我们将在本章中处理的问题。
# 问题描述
线性回归旨在解决的问题不是基于连续函数的值预测,这一次,我们想知道样本属于确定类别的可能性。
在本章中,我们将依靠线性模型的一般化来解决回归问题,但最终目标是解决分类问题,我们必须应用标签或将观察集中的所有元素分配给预定义的组。
![Problem description](img/00058.jpg)
在上图中,我们可以看到如何对旧问题和新问题进行分类。 第一个(线性回归)可以想象为价值不断增长的连续体。
另一个是基于`x`值的输出只能具有两个不同值的域。 在第二张图的特定情况下,我们可以看到对其中一个选项的特定偏向极端:在左侧,偏向 0 `y`值,在右侧偏向某个值。 共 1。
鉴于即使在进行回归从而寻找连续值的情况下,这种项也可能有些棘手,实际上,最终目标是为具有离散变量的分类问题建立预测。
此处的关键是要了解我们将获得与类有关的项目的概率,而不是完全离散的值。
# sigmoid 函数的前身 -- Logit 函数
在研究逻辑函数之前,我们将回顾该函数所基于的原始函数,并为其提供一些更一般的属性。
本质上,当我们谈论`logit`函数时,我们正在使用随机变量`p`的函数,更具体地说,是与伯努利分布相对应的函数。
## 伯努利分布
在解释理论细节之前,值得注意的是伯努利分布是一个随机变量,它具有:
* 取值为 0 且失败概率为`q = 1 - p`
* 取值为 1,成功概率为`p`
可以表示如下(对于具有伯努利分布的随机变量`X`):
![Bernoulli distribution](img/00059.jpg)
这是一种概率分布,它将以二元选项的形式表示事件的发生概率,就像我们要表示自己的变量(特征的存在,事件的发生,现象的因果关系等)一样。
## 链接函数
在尝试建立广义线性模型时,我们要从线性函数开始,并从因变量开始,获取到概率分布的映射。
由于选项具有二元性质,因此通常选择的分布是最近提到的 Bernoulli 分布,而倾向于 logistic 函数的链接函数是`logit`函数。
## Logit 函数
我们可以利用的可能变量之一是`p`等于 1 的几率的自然对数。 此函数称为`logit`函数:
![Logit function](img/00060.jpg)
我们也可以将`logit`函数称为对数奇数函数,因为对于给定的概率`p`,我们正在计算赔率的对数`(p/1-p)`
![Logit function](img/00061.jpg)
因此,正如我们可以直观地推断出的那样,用自变量的组合替换`X`,无论它们的值是什么,用从负无穷大到无穷大的任何出现替换`X`,我们将响应缩放到`0``1`
## Logit 反函数的重要性
假设我们计算`logit`函数的逆。 这将使我们编写以下函数:
![The importance of the logit inverse](img/00062.jpg)
此函数是`sigmoid`函数。
# sigmoid 函数
逻辑函数将帮助我们在新的回归任务中表示二元类别。
在下图中,您将找到`sigmoid`函数的图形表示:
![The logistic function](img/00063.jpg)
逻辑函数或 Sigmoid 的图形表示
## Logistic 函数作为线性建模概括
逻辑函数`δ(t)`定义如下:
![Logistic function as a linear modeling generalization](img/00064.jpg)
该方程式的正常解释是`t`代表一个简单的自变量。 但是,我们将改进此模型,并假定`t`是单个解释变量`x`的线性函数(对 t 是多个解释变量的线性组合的情况进行类似处理)。
然后,我们将`t`表示为:
![Logistic function as a linear modeling generalization](img/00065.jpg)
### 最终估计的回归方程
因此,我们从以下等式开始:
![Final estimated regression equation](img/00066.jpg)
使用所有这些元素,我们可以计算回归方程,这将为我们提供回归概率:
![Final estimated regression equation](img/00067.jpg)
下图将显示如何将从任意范围的映射最终转换为范围`[0, 1]`,该范围可以解释为表示事件发生的概率 p:
![Final estimated regression equation](img/00068.jpg)
什么影响会改变线性函数的参数? 它们是将更改`sigmoid`函数的中心斜率和从零开始的位移的值,从而使其可以更精确地减小回归值与实际数据点之间的误差。
## 逻辑函数的属性
函数空间中的每条曲线都可以通过可能适用的目标来描述。 对于 logistic 函数,它们是:
* 根据一个或多个独立变量对事件的概率`p`进行建模。 例如,鉴于先前的资格,被授予奖品的可能性。
* 对确定的观测值进行估计(这是回归部分)`p`,与事件未发生的可能性有关。
* 预测自变量变化对二元响应的影响。
* 通过计算某项属于确定类别的概率对观察进行分类。
### 损失函数
在上一节中,我们看到了近似的`p^`函数,该函数将对样本属于特定类别的概率进行建模。 为了衡量我们对解的近似程度,我们将寻找精心选择的损失函数。
该损失函数表示为:
![Loss function](img/00069.jpg)
该损失函数的主要特性是它不会以类似的方式惩罚误差,当误差增加到远远超过 0.5 时,误差惩罚因子会渐近增长。
## 多类应用 -- softmax 回归
到目前为止,我们仅针对两个类的情况进行分类,或者以概率语言对事件发生概率`p`进行分类。
在要决定两个以上类别的情况下,有两种主要方法: 一对一,一对全。
* 第一种技术包括计算许多模型,这些模型代表每个类别相对于所有其他类别的概率。
* 第二个由一组概率组成,其中我们代表一个类别相对于所有其他类别的概率。
* 第二种方法是`softmax`回归的输出格式,它是 n 个类的逻辑回归的概括。
因此,为了训练样本,我们将使用句柄`y(i)ε{1,...,K},`将二元标签`( y(i)ε{0,1})`更改为向量标签,其中`K`是类别数,标签 Y 可以采用`K`不同的值, 而不是只有两个。
因此,对于这种特定技术,给定测试输入`X`,我们想要针对`k=1,...,K`的每个值估计`P``y=k|x`)的概率。 `softmax`回归将输出`K`维向量(其元素总和为 1),从而为我们提供了`K`估计的概率。
在下图中,我们表示在单类和多类逻辑回归的概率映射上发生的映射:
![Multiclass application - softmax regression](img/00070.jpg)
### 成本函数
`softmax`函数的成本函数是自适应的交叉熵函数,该函数不是线性的,因此对大阶函数差异的惩罚要比对小阶函数的惩罚更大。
![Cost function](img/00071.jpg)
在这里,`c`是类别编号,`I`是各个训练样本索引,`yc`对于期望的类别为 1,对于其余类别为 0。
扩展这个方程,我们得到以下结果:
![Cost function](img/00072.jpg)
### 迭代方法的数据标准化
正如我们将在以下各节中看到的那样,对于逻辑回归,我们将使用`gradient descent`方法来最小化成本函数。
![Data normalization for iterative methods](img/00073.jpg)
此方法对特征数据的形式和分布非常敏感。
因此,我们将进行一些预处理,以便获得更好,更快的收敛结果。
我们将把这种方法的理论原因留给其他书籍,但我们将总结其原因,即通过归一化可以平滑误差表面,使迭代`gradient descent`更快地达到最小误差。
### 输出的单热表示
为了将`softmax`函数用作回归函数,我们必须使用一种称为单热编码的编码。 这种编码形式只是将变量的数字整数值转换为数组,其中将值列表转换为数组列表,每个数组的长度与该列表的最大值相同,并且每个数组的表示方式是在值的索引上添加 1,其余元素保持为 0。
例如,这将是单热编码形式的列表[1、3、2、4]的表示形式:
```py
[[0 1 0 0 0]
[0 0 0 1 0]
[0 0 1 0 0]
[0 0 0 0 1]]
```
# 示例 1 -- 单变量 logistic 回归
在第一个示例中,我们将使用单变量 logistic 回归(患者年龄)来估计心脏病的概率。
......@@ -292,4 +476,106 @@ with tf.Session() as sess:
使用 TensorBoard 实用程序,我们将看到操作链。 请注意,在一半的操作图中,我们定义了主要的全局操作(“小数点”)以及应用于其余项的梯度操作,这是进行`loss`函数最小化所必需的。 这是接下来几章要讨论的主题。
![Graphical representation](img/00076.jpg)
\ No newline at end of file
![Graphical representation](img/00076.jpg)
# 示例 2 -- 使用 skflow 的单变量 logistic 回归
在此示例中,我们将探索单变量示例域,但是这次我们将使用来自新库的帮助,该库为我们简化了模型构建,称为`skflow`
## 有用的库和方法
在机器学习库领域中,有很多选择。 最知名的之一是`sklearn`,我们在第 2 章聚类中讨论过。
在 TensorFlow 发布之后的很早,一个新的贡献库就出现了,叫做`skflow`,其主要目的是模拟`sklearn`的界面和工作流程,在这个 TensorFlow 会话环境中工作更简洁。
在下面的示例中,我们将使用`skflow`界面重复先前回归的分析。
在示例中,我们还将看到 skflow 如何为回归模型自动生成详细且组织良好的图,只需将日志目录设置为参数即可。
## 数据集说明
使用`pandas`库,数据集加载阶段与前面的示例相同:
```py
import pandas as pd
df = pd.read_csv("data/CHD.csv", header=0)
print df.describe()
```
## 模型架构
这是`my_model`的代码段:
```py
def my_model(X, y):
return skflow.models.logistic_regression(X, y)
X1 =a.fit_transform(df['age'].astype(float))
y1 = df['chd'].values
classifier = skflow.TensorFlowEstimator(model_fn=my_model, n_classes=2)
```
在这里,我们可以使用`softmax`分类器查看逻辑回归阶段的详细视图:
![Model architecture](img/00077.jpg)
![Model architecture](img/00078.jpg)
## 结果描述
```py
score = metrics.accuracy_score(df['chd'].astype(float), classifier.predict(X))
print("Accuracy: %f" % score)
```
输出结果可观(为了简化模型)74%的准确率:
```py
Accuracy: 0.740000
```
## 完整源代码
这是完整的源代码:
```py
import tensorflow.contrib.learn as skflow
from sklearn import datasets, metrics, preprocessing
import numpy as np
import pandas as pd
df = pd.read_csv("data/CHD.csv", header=0)
print df.describe()
def my_model(X, y):
return skflow.models.logistic_regression(X, y)
a = preprocessing.StandardScaler()
X1 =a.fit_transform(df['age'].astype(float))
y1 = df['chd'].values
classifier = skflow.TensorFlowEstimator(model_fn=my_model, n_classes=2)
classifier.fit(X1,y1 , logdir='/tmp/logistic')
score = metrics.accuracy_score(df['chd'].astype(float), classifier.predict(X))
print("Accuracy: %f" % score)
```
# 总结
在本章中,我们学习了一种新的建模技术,即逻辑函数,并从一种简单的分类任务入手。
我们还学习了一种通过`pandas`库读取基于文本的数据的新方法。
此外,我们还看到了与`skflow`库一起使用的经典工作流的一种补充方法。
在下一章中,我们将开始处理更复杂的架构,并进入 TensorFlow 库擅长的领域:训练,测试和最终实现神经网络以解决实际问题。
# 八、深度神经网络
在本章中,我们将回顾机器学习,深度神经网络中最先进的技术,也是研究最多的领域之一。
# 深度神经网络定义
这是一个新闻技术领域蓬勃发展的领域,每天我们都听到成功地将 DNN 用于解决新问题的实验,例如计算机视觉,自动驾驶,语音和文本理解等。
在前几章中,我们使用了与 DNN 相关的技术,尤其是在涉及卷积神经网络的技术中。
出于实际原因,我们将指深度学习和深度神经网络,即其中层数明显优于几个相似层的架构,我们将指代具有数十个层的神经网络架构,或者复杂结构的组合。
# 穿越时空的深度网络架构
在本节中,我们将回顾从 LeNet5 开始在整个深度学习历史中出现的里程碑架构。
## LeNet 5
在 1980 年代和 1990 年代,神经网络领域一直保持沉默。 尽管付出了一些努力,但是架构非常简单,并且需要大的(通常是不可用的)机器力量来尝试更复杂的方法。
1998 年左右,在 Bells 实验室中,在围绕手写校验数字分类的研究中,Ian LeCun 开始了一种新趋势,该趋势实现了所谓的“深度学习-卷积神经网络”的基础,我们已经在第 5 章,简单的前馈神经网络中对其进行了研究。
在那些年里,SVM 和其他更严格定义的技术被用来解决这类问题,但是有关 CNN 的基础论文表明,与当时的现有方法相比,神经网络的表现可以与之媲美或更好。
# Alexnet
经过几年的中断(即使 LeCun 继续将其网络应用到其他任务,例如人脸和物体识别),可用结构化数据和原始处理能力的指数增长,使团队得以增长和调整模型, 在某种程度上被认为是不可能的,因此可以增加模型的复杂性,而无需等待数月的训练。
来自许多技术公司和大学的计算机研究团队开始竞争一些非常艰巨的任务,包括图像识别。 对于以下挑战之一,即 Imagenet 分类挑战,开发了 Alexnet 架构:
![Alexnet](img/00125.jpg)
Alexnet 架构
## 主要功能
从其第一层具有卷积运算的意义上讲,Alexnet 可以看作是增强的 LeNet5。 但要添加未使用过的最大池化层,然后添加一系列密集的连接层,以建立最后的输出类别概率层。 视觉几何组(VGG)模型
图像分类挑战的其他主要竞争者之一是牛津大学的 VGG。
VGG 网络架构的主要特征是它们将卷积滤波器的大小减小到一个简单的 3x3,并按顺序组合它们。
微小的卷积内核的想法破坏了 LeNet 及其后继者 Alexnet 的最初想法,后者最初使用的过滤器高达 11x11 过滤器,但复杂得多且表现低下。 过滤器大小的这种变化是当前趋势的开始:
![Main features](img/00126.jpg)
VGG 中每层的参数编号摘要
然而,使用一系列小的卷积权重的积极变化,总的设置是相当数量的参数(数以百万计的数量级),因此它必须受到许多措施的限制。
## 原始的初始模型
在由 Alexnet 和 VGG 主导的两个主要研究周期之后,Google 凭借非常强大的架构 Inception 打破了挑战,该架构具有多次迭代。
这些迭代的第一个迭代是从其自己的基于卷积神经网络层的架构版本(称为 GoogLeNet)开始的,该架构的名称让人想起了始于网络的方法。
## GoogLenet(Inception V1)
![GoogLenet (Inception V1)](img/00127.jpg)
1 启动模块
GoogLeNet 是这项工作的第一个迭代,如下图所示,它具有非常深的架构,但是它具有九个链式初始模块的令人毛骨悚然的总和,几乎没有或根本没有修改:
![GoogLenet (Inception V1)](img/00128.jpg)
盗梦空间原始架构
与两年前发布的 Alexnet 相比,它是如此复杂,但它设法减少了所需的参数数量并提高了准确率。
但是,由于几乎所有结构都由相同原始结构层构建块的确定排列和重复组成,因此提高了此复杂架构的理解和可伸缩性。
## 批量归一化初始化(V2)
2015 年最先进的神经网络在提高迭代效率的同时,还存在训练不稳定的问题。
为了理解问题的构成,首先我们将记住在前面的示例中应用的简单正则化步骤。 它主要包括将这些值以零为中心,然后除以最大值或标准偏差,以便为反向传播的梯度提供良好的基线。
在训练非常大的数据集的过程中,发生的事情是,经过大量训练示例之后,不同的值振荡开始放大平均参数值,就像在共振现象中一样。 我们非常简单地描述的被称为协方差平移。
![Batch normalized inception (V2)](img/00129.jpg)
有和没有批量归一化的表现比较
这是开发批归一化技术的主要原因。
再次简化了过程描述,它不仅包括对原始输入值进行归一化,还对每一层上的输出值进行了归一化,避免了在层之间出现不稳定性之前就开始影响或漂移这些值。
这是 Google 在 2015 年 2 月发布的改进版 GoogLeNet 实现中提供的主要功能,也称为 Inception V2。
# Inception v3
快进到 2015 年 12 月,Inception 架构有了新的迭代。 两次发行之间月份的不同使我们对新迭代的开发速度有了一个想法。
此架构的基本修改如下:
* 将卷积数减少到最大 3x3
* 增加网络的总体深度
* 在每一层使用宽度增加技术来改善特征组合
下图说明了如何解释改进的启动模块:
![Inception v3](img/00130.jpg)
Inception V3 基本模块
这是整个 V3 架构的表示形式,其中包含通用构建模块的许多实例:
![Inception v3](img/00131.jpg)
Inception V3 总体图
# 残差网络(ResNet)
残差网络架构于 2015 年 12 月出现(与 Inception V3 几乎同时出现),它带来了一个简单而新颖的想法:不仅使用每个构成层的输出,还将该层的输出与原始输入结合。
在下图中,我们观察到 ResNet 模块之一的简化​​视图。 它清楚地显示了卷积层堆栈末尾的求和运算,以及最终的 relu 运算:
![Residual Networks (ResNet)](img/00132.jpg)
ResNet 一般架构
模块的卷积部分包括将特征从 256 个值减少到 64 个值,一个保留特征数的 3x3 过滤层以及一个从 64 x 256 个值增加 1x1 层的特征。 在最近的发展中,ResNet 的使用深度还不到 30 层,分布广泛。
## 其他深度神经网络架构
最近开发了很多神经网络架构。 实际上,这个领域是如此活跃,以至于我们每年或多或少都有新的杰出建筑外观。 最有前途的神经网络架构的列表是:
* SqueezeNet:此架构旨在减少 Alexnet 的参数数量和复杂性,声称减少了 50 倍的参数数量
* 高效神经网络(Enet):旨在构建更简单,低延迟的浮点运算数量,具有实时结果的神经网络
* Fractalnet:它的主要特征是非常深的网络的实现,不需要残留的架构,将结构布局组织为截断的分形
# 示例 -- 使用风格绘画 -- VGG 风格迁移
在此示例中,我们将配合 Leon Gatys 的论文《艺术风格的神经算法》的实现。
......@@ -467,4 +599,13 @@ def preprocess(image, mean_pixel):
def unprocess(image, mean_pixel):
return image + mean_pixel
```
\ No newline at end of file
```
# 总结
在本章中,我们一直在学习不同的深度神经网络架构。
我们了解了如何构建近年来最著名的架构之一 VGG,以及如何使用它来生成可转换艺术风格的图像。
在下一章中,我们将使用机器学习中最有用的技术之一:图形处理单元。 我们将回顾安装具有 GPU 支持的 TensorFlow 所需的步骤并对其进行训练,并将执行时间与唯一运行的模型 CPU 进行比较。
此差异已折叠。
+ [使用 TensorFlow 构建机器学习项目中文版](docs/build-ml-proj-tf-zh/README.md)
+ [第 1 章 探索和转换数据](docs/build-ml-proj-tf-zh/0.md)
+ [TensorFlow 的主要数据结构 -- 张量](docs/build-ml-proj-tf-zh/1.md)
+ [处理计算工作流程 -- TensorFlow 的数据流程图](docs/build-ml-proj-tf-zh/2.md)
+ [运行我们的程序 -- 会话](docs/build-ml-proj-tf-zh/3.md)
+ [基本张量方法](docs/build-ml-proj-tf-zh/4.md)
+ [总结](docs/build-ml-proj-tf-zh/5.md)
+ [第 2 章 聚类](docs/build-ml-proj-tf-zh/6.md)
+ [从数据中学习 -- 无监督学习](docs/build-ml-proj-tf-zh/7.md)
+ [聚类](docs/build-ml-proj-tf-zh/8.md)
+ [k 均值](docs/build-ml-proj-tf-zh/9.md)
+ [k 最近邻](docs/build-ml-proj-tf-zh/10.md)
+ [项目 1 -- 在合成数据集上进行 k 均值聚类](docs/build-ml-proj-tf-zh/11.md)
+ [项目 2 -- 综合数据集上的最近邻](docs/build-ml-proj-tf-zh/12.md)
+ [总结](docs/build-ml-proj-tf-zh/13.md)
+ [第 3 章 线性回归](docs/build-ml-proj-tf-zh/14.md)
+ [单变量线性建模函数](docs/build-ml-proj-tf-zh/15.md)
+ [成本函数的确定](docs/build-ml-proj-tf-zh/16.md)
+ [最小化成本函数](docs/build-ml-proj-tf-zh/17.md)
+ [示例部分](docs/build-ml-proj-tf-zh/18.md)
+ [示例 1 -- 单变量线性回归](docs/build-ml-proj-tf-zh/19.md)
+ [示例 2 -- 多元线性回归](docs/build-ml-proj-tf-zh/20.md)
+ [总结](docs/build-ml-proj-tf-zh/21.md)
+ [第 4 章 逻辑回归](docs/build-ml-proj-tf-zh/22.md)
+ [问题描述](docs/build-ml-proj-tf-zh/23.md)
+ [sigmoid 函数的前身 -- Logit 函数](docs/build-ml-proj-tf-zh/24.md)
+ [sigmoid 函数](docs/build-ml-proj-tf-zh/25.md)
+ [示例 1 -- 单变量 logistic 回归](docs/build-ml-proj-tf-zh/26.md)
+ [示例 2 -- 使用 skflow 的单变量 logistic 回归](docs/build-ml-proj-tf-zh/27.md)
+ [总结](docs/build-ml-proj-tf-zh/28.md)
+ [第 5 章 简单的前馈神经网络](docs/build-ml-proj-tf-zh/29.md)
+ [初步概念](docs/build-ml-proj-tf-zh/30.md)
+ [第一个项目 -- 非线性合成函数回归](docs/build-ml-proj-tf-zh/31.md)
+ [第二个项目 -- 使用非线性回归建模汽车的燃油效率](docs/build-ml-proj-tf-zh/32.md)
+ [第三个项目 -- 学习葡萄酒分类:多类分类](docs/build-ml-proj-tf-zh/33.md)
+ [总结](docs/build-ml-proj-tf-zh/34.md)
+ [第 6 章 卷积神经网络](docs/build-ml-proj-tf-zh/35.md)
+ [卷积神经网络的起源](docs/build-ml-proj-tf-zh/36.md)
+ [示例 1 -- MNIST 数字分类](docs/build-ml-proj-tf-zh/37.md)
+ [示例 2 -- 使用 CIFAR10 数据集进行图像分类](docs/build-ml-proj-tf-zh/38.md)
+ [总结](docs/build-ml-proj-tf-zh/39.md)
+ [第 7 章 循环神经网络和 LSTM](docs/build-ml-proj-tf-zh/40.md)
+ [循环神经网络](docs/build-ml-proj-tf-zh/41.md)
+ [示例 1 -- 能耗数据的单变量时间序列预测](docs/build-ml-proj-tf-zh/42.md)
+ [示例 2 -- 编写音乐 “a la” Bach](docs/build-ml-proj-tf-zh/43.md)
+ [总结](docs/build-ml-proj-tf-zh/44.md)
+ [第 8 章 深度神经网络](docs/build-ml-proj-tf-zh/45.md)
+ [深度神经网络定义](docs/build-ml-proj-tf-zh/46.md)
+ [穿越时空的深度网络架构](docs/build-ml-proj-tf-zh/47.md)
+ [Alexnet](docs/build-ml-proj-tf-zh/48.md)
+ [Inception v3](docs/build-ml-proj-tf-zh/49.md)
+ [残差网络(ResNet)](docs/build-ml-proj-tf-zh/50.md)
+ [示例 -- 使用风格绘画 -- VGG 风格迁移](docs/build-ml-proj-tf-zh/51.md)
+ [总结](docs/build-ml-proj-tf-zh/52.md)
+ [第 9 章 大规模运行模型 -- GPU 和服务](docs/build-ml-proj-tf-zh/53.md)
+ [TensorFlow 上的 GPU 支持](docs/build-ml-proj-tf-zh/54.md)
+ [示例 1 -- 将操作分配给 GPU](docs/build-ml-proj-tf-zh/55.md)
+ [示例 2 -- 并行计算 Pi](docs/build-ml-proj-tf-zh/56.md)
+ [分布式 TensorFlow](docs/build-ml-proj-tf-zh/57.md)
+ [示例 3 -- 分布式 Pi 计算](docs/build-ml-proj-tf-zh/58.md)
+ [示例 4 -- 在集群中运行分布式模型](docs/build-ml-proj-tf-zh/59.md)
+ [总结](docs/build-ml-proj-tf-zh/60.md)
+ [第 10 章 库安装和其他提示](docs/build-ml-proj-tf-zh/61.md)
+ [Linux 安装](docs/build-ml-proj-tf-zh/62.md)
+ [Windows 安装](docs/build-ml-proj-tf-zh/63.md)
+ [MacOS X 安装](docs/build-ml-proj-tf-zh/64.md)
+ [总结](docs/build-ml-proj-tf-zh/65.md)
+ [一、探索和转换数据](docs/build-ml-proj-tf-zh/ch01.md)
+ [二、聚类](docs/build-ml-proj-tf-zh/ch02.md)
+ [三、线性回归](docs/build-ml-proj-tf-zh/ch03.md)
+ [四、逻辑回归](docs/build-ml-proj-tf-zh/ch04.md)
+ [五、简单的前馈神经网络](docs/build-ml-proj-tf-zh/ch05.md)
+ [六、卷积神经网络](docs/build-ml-proj-tf-zh/ch06.md)
+ [七、循环神经网络和 LSTM](docs/build-ml-proj-tf-zh/ch07.md)
+ [八、深度神经网络](docs/build-ml-proj-tf-zh/ch08.md)
+ [九、大规模运行模型 -- GPU 和服务](docs/build-ml-proj-tf-zh/ch09.md)
+ [十、库安装和其他提示](docs/build-ml-proj-tf-zh/ch10.md)
+ [TensorFlow 深度学习中文第二版](docs/dl-tf-2e-zh/README.md)
+ [一、人工神经网络](docs/dl-tf-2e-zh/ch01.md)
+ [二、TensorFlow v1.6 的新功能是什么?](docs/dl-tf-2e-zh/ch02.md)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册