数据科学引论-Python之道 第10课TensorFlow-深度学习实践 本节课将介绍如何利用TensorFlow框架建立一个简单的线性模型的基本工 作流程。在此特别感谢Hvass-Labs提供的教程,感兴趣的同学可以在github上 找到他们的教程。 首先介绍我们需要引入的模块。第一个matplotlib模块主要是用来辅助我们 画图,然后引入基本的TensorFlow模块,以及用于矩阵计算和其他一些数组计 算的numpy模块。本次教程使用的Python版本是3.6,TensorFlow的版本是 1.4.0。 In (1]:imatplotlib inlime import matplotlib.Pyplot as plt import tensorflov as tf import numpy as np /Users/chenhaopeng/anaconda/lib/python3.6/importlib/_bootstrap.py:205:Runtimewarning:compiletime version 3.5 of nod ule 'tensorflow.python.framework.fast_tensor_util'does not natch runtine version 3.6 r8tuEn【(*axg8,**灯ud8) 本教程使用3.6版本的Pythoni进行开发,Ten8 orFlowl库的版本是 In 12]:tf.veraion_ 0ut21:1.4.0' 在引入基本模块之后,我们需要将手写数字的图片,也就是我们此次简单线 性模型需要识别的图片加载进来。我们此次所用到的数据集是MNIST数据集, 它里面包含了7万张手写数字的图片,还包含它们对应的标签,它们的标签表示 的就是这些图片所对应的数字。TensorFlow直接提供了库函数,我们可以直接使 用它的库函数进行下载,例如第一个代码框里的两行代码,执行完这两行代码之 后会得到相应的输出信息,表明MNIST数据集已经加载完毕。整个MNST数据 集被分为三个不同的子数据集,包含训练数据集、测试数据集和验证数据集。本 次教程只使用训练数据集和测试数据集。通过pint函数打印出来的信息说明训 练数据集有55000张图片,测试数据集有10,000张图片,验证数据集有5000张 图片
数据科学引论-P瀌瀇h瀂瀁 之道 第 10 课 Te瀁瀆瀂瀅F濿瀂瀊-深度学习实践 本节课将介绍如何利用 Te瀁瀆瀂瀅F濿瀂瀊 框架建立一个简单的线性模型的基本工 作流程。在此特别感谢 H瀉a瀆瀆-Lab瀆 提供的教程,感兴趣的同学可以在 gi瀇h瀈b 上 找到他们的教程。 首先介绍我们需要引入的模块。第一个 瀀a瀇瀃濿瀂瀇濿ib 模块主要是用来辅助我们 画图,然后引入基本的 Te瀁瀆瀂瀅F濿瀂瀊 模块,以及用于矩阵计算和其他一些数组计 算的 瀁瀈瀀瀃瀌 模块。本次教程使用的 P瀌瀇h瀂瀁 版本是 3.6,Te瀁瀆瀂瀅F濿瀂瀊 的版本是 1.4.0。 在引入基本模块之后,我们需要将手写数字的图片,也就是我们此次简单线 性模型需要识别的图片加载进来。我们此次所用到的数据集是 MNIST 数据集, 它里面包含了 7 万张手写数字的图片,还包含它们对应的标签,它们的标签表示 的就是这些图片所对应的数字。Te瀁瀆瀂瀅F濿瀂瀊 直接提供了库函数,我们可以直接使 用它的库函数进行下载,例如第一个代码框里的两行代码,执行完这两行代码之 后会得到相应的输出信息,表明 MNIST 数据集已经加载完毕。整个 MNIST 数据 集被分为三个不同的子数据集,包含训练数据集、测试数据集和验证数据集。本 次教程只使用训练数据集和测试数据集。通过 瀃瀅i瀁瀇 函数打印出来的信息说明训 练数据集有 55000 张图片,测试数据集有 10,000 张图片,验证数据集有 5000 张 图片
载入数据 MNIST致据集大约12MB并且使用TensorFlow提供的库两数可以自动下载 data/dx-ubyte. /10 0y6+92 当你看到上在输出的信息时,MNST双据集已经加基完毕。MNST数据集一共有70000个图片并且有对应的标签(标签表示的是图片所对应的数乳,整个MNST数 据集会被分为3个不同的子数据集,包括刹练数据集、测试数据集和验证数据集,本教程只使用悠数据集和测试数据集。 In [4]1 print("Size of:") print("-Training-set:\t\t()".format(len(data.train.labels))) ion.labels))) size of: Training-set: vidation-et 5000 这个MNIST数据集是以One-Host编码方式进行加载的,这意味着标签从一 个单独的数字转换成了一个vector,而vector的长度等于所有可能类别的数量。 本次教程中一共有0到9十个数字,所以vector的长度就是10。每个vector中 只有一个代表第几个类别的元素是1,其他的元素都是0。例如,测试数据集前 五个图片标签中,第一行第七个坐标对应的数字是1,其他都是0,这也就意味 着第一个标签对应的图片就是7。 One-Hot编码 数据集以Oot的编码方式扣载,这意球着标签从一个单独的数字转为 ecto的长座等于所有可能类别的数量本教程中的vector长座是10,表示0型 g-共10个类别的数。每个v9cto中只有 个代表第几个类别的元素是1, 其他的元素都是0。例如我们展示的测试据集前五个图片的标签 In [5]:data.test.labels[0:5,:] array(I[..0.. 0 D.r 0 8 0 0. 0 0.j 1,0.0 0 . 0. 0. 0.j 【0,,0.。0,。 0.,1.,0,0.,0, 0.,0.111 为了比校和性能测试,我们还是需要把标益的类别表示为单个数字的,我们通过取出vec1or中最大元索的下标nde的方法将Oe-Hot端码的vector转换为单个的 数字。为了和Py0中的关键字s区分开,我们使用cs来命名表示为单个数字的标签类别,下面我们将测试数据集标签都转换为单个数字,并取出前五个标 签。第一个图片的标签类别是7,对应一个One-Hots编阳的vector中index为7的元素是1,其他的元素都是0, 0ut[51:array(【7,2,1,0,4]) 为了比较和性能测试,我们还是需要把标签的类别表示为单独的数字。因此, 我们通过取出vector中最大元素的下标,也就是index的方法,将One-Hot编 码的vector转换为单个的数字。为了和Python中的关键字class区分开,我们 使用cs来命名,表示单个数字的标签类别。我们将测试数据集标签都转换为单 个数字,然后取出前五个标签,可以看到它们组成的数组是7,2,10,4],也就是说
这个 MNIST 数据集是以 O瀁e-H瀂瀆瀇 编码方式进行加载的,这意味着标签从一 个单独的数字转换成了一个 瀉ec瀇瀂瀅,而 瀉ec瀇瀂瀅 的长度等于所有可能类别的数量。 本次教程中一共有 0 到 9 十个数字,所以 瀉ec瀇瀂瀅 的长度就是 10。每个 瀉ec瀇瀂瀅 中 只有一个代表第几个类别的元素是 1,其他的元素都是 0。例如,测试数据集前 五个图片标签中,第一行第七个坐标对应的数字是 1,其他都是 0,这也就意味 着第一个标签对应的图片就是 7。 为了比较和性能测试,我们还是需要把标签的类别表示为单独的数字。因此, 我们通过取出 瀉ec瀇瀂瀅 中最大元素的下标,也就是 i瀁de瀋 的方法,将 O瀁e-H瀂瀇 编 码的 瀉ec瀇瀂瀅 转换为单个的数字。为了和 P瀌瀇h瀂瀁 中的关键字 c濿a瀆瀆 区分开,我们 使用 c濿瀆 来命名,表示单个数字的标签类别。我们将测试数据集标签都转换为单 个数字,然后取出前五个标签,可以看到它们组成的数组是[7,2,1,0,4],也就是说
第一个图片的标签的类别是7,也就对应的是数字7,这和我们之前看到的vector 中第7个坐标对应的元素是1,而其他元素都是0是相符合的。 因为我们使用的MNIST书剧集中的图片,它的长度是28个像素,宽度也是 28个像素,所以我们现在需要定义几个数据维度的变量,以便我们在之后的代 码中能够重复使用这些数据维度。 首先,我们定义一个MNIST的图片,在每个维度上的长度是28个像素;其 次,我们再定义一个将图片存储在一维空间上的长度,即28×28这么长的一个 长度;然后,我们需要定义一个用来reshape图片的tuple;最后,我们需要定 义数字类别的数量,因为0到9一共有10个类别,所以数字类别的数量就是10。 数据维度T 工n【71:产加15T图片在每个度上都是2B个像景 i1m时gize-28 卓将雷片存在一维空间上的长度 img_size_flat img_size img_sizo ◆数字类别的数量,0到9一共10个类别 numc1asa88■10 下面定义一个画图的函数,这个画图函数主要是在3×3的网格上画出9张图 片,并且在图片下方标注图片所对应的正确类别和我们通过模型预测的类别,这 个函数主要是帮助大家能够可视化的理解整个工作的流程。 画图的函数 在3x3网格上画出9个图片并且在图片下方标注正碎的类别和预测的类别的函数 #创理一个包含3x3个子图的图 fig,axes plt.subplots(3,3) fig.subplots_adjust(hspace=0.3,vspace=0.3) ax.inshow(images[i].reshape(img_shape),cmap='binary') ·展示正种的类别和预测的类别 if cla_pred is None: xlabel "True:(0)".format(cls_true[i]) ax.set_xlabel(xlabel) ·将图中的鹅斯去掉 ax.set_xticka([]) ax.set_yticks(lJ) 下面我们将取出一些样本数据来看看我们这个数据集中所对应的一些手写
第一个图片的标签的类别是 7,也就对应的是数字 7,这和我们之前看到的 瀉ec瀇瀂瀅 中第 7 个坐标对应的元素是 1,而其他元素都是 0 是相符合的。 因为我们使用的 MNIST 书剧集中的图片,它的长度是 28 个像素,宽度也是 28 个像素,所以我们现在需要定义几个数据维度的变量,以便我们在之后的代 码中能够重复使用这些数据维度。 首先,我们定义一个 MNIST 的图片,在每个维度上的长度是 28 个像素;其 次,我们再定义一个将图片存储在一维空间上的长度,即 28×28 这么长的一个 长度;然后,我们需要定义一个用来 瀅e瀆ha瀃e 图片的 瀇瀈瀃濿e;最后,我们需要定 义数字类别的数量,因为 0 到 9 一共有 10 个类别,所以数字类别的数量就是 10。 下面定义一个画图的函数,这个画图函数主要是在 3×3 的网格上画出 9 张图 片,并且在图片下方标注图片所对应的正确类别和我们通过模型预测的类别,这 个函数主要是帮助大家能够可视化的理解整个工作的流程。 下面我们将取出一些样本数据来看看我们这个数据集中所对应的一些手写
字体以及它们对应的标签,然后再看看这些数据对不对。首先,我们从测试数据 集中取出前9张图片,然后再从测试数据集中取出前9个标签,将它们通过我们 刚才定义的画图函数进行绘制。然后,可以看到9张手写字体的图片以及它们所 对应的标签。 画几个图片看看数据是不是对的 I【91:来从测试数据集中取出前9个图片 images data.test.images(0:9] 从源试登据第中取出前个标签 cls_true data.test.cls[0:9] 严他用城雨致棕丽片阳短等面出度 plot_images(images-image8,cl8_true-cla_true) 因为我们需要通过操作符号变量来描述交互的操作单元,因此我们需要定义 一些操作符号变量。在第一个代码框中的X不是一个特定的值,而是一个占位符 (placeholder)。这些占位符在TensorFlow运行计算时需要对应的输入值。X也被 称作张量,也就是Tensor,,它可以表示为多维度的vector或者矩阵。因为我们 希望能够输入任意数量的MNIST图像,每一张图片都要转成28×28维的向量, 所以我们使用二维的浮点数张量来表示这些图。这个张量的数据类型被设置为 float32,形状是[None,28×28],这里的None表示此张量的第一个维度可以是 任意长度。然后,我们使用占位符变量表示图片对应的标签,这个占位符变量的 形状是None,第二位是l0,表示该变量可以存储任意数量的标签,并且每个标 签都是一个长度为10的vector。最后,我们定义一个保存标签对应数字的占位 符变量。为了方便比较,我们可以把标签转为单个数字,所以下面定义的这个变 量存储的就是这些数字。同样,这里的Noe表示这个变量是一个一维任意长度 的vector
字体以及它们对应的标签,然后再看看这些数据对不对。首先,我们从测试数据 集中取出前 9 张图片,然后再从测试数据集中取出前 9 个标签,将它们通过我们 刚才定义的画图函数进行绘制。然后,可以看到 9 张手写字体的图片以及它们所 对应的标签。 因为我们需要通过操作符号变量来描述交互的操作单元,因此我们需要定义 一些操作符号变量。在第一个代码框中的 X 不是一个特定的值,而是一个占位符 (瀃濿aceh瀂濿de瀅)。这些占位符在 Te瀁瀆瀂瀅F濿瀂瀊 运行计算时需要对应的输入值。X 也被 称作张量,也就是 Te瀁瀆瀂瀅,它可以表示为多维度的 瀉ec瀇瀂瀅 或者矩阵。因为我们 希望能够输入任意数量的 MNIST 图像,每一张图片都要转成 28×28 维的向量, 所以我们使用二维的浮点数张量来表示这些图。这个张量的数据类型被设置为 f濿瀂a瀇_32,形状是[N瀂瀁e, 28×28],这里的 N瀂瀁e 表示此张量的第一个维度可以是 任意长度。然后,我们使用占位符变量表示图片对应的标签,这个占位符变量的 形状是 N瀂瀁e,第二位是 10,表示该变量可以存储任意数量的标签,并且每个标 签都是一个长度为 10 的 瀉ec瀇瀂瀅。最后,我们定义一个保存标签对应数字的占位 符变量。为了方便比较,我们可以把标签转为单个数字,所以下面定义的这个变 量存储的就是这些数字。同样,这里的 N瀂瀁e 表示这个变量是一个一维任意长度 的 瀉ec瀇瀂瀅
占位符Placeholder)变量 我们通过操作符号变量来描迷交互的提作单元,x不是一个特定的值,而是一个占位荷placehoider,我们在TensorFlowi运行计算时裙入这个值。x就被称作张量 tensor),x可以表示为多维度的vector成者矩阵。我们希望缩够编入任您数量的M 图像,年一引 2B维的向量 我们用2维的泸 点数张量来表示这些 图,该张量的数据类型极设置为E1cat32,这个张量的形状是【N0ne,28x28]。(这里的one表示此张量的第一个维度可以是任何长度的, In [10]:x=tf.placeholder(tf.float32,[None,img_size_flat]) 然后我们使用占位符变量表示图片对应的标益,这个占位符受量的形状是Ioe,um_classes],这表示该变量可以存储任意数星的标签,并且每个标益都是 个长度为num_classest也就是10的vecto In [11]:y_true tf.placeholder(tf.float32,[None,num_classes]) 最后我们定义一个保存标签对应的数字的占位符变量,我们之前提到过为了方便比较我们把标签都转换为单个数字,所以下面定义的这个变量祝是存储这些数 字。[Woae】表示这个变量是一个一-维任意长座的vect0r In [12]:y_true_cls -tf.placeholder(tf.int64,[Nome]) 我们的模型除了前面的占位符变量之外,还需要一些权重值和偏置量,这些 当作另外的输入。我们可以使用占位符来表示它们,但是TensorFlow有一个更 好的方法表示,就是用Variable.。一个Variable代表一个可修改的张量,存放在 TensorFlow用于交互操作的图中,它们可以用于计算输入值,也可以在计算中被 修改。各种机器学习应用一般都会有模型参数,这些模型参数都可以用Variable 来表示,我们赋予Variable不同的初值来创建不同的Variable。在这里,我们使 用全为0的张量来初始化权重值weights和偏置量biases。.因为我们要学习 weights和biases的值,所以它们的初值可以随意设置。在这里,我们需要注意 到的是weights的形状是28×28和10,因为我们想用28×28位的图片向量乘以 它得到一个10维的向量,这个10维的向量每一个维度都对应不同的数字的类 别。然后,把biases的形状设置为一个1维的长度为10的向量,这样我们可以 直接把它加到输出上面。 In [13]:weights tf.Variable(tf.zeros([ing_size_flat,num_classes])) biases tf.Variable(tf.zeros([num_classes])) 下面我们将正式进入简单的线性模型的建立。首先,我们使用的这个简单的 线性模型就是把占位符变量X保存的图片vector和变量weights相乘,然后再 加上biases变量。从第一个代码框我们可以看到这个计算,因为我们的预测值得 到的结果可能很大或者很小,所以很难去分析这些预测值,所以我们希望能够归
我们的模型除了前面的占位符变量之外,还需要一些权重值和偏置量,这些 当作另外的输入。我们可以使用占位符来表示它们,但是 Te瀁瀆瀂瀅F濿瀂瀊 有一个更 好的方法表示,就是用 Va瀅iab濿e。一个 Va瀅iab濿e 代表一个可修改的张量,存放在 Te瀁瀆瀂瀅F濿瀂瀊 用于交互操作的图中,它们可以用于计算输入值,也可以在计算中被 修改。各种机器学习应用一般都会有模型参数,这些模型参数都可以用 Va瀅iab濿e 来表示,我们赋予 Va瀅iab濿e 不同的初值来创建不同的 Va瀅iab濿e。在这里,我们使 用全为 0 的张量来初始化权重值 瀊eigh瀇瀆 和偏置量 bia瀆e瀆。因为我们要学习 瀊eigh瀇瀆 和 bia瀆e瀆 的值,所以它们的初值可以随意设置。在这里,我们需要注意 到的是 瀊eigh瀇瀆 的形状是 28×28 和 10,因为我们想用 28×28 位的图片向量乘以 它得到一个 10 维的向量,这个 10 维的向量每一个维度都对应不同的数字的类 别。然后,把 bia瀆e瀆 的形状设置为一个 1 维的长度为 10 的向量,这样我们可以 直接把它加到输出上面。 下面我们将正式进入简单的线性模型的建立。首先,我们使用的这个简单的 线性模型就是把占位符变量 X 保存的图片 瀉ec瀇瀂瀅 和变量 瀊eigh瀇瀆 相乘,然后再 加上 bia瀆e瀆 变量。从第一个代码框我们可以看到这个计算,因为我们的预测值得 到的结果可能很大或者很小,所以很难去分析这些预测值,所以我们希望能够归