# 3. TensorFlow 中的聚类
前一章中介绍的线性回归是一种监督学习算法,我们使用数据和输出值(或标签)来构建适合它们的模型。但我们并不总是拥有标记数据,尽管如此,我们也希望以某种方式分析它们。在这种情况下,我们可以使用无监督学习算法,例如聚类。聚类方法被广泛使用,因为它通常是数据分析的初步筛选的好方法。
在本章中,我将介绍名为 K-means 的聚类算法。它肯定是最受欢迎的,广泛用于自动将数据分组到相关的子集中,以便子集中的所有元素彼此更相似。在此算法中,我们没有任何目标或结果变量来预测估计值。
我还将使用本章来介绍 TensorFlow 的知识,并在更详细地介绍名为`tensor`(张量)的基本数据结构。我将首先解释这种类型的数据是什么样的,并展示可以在其上执行的转换。然后,我将使用张量在案例研究中展示 K-means 算法的使用。
### 基本数据结构:张量
TensorFlow 程序使用称为张量的基本数据结构来表示其所有数据。张量可以被认为是动态大小的多维数据数组,其具有静态数据类型的属性,可以从布尔值或字符串到各种数字类型。下面是 Python 中的主要类型及其等价物的表格。
| TensorFlow 中的类型 | Python 中的类型 | 描述 |
| --- | --- | --- |
| `DT_FLOAT` | `tf.float32` | 32 位浮点 |
| `DT_INT16` | `tf.int16` | 16 位整数 |
| `DT_INT32` | `tf.int32` | 32 位整数 |
| `DT_INT64` | `tf.int64` | 64 位整数 |
| `DT_STRING` | `tf.string` | 字符串 |
| `DT_BOOL` | `tf.bool` | 布尔值 |
另外,每个张量拥有阶(Rank),这是其维度的数量。例如,以下张量(在 Python 中定义为列表)的阶为 2:
```
t = [[1,2,3],[4,5,6],[7,8,9]]
```
张量可以有任何阶。二阶张量通常被认为是矩阵,一阶张量将是向量。零阶被认为是标量值。
TensorFlow 文档使用三种类型的命名约定来描述张量的维度:形状(Shape),阶(Rank)和维数(Dimension Number)。下表显示了它们之间的关系,以便使跟踪 TensorFlow 文档更容易:
| 形状 | 阶 | 维数 |
| --- | --- | --- |
| `[]` | 0 | 0-D |
| `[D0]` | 1 | 1-D |
| `[D0, D1]` | 2 | 2-D |
| `[D0, D1, D2]` | 3 | 3-D |
| … | … | … |
| `[D0, D1, ... Dn]` | n | n-D |
这些张量可以通过一系列 TensorFlow 软件包提供的转换进行操作。 下面,我们将在下表中讨论其中的一些内容。
在本章中,我们将详细介绍其中一些内容。 可以在 TensorFlow 的官方网站 [18] 上找到完整的转换列表和详细信息。
| 操作 | 描述 |
| tf.shape | 获取张量的形状 |
| tf.size | 获取张量的大小 |
| tf.rank | 获取张量的阶 |
| tf.reshape | 改变张量的形状,保持包含相同的元素 |
| tf.squeeze | 删除大小为 1 的张量维度 |
| tf.expand_dims | 将维度插入张量 |
| tf.slice | 删除部分张量 |
| tf.split | 将张量沿一个维度划分为多个张量 |
| tf.tile | 将一个张量多次复制,并创建新的张量 |
| tf.concat | 在一个维度上连接张量 |
| tf.reverse | 反转张量的特定维度 |
| tf.transpose | 转置张量中的维度 |
| tf.gather | 根据索引收集部分 |
例如,假设你要将`2×2000`(2D 张量)的数组扩展为立方体(3D 张量)。 我们可以使用`tf.expand_ dims`函数,它允许我们向张量插入一个维度:
```py
vectors = tf.constant(conjunto_puntos)
extended_vectors = tf.expand_dims(vectors, 0)
```
在这种情况下,`tf.expand_dims`将一个维度插入到由参数给定的一个张量中(维度从零开始)。
从视觉上看,上述转变如下:
![](https://jorditorres.org/wp-content/uploads/2016/02/image023.gif)
如你所见,我们现在有了 3D 张量,但我们无法根据函数参数确定新维度 D0 的大小。
如果我们使用`get_shape()`操作获得此`tensor`的形状,我们可以看到没有关联的大小:
```py
print expanded_vectors.get_shape()
```
它可能会显示:
```py
TensorShape([Dimension(1), Dimension(2000), Dimension(2)])
```
在本章的后面,我们将看到,由于 TensorFlow 形状广播, 张量的许多数学处理函数(如第一章所示),能够发现大小未指定的维度的大小,,并为其分配这个推导出的值。
### TensorFlow 中的数据存储
在介绍 TensorFlow 的软件包之后,从广义上讲,有三种主要方法可以在 TensorFlow 程序上获取数据:
1. 来自数据文件。
2. 数据作为常量或变量预加载。
3. 那些由 Python 代码提供的。
下面,我简要介绍其中的每一个。
1) **数据文件**
通常,从数据文件加载初始数据。这个过程并不复杂,鉴于本书的介绍性质,我邀请读者访问TensorFlow 的网站 [19],了解如何从不同文件类型加载数据。你还可以查看 Python 代码[`input_data.py`](https://github.com/jorditorresBCN/TutorialTensorFlow/blob/master/input_data.py) [20](可在 Github 上找到),它从文件中加载 MNIST 数据(我将在下面几章使用它)。
2) **变量和常量**
当谈到小集合时,也可以预先将数据加载到内存中;创建它们有两种基本方法,正如我们在前面的例子中看到的那样:
* `constant(…)`用于常量
* `Variable(…)`用于变量
TensorFlow 包提供可用于生成常量的不同操作。在下表中,你可以找到最重要的操作的摘要:
| 操作 | 描述 |
| --- | --- |
| `tf.zeros_like` | 创建一个张量,所有元素都初始化为 0 |
| `tf.ones_like` | 创建一个张量,所有元素都初始化为 1 |
| `tf.fill` | 创建一个张量,其中所有元素都初始化为由参数给出的标量值 |
| `tf.constant` | 使用参数列出的元素创建常量张量 |
在 TensorFlow 中,在模型的训练过程中,参数作为变量保存在存储器中。 创建变量时,可以使用由函数参数定义的张量作为初始值,该值可以是常量值或随机值。 TensorFlow 提供了一系列操作,可生成具有不同分布的随机张量:
| 操作 | 描述 |
| --- | --- |
| `tf.random_normal` | 具有正态分布的随机值 |
| `tf.truncated_normal` | 具有正态分布的随机值,但消除那些幅度大于标准差 2 倍的值 |
| `tf.random_uniform` | 具有均匀分布的随机值 |
| `tf.random_shuffle` | 在第一维中随机打乱张量元素 |
| `tf.set_random_seed` | 设置随机种子 |
一个重要的细节是,所有这些操作都需要特定形状的张量作为函数的参数,并且创建的变量具有相同的形状。 通常,变量具有固定的形状,但TensorFlow提供了在必要时对其进行重塑的机制。
使用变量时,必须在构造图之后,在使用`run()`函数执行任何操作之前显式初始化这些变量。 正如我们所看到的,为此可以使用`tf.initialize_all_variables()`。 通过 TensorFlow 的`tf.train.Saver()`类,可以在训练模型时和之后将变量保存到磁盘上,但是这个类超出了本书的范围。
3) **由Python代码提供**
最后,我们可以使用我们所谓的“符号变量”或占位符来在程序执行期间操作数据。调用是`placeholder()`,参数为元素类型和张量形状,以及可选的名称。
从 Python 代码调用`Session.run()`或`Tensor.eval()`的同时,张量由`feed_dict`参数中指定的数据填充。回想第 1 章中的第一个代码:
```py
import tensorflow as tf
a = tf.placeholder("float")
b = tf.placeholder("float")
y = tf.mul(a, b)
sess = tf.Session()
print sess.run(y, feed_dict={a: 3, b: 3})
```
在最后一行代码中,调用`sess.run()`时,我们传递两个张量`a`和`b`的值到`feed_dict`参数。
通过张量的简要介绍,我希望从现在起读者可以毫不费力地读懂下面几章的代码。
### K-Means 算法
K-Means 是一种无监督算法,可以解决聚类问题。 它的过程遵循一种简单易行的方法,通过一定数量的簇(假设`k`簇)对给定数据集进行聚类。 簇内的数据点是同构的,不同簇的点是异构的,这意味着子集中的所有元素与其余元素相比更为相似。
算法的结果是一组`K`个点,称为质心,它们是所得的不同组的焦点,以及点集的标签,这些点分配给其中一个簇。 簇内的所有点与质心的距离都比任何其他质心更近。
如果我们想要直接最小化误差函数(所谓的 NP-hard 问题),那么簇的生成是一个计算上很昂贵的问题。因此,已经创建了一些算法,通过启发式在局部最优中快速收敛。 最常用的算法使用迭代优化技术,它在几次迭代中收敛。
一般来讲,这种技术有三个步骤:
+ 初始步骤(步骤 0):确定`K`个质心的初始集合。
+ 分配步骤(步骤 1):将每个观测值分配到最近的组。
+ 更新步骤(步骤 2):计算每个新组的新质心。
有几种方法可以确定初始`K`质心。 其中一个是在数据集中随机选择`K`个观测值并将它们视为质心;这是我们将在我们的示例中使用的那个。
分配(步骤 1)和更新(步骤 2)的步骤在循环中交替,直到认为算法已经收敛为止,这可以是,例如,当点到组的分配不再改变的时候。
由于这是一种启发式算法,因此无法保证它收敛于全局最优,结果取决于初始组。 因此,由于算法通常非常快,通常使用不同的初始质心值重复执行多次,然后权衡结果。
要在 TensorFlow 中开始编写 K-means 的示例,我建议首先生成一些数据作为测试平台。 我建议做一些简单的事情,比如在 2D 空间中随机生成 2,000 个点,遵循二维正态分布来绘制一个空间,使我们能够更好地理解结果。 例如,我建议使用以下代码:
```py
num_puntos = 2000
conjunto_puntos = []
for i in xrange(num_puntos):
if np.random.random() > 0.5:
conjunto_puntos.append([np.random.normal(0.0, 0.9), np.random.normal(0.0, 0.9)])
else:
conjunto_puntos.append([np.random.normal(3.0, 0.5), np.random.normal(1.0, 0.5)])
```
正如我们在前一章中所做的那样,我们可以使用一些 Python 图形库来绘制数据。 我建议像以前一样使用 matplotlib,但这次我们还将使用基于 matplotlib 的可视化包 Seaborn 和数据操作包 pandas,它允许我们使用更复杂的数据结构。
如果未安装这些软件包,则必须先使用`pip`执行此操作,然后才能运行以下代码。
要显示随机生成的点,我建议使用以下代码:
```py
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
df = pd.DataFrame({"x": [v[0] for v in conjunto_puntos],
"y": [v[1] for v in conjunto_puntos]})
sns.lmplot("x", "y", data=df, fit_reg=False, size=6)
plt.show()
```
此代码生成二维空间中的点图,如下面的截图所示:
![](https://jorditorres.org/wp-content/uploads/2016/02/image024.png)
在 TensorFlow 中实现的 k-means 算法将上述点分组,例如在四个簇中,可能像这样(基于 Shawn Simister 在他的博客中展示的模型 [21]):
```py
import numpy as np
vectors = tf.constant(conjunto_puntos)
k = 4
centroides = tf.Variable(tf.slice(tf.random_shuffle(vectors),[0,0],[k,-1]))
expanded_vectors = tf.expand_dims(vectors, 0)
expanded_centroides = tf.expand_dims(centroides, 1)
assignments = tf.argmin(tf.reduce_sum(tf.square(tf.sub(expanded_vectors, expanded_centroides)), 2), 0)
means = tf.concat(0, [tf.reduce_mean(tf.gather(vectors, tf.reshape(tf.where( tf.equal(assignments, c)),[1,-1])), reduction_indices=[1]) for c in xrange(k)])
update_centroides = tf.assign(centroides, means)
init_op = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init_op)
for step in xrange(100):
_, centroid_values, assignment_values = sess.run([update_centroides, centroides, assignments])
```
我建议读者使用以下代码检查`assignment_values`张量中的结果,该代码生成像上面那样的图:
```py
data = {"x": [], "y": [], "cluster": []}
for i in xrange(len(assignment_values)):
data["x"].append(conjunto_puntos[i][0])
data["y"].append(conjunto_puntos[i][1])
data["cluster"].append(assignment_values[i])
df = pd.DataFrame(data)
sns.lmplot("x", "y", data=df, fit_reg=False, size=6, hue="cluster", legend=False)
plt.show()
```
截图以及我的代码执行结果如下图所示:
![](https://jorditorres.org/wp-content/uploads/2016/02/image026.png)
### 新的组
我假设读者可能会对上一节中介绍的 K-means 代码感到有些不知所措。 好吧,我建议我们一步一步详细分析它,特别是观察涉及的张量以及它们在程序中如何转换。
首先要做的是将所有数据移到张量。 在常数张量中,我们使初始点保持随机生成:
```py
vectors = tf.constant(conjunto_vectors)
```
按照上一节中介绍的算法,为了开始我们必须确定初始质心。 随着我前进,一个选项可能是,从输入数据中随机选择`K`个观测值。 一种方法是使用以下代码,它向 TensorFlow 表明,它必须随机地打乱初始点并选择前`K`个点作为质心:
```py
k = 4
centroides = tf.Variable(tf.slice(tf.random_shuffle(vectors),[0,0],[k,-1]))
```
这`K`个点存储在 2D 张量中。 要知道这些张量的形状,我们可以使用`tf.Tensor.get_shape()`:
```py
print vectors.get_shape()
print centroides.get_shape()
TensorShape([Dimension(2000), Dimension(2)])
TensorShape([Dimension(4), Dimension(2)])
```
我们可以看到`vectors`是一个数组,D0 维包含 2000 个位置,每个位置一个向量,D1 的位置是每个点`x, y`。 相反,`centroids`是一个矩阵,维度 D0 有四个位置,每个质心一个位置,D1 和`vectors`相同。
接下来,算法进入循环。 第一步是为每个点计算其最接近的质心,根据平方欧几里德距离 [22](只能在我们想要比较距离时使用):
![](https://jorditorres.org/wp-content/uploads/2016/02/image028.jpg)
为了计算该值,使用`tf.sub(vectors, centroides`。 我们应该注意到,虽然减法的两个张量都有 2 个维度,但它们在一个维度上大小不同(维度 D0 为 2000 和 4),实际上它们也代表不同的东西。
为了解决这个问题,我们可以使用之前讨论过的一些函数,例如`tf.expand_dims`,以便在两个张量中插入一个维度。 目的是将两个张量从 2 维扩展到 3 维来使尺寸匹配,以便执行减法:
```py
expanded_vectors = tf.expand_dims(vectors, 0)
expanded_centroides = tf.expand_dims(centroides, 1)
```
`tf.expand_dims`在每个张量中插入一个维度;在`vectors`张量的第一维(D0),以及`centroides`张量的第二维(D1)。 从图形上看,我们可以看到,在扩展后的张量中,每个维度具有相同的含义:
![](https://jorditorres.org/wp-content/uploads/2016/02/image031.gif)
它似乎得到了解决,但实际上,如果你仔细观察(在插图中概述),在每种情况下都有大小无法确定的些维度。 请记住,使用`get_shape()`函数我们可以发现:
```py
print expanded_vectors.get_shape()
print expanded_centroides.get_shape()
```
输出如下:
```py
TensorShape([Dimension(1), Dimension(2000), Dimension(2)])
TensorShape([Dimension(4), Dimension(1), Dimension(2)])
```
使用 1 表示没有指定大小。
但我已经展示 TensorFlow 允许广播,因此`tf.sub`函数能够自己发现如何在两个张量之间将元素相减。
直观地,并且观察先前的附图,我们看到两个张量的形状匹配,并且在这些情况下,两个张量在一定维度上具有相同的尺寸。 这些数学,如 D2 维度所示。 相反,在维度 D0 中只有`expanded_centroides`的定义大小。
在这种情况下,如果我们想要在此维度内对元素执行减法,则 TensorFlow 假定`expanded_vectors`张量的维度 D0 必须是相同的大小。
对于`expended_centroides`张量的维度 D1 的大小也是如此,其中 TensorFlow 推导出`expanded_vectors`张量的尺寸 D1 的大小。
因此,在分配步骤(步骤 1)中,算法可以用 TensorFlow 代码的这四行表示,它计算平方欧几里德距离:
```py
diff=tf.sub(expanded_vectors, expanded_centroides)
sqr= tf.square(diff)
distances = tf.reduce_sum(sqr, 2)
assignments = tf.argmin(distances, 0)
```
而且,如果我们看一下张量的形状,我们会看到它们分别对应`diff`,`sqr`,`distance`和`assign`,如下所示:
```py
TensorShape([Dimension(4), Dimension(2000), Dimension(2)])
TensorShape([Dimension(4), Dimension(2000), Dimension(2)])
TensorShape([Dimension(4), Dimension(2000)])
TensorShape([Dimension(2000)])
```
也就是说,`tf.sub`函数返回了张量`dist`,其中包含质心和向量的坐标的差(维度 D1 表示数据点,D0 表示质心,每个坐标`x, y`在维度 D2 中表示)。
`sqr`张量包含它们的平方。 在`dist`张量中,我们可以看到它已经减少了一个维度,它在`tf.reduce_sum`函数中表示为一个参数。
我用这个例子来解释 TensorFlow 提供的几个操作,它们可以用来执行减少张量维数的数学运算,如`tf.reduce_sum`。在下表中,你可以找到最重要的操作摘要。
| 操作 | 描述 |
| --- | --- |
| tf.reduce_sum | 沿一个维度计算元素总和 |
| tf.reduce_prod | 沿一个维度计算元素的乘积 |
| tf.reduce_min | 沿一个维度计算元素最小值 |
| tf.reduce_max | 沿一个维度计算元素最大值 |
| tf.reduce_mean | 沿一个维度计算元素平均值 |
最后,使用`tf.argmin`实现分配,它返回张量的某个维度的最小值的索引(在我们的例子中是 D0,记得它是质心)。 我们还有`tf.argmax`操作:
| 手术 | 描述 |
| --- | --- |
| tf.argmin | 沿某个维度返回最小值的索引 |
| tf.argmax | 沿某个维度返回最大值的索引 |
事实上,上面提到的 4 条语句可以在一行代码中汇总,正如我们在上一节中看到的那样:
```py
assignments = tf.argmin(tf.reduce_sum(tf.square(tf.sub(expanded_vectors, expanded_centroides)), 2), 0)
```
但无论如何,内部的`tensors`,以及它们定义为节点和执行的内部图的操作,就像我们之前描述的那样。
### 计算新的质心
在那段代码中,我们可以看到`means`张量是`k`张量的连接结果,它们对应属于每个簇的每个点的平均值。
接下来,我将评论每个 TensorFlow 操作,这些操作涉及计算属于每个簇的每个点的平均值 [23]。
* 使用`equal`,我们可以得到布尔张量(`Dimension(2000)`),它(使用`true`)表示`assignments`张量`K`个簇匹配的位置,当时我们正在计算点的平均值。
* 使用`where`构造一个张量(`Dimension(1) x Dimension(2000)`),带有布尔张量中值为`true`的位置,布尔张量作为参数接收的_布尔张量_。
* 用`reshape`构造张量(`Dimension(2000) x Dimension(1)`),其中`vectors`张量内的点的索引属于簇`c`。
* 用`gather`构造张量(`Dimension(1) x Dimension(2000)`),它收集形成簇`c`的点的坐标。
* 使用`reduce_mean`,构造张量_(`Dimension(1) x Dimension(2)`)_,其中包含属于簇`c`的所有点的平均值。
无论如何,如果读者想要深入研究代码,正如我常说的那样,你可以在 TensorFlow API 页面上找到有关这些操作的更多信息,以及非常具有说明性的示例 [24]。
### 图表执行
最后,我们必须描述上述代码中,与循环相对应的部分,以及使用`means`张量的新值更新质心的部分。
为此,我们需要创建一个操作,它将`means`张量的值分配到质心中,而不是在执行操作`run()`时,更新的质心的值在循环的下一次迭代中使用:
```py
update_centroides = tf.assign(centroides, means)
```
在开始运行图之前,我们还必须创建一个操作来初始化所有变量:
```py
init_op = tf.initialize_all_variables()
```
此时一切准备就绪。 我们可以开始运行图了:
```py
sess = tf.Session()
sess.run(init_op)
for step in xrange(num_steps):
_, centroid_values, assignment_values = sess.run([update_centroides, centroides, assignments])
```
在此代码中,每次迭代中,更新每个初始点的质心和新的簇分配。
请注意,代码指定了三个操作,它必须查看`run()`调用的执行,并按此顺序运行。 由于要搜索三个值,`sess.run()`会在训练过程中返回元素为三个 numpy 数组的数据结构,内容为相应张量。
由于`update_centroides`是一个结果是不返回的参数的操作,因此返回元组中的相应项不包含任何内容,因此被排除,用`_`来表示 [25] 。
对于其他两个值,质心和每个簇的分配点,我们有兴趣在完成所有`num_steps`次迭代后在屏幕上显示它们。
我们可以使用简单的打印。 输出如下:
```py
print centroid_values
[[ 2.99835277e+00 9.89548564e-01]
[ -8.30736756e-01 4.07433510e-01]
[ 7.49640584e-01 4.99431938e-01]
[ 1.83571398e-03 -9.78474259e-01]]
```
我希望读者的屏幕上有类似的值,因为这表明他已成功执行了本书这一章中展示的代码。
我建议读者在继续之前尝试更改代码中的任何值。 例如`num_points`,特别是`k`的数量,并使用生成图的先前代码查看它如何更改`assignment_values`张量中的结果。
请记住,为了便于测试本章所述的代码,可以从 Github [26] 下载。 包含此代码的文件名是`Kmeans.py`。
在本章中,我们展示了 TensorFlow 的一些知识,特别是基本数据结构张量,它来自实现 KMeans 聚类算法的 TensorFlow 代码示例。
有了这些知识,我们就可以在下一章中逐步使用 TensorFlow 构建单层神经网络。
- TensorFlow 1.x 深度学习秘籍
- 零、前言
- 一、TensorFlow 简介
- 二、回归
- 三、神经网络:感知器
- 四、卷积神经网络
- 五、高级卷积神经网络
- 六、循环神经网络
- 七、无监督学习
- 八、自编码器
- 九、强化学习
- 十、移动计算
- 十一、生成模型和 CapsNet
- 十二、分布式 TensorFlow 和云深度学习
- 十三、AutoML 和学习如何学习(元学习)
- 十四、TensorFlow 处理单元
- 使用 TensorFlow 构建机器学习项目中文版
- 一、探索和转换数据
- 二、聚类
- 三、线性回归
- 四、逻辑回归
- 五、简单的前馈神经网络
- 六、卷积神经网络
- 七、循环神经网络和 LSTM
- 八、深度神经网络
- 九、大规模运行模型 -- GPU 和服务
- 十、库安装和其他提示
- TensorFlow 深度学习中文第二版
- 一、人工神经网络
- 二、TensorFlow v1.6 的新功能是什么?
- 三、实现前馈神经网络
- 四、CNN 实战
- 五、使用 TensorFlow 实现自编码器
- 六、RNN 和梯度消失或爆炸问题
- 七、TensorFlow GPU 配置
- 八、TFLearn
- 九、使用协同过滤的电影推荐
- 十、OpenAI Gym
- TensorFlow 深度学习实战指南中文版
- 一、入门
- 二、深度神经网络
- 三、卷积神经网络
- 四、循环神经网络介绍
- 五、总结
- 精通 TensorFlow 1.x
- 一、TensorFlow 101
- 二、TensorFlow 的高级库
- 三、Keras 101
- 四、TensorFlow 中的经典机器学习
- 五、TensorFlow 和 Keras 中的神经网络和 MLP
- 六、TensorFlow 和 Keras 中的 RNN
- 七、TensorFlow 和 Keras 中的用于时间序列数据的 RNN
- 八、TensorFlow 和 Keras 中的用于文本数据的 RNN
- 九、TensorFlow 和 Keras 中的 CNN
- 十、TensorFlow 和 Keras 中的自编码器
- 十一、TF 服务:生产中的 TensorFlow 模型
- 十二、迁移学习和预训练模型
- 十三、深度强化学习
- 十四、生成对抗网络
- 十五、TensorFlow 集群的分布式模型
- 十六、移动和嵌入式平台上的 TensorFlow 模型
- 十七、R 中的 TensorFlow 和 Keras
- 十八、调试 TensorFlow 模型
- 十九、张量处理单元
- TensorFlow 机器学习秘籍中文第二版
- 一、TensorFlow 入门
- 二、TensorFlow 的方式
- 三、线性回归
- 四、支持向量机
- 五、最近邻方法
- 六、神经网络
- 七、自然语言处理
- 八、卷积神经网络
- 九、循环神经网络
- 十、将 TensorFlow 投入生产
- 十一、更多 TensorFlow
- 与 TensorFlow 的初次接触
- 前言
- 1. TensorFlow 基础知识
- 2. TensorFlow 中的线性回归
- 3. TensorFlow 中的聚类
- 4. TensorFlow 中的单层神经网络
- 5. TensorFlow 中的多层神经网络
- 6. 并行
- 后记
- TensorFlow 学习指南
- 一、基础
- 二、线性模型
- 三、学习
- 四、分布式
- TensorFlow Rager 教程
- 一、如何使用 TensorFlow Eager 构建简单的神经网络
- 二、在 Eager 模式中使用指标
- 三、如何保存和恢复训练模型
- 四、文本序列到 TFRecords
- 五、如何将原始图片数据转换为 TFRecords
- 六、如何使用 TensorFlow Eager 从 TFRecords 批量读取数据
- 七、使用 TensorFlow Eager 构建用于情感识别的卷积神经网络(CNN)
- 八、用于 TensorFlow Eager 序列分类的动态循坏神经网络
- 九、用于 TensorFlow Eager 时间序列回归的递归神经网络
- TensorFlow 高效编程
- 图嵌入综述:问题,技术与应用
- 一、引言
- 三、图嵌入的问题设定
- 四、图嵌入技术
- 基于边重构的优化问题
- 应用
- 基于深度学习的推荐系统:综述和新视角
- 引言
- 基于深度学习的推荐:最先进的技术
- 基于卷积神经网络的推荐
- 关于卷积神经网络我们理解了什么
- 第1章概论
- 第2章多层网络
- 2.1.4生成对抗网络
- 2.2.1最近ConvNets演变中的关键架构
- 2.2.2走向ConvNet不变性
- 2.3时空卷积网络
- 第3章了解ConvNets构建块
- 3.2整改
- 3.3规范化
- 3.4汇集
- 第四章现状
- 4.2打开问题
- 参考
- 机器学习超级复习笔记
- Python 迁移学习实用指南
- 零、前言
- 一、机器学习基础
- 二、深度学习基础
- 三、了解深度学习架构
- 四、迁移学习基础
- 五、释放迁移学习的力量
- 六、图像识别与分类
- 七、文本文件分类
- 八、音频事件识别与分类
- 九、DeepDream
- 十、自动图像字幕生成器
- 十一、图像着色
- 面向计算机视觉的深度学习
- 零、前言
- 一、入门
- 二、图像分类
- 三、图像检索
- 四、对象检测
- 五、语义分割
- 六、相似性学习
- 七、图像字幕
- 八、生成模型
- 九、视频分类
- 十、部署
- 深度学习快速参考
- 零、前言
- 一、深度学习的基础
- 二、使用深度学习解决回归问题
- 三、使用 TensorBoard 监控网络训练
- 四、使用深度学习解决二分类问题
- 五、使用 Keras 解决多分类问题
- 六、超参数优化
- 七、从头开始训练 CNN
- 八、将预训练的 CNN 用于迁移学习
- 九、从头开始训练 RNN
- 十、使用词嵌入从头开始训练 LSTM
- 十一、训练 Seq2Seq 模型
- 十二、深度强化学习
- 十三、生成对抗网络
- TensorFlow 2.0 快速入门指南
- 零、前言
- 第 1 部分:TensorFlow 2.00 Alpha 简介
- 一、TensorFlow 2 简介
- 二、Keras:TensorFlow 2 的高级 API
- 三、TensorFlow 2 和 ANN 技术
- 第 2 部分:TensorFlow 2.00 Alpha 中的监督和无监督学习
- 四、TensorFlow 2 和监督机器学习
- 五、TensorFlow 2 和无监督学习
- 第 3 部分:TensorFlow 2.00 Alpha 的神经网络应用
- 六、使用 TensorFlow 2 识别图像
- 七、TensorFlow 2 和神经风格迁移
- 八、TensorFlow 2 和循环神经网络
- 九、TensorFlow 估计器和 TensorFlow HUB
- 十、从 tf1.12 转换为 tf2
- TensorFlow 入门
- 零、前言
- 一、TensorFlow 基本概念
- 二、TensorFlow 数学运算
- 三、机器学习入门
- 四、神经网络简介
- 五、深度学习
- 六、TensorFlow GPU 编程和服务
- TensorFlow 卷积神经网络实用指南
- 零、前言
- 一、TensorFlow 的设置和介绍
- 二、深度学习和卷积神经网络
- 三、TensorFlow 中的图像分类
- 四、目标检测与分割
- 五、VGG,Inception,ResNet 和 MobileNets
- 六、自编码器,变分自编码器和生成对抗网络
- 七、迁移学习
- 八、机器学习最佳实践和故障排除
- 九、大规模训练
- 十、参考文献