Tensorflow之旅(4)(戴德曼翻译)

四. Tensorflow的编程接口

在讨论了Tensorflow计算模型之后,我们现在聚焦到更为实际的编程接口。我们先介绍可用的编程语言接口,再使用一个例子讲解Python API的使用。最后,我们概括Tensorflow API的格局和怎么能够快速创建算法原型。

A. 接口

        Tensorflow拥有C++和Python两种编程接口,允许用户调用后端功能。Python API提供了丰富和完整的创建和运行计算图的编程接口,而C++的接口相对有限和与后端功能实现耦合度太高,仅仅允许去执行计算图和序列化图到谷歌协议缓冲格式。对于创建图的C++接口在文章发表的时候还很不完善。

        值得注意的是,Tensorflow的API和NumPy有很好的集成。因此,我们可以看到Tensorflow的数据类型tensor和NumPy的ndarrays在很多应用场合都是可以互换的。

B. 示例解读

         接下来的几个章节,我们将一步一步的解读一个Tensorflow的真实示例。我们将训练一个带有一个输入和一个输出的简单的多层感知器(MLP),它将用于识别MNIST数据集中的手写字符。在这个数据集中,样本时28x28像素的手写字符从0-9。我们将这些字符转换成784灰度像素扁平的向量。对于每个样本的标签是相应字符的数字。

        我们从加载输入数据开始解读。这里数据已经被处理好成为我们需要的格式,只需要调用read函数加载数据到内存。进一步来看,我们设置one_hot=True来指定是否使用一个10维向量(d1,。。。,d10)的转置来表征某一个字符,即所有维度数字是0,只有表征该字符的位置是1。

importtensorflow as tf

# Download and extract the MNIST data set.

# Retrieve the labels as one-hot-encoded vectors.

mnist = mnist_data.read("/tmp/mnist", one_hot=True)

        接下来,我们通过调用tf.Graph创建一个新计算图。为了给这个图增加算子,我们必须把这个图注册为缺省图。在TensorflowAPI和库设计里面,新的算子总是挂在缺省图上。相应代码如下:

# Create a new graph

graph = tf.Graph()

# Register the graph as the default one to add nodes

with graph.as_default():

# Add operations ...

        我们现在准备通过增加算子来生成计算图。让我们先增加两个占位节点examples和labels。占位者是一种特殊变量,在图运算的时候必须被确切的张量赋值。也就是说,上面创建的占位者必须在Session.run()被调用的时候,被feed_dict参数传进来的张量所取代。对于每一个这个的占位者,我们定义它的形状和数据类型。Tensorflow在这里可以使用None来描述占位者形状的第一个维度。这就是为未来给此占位者赋值一个在此维度大小可变的张量。对于examples的列大小,我们指定每一幅图的特征数,即28 x 28 = 784个像素。labels占位者应该有10列,代表着我们在上面定义的10维字符分类向量。

# Using a 32-bit floating-point data type tf.float32

examples = tf.placeholder(tf.float32, [None, 784])

labels = tf.placeholder(tf.float32, [None, 10])

        给定一个example矩阵X属于集合R是nx784,意味着包含n个图像,学习算法将使用仿射变换X.W+b,这里W是一个784x10的权重矩阵,b是10维偏置向量。这个变换的结果产生Y是nx10的矩阵,包含我们模型对于每一个样本图像识别的结果。这些结果是一些任意数值而不是概率分布。为了转换它们到一个有效概率分布,在给定似然Pr[x=i],即第x样本图像是数字i的概率,我们使用softmax函数,公式和相应代码如下:

# Draw random weights for symmetry breaking

weights = tf.Variable(tf.random_uniform([784, 10]))

# Slightly positive initial bias

bias = tf.Variable(tf.constant(0.1, shape=[10]))

# tf.matmul performs the matrix multiplication XW

# Note how the + operator is overloaded for tensors

logits = tf.matmul(examples, weights) + bias

# Applies the operation element-wise on tensors

estimates = tf.nn.softmax(logits)


        接下来,我们计算我们的目标函数,产生模型在当前权重W和偏差b下的成本或者损失。公式H(L,Y)i=−jLi,j·log(Yi,j)计算我们预测的结果和训练样本实际结果之间的交叉熵。更精确而言,我们考虑的是所有训练样本的交叉熵的均值作为成本或者损失。

# Computes the cross-entropy and sums the rows

cross_entropy = -tf.reduce_sum(labels*tf.log(estimates), [1])

loss = tf.reduce_mean(cross_entropy)

        现在,我们有了目标函数,就可以进行随机梯度下降计算去更新我们模型的权重矩阵。为此,Tensorflow提供了GradientDescentOptimizer这个类实现这一过程。该类使用算法的学习速度来初始化,同时提供算子minimize来处理我们的成本或损失张量。这就是我们在Session环境里训练模型需要反复迭代的算子。

# We choose a learning rate of 0.5

gdo = tf.train.GradientDescentOptimizer(0.5)

optimizer = gdo.minimize(loss)

        最后,我们就可以实际训练模型了。在Tensorflow里,我们需要进入一个会话环境,使用tf.Session来管理会话。通过Session,我们训练我们的模型,执行计算图上的算子。我们有几种调用方法,最常见的方式是调用Session.run(),然后传递一组张量给它。或者,我们也可以直接在张量上调用eval()和算子上run()。在评估算子之前,我们必须确保我们图变量被初始化了。理论上,我们可以通过调用Variable.initializer算子来初始化每一个变量。然而,最常见的办法是调用tf.initialize_all_variables()方法去一次性初始化所有变量。然后我们就可以迭代几次随机梯度下降,每一次我们选取一些样本图像和标签,传递给模型去计算成本或损失。最后,我们的成本或损失会越来越小(我们希望如此):

with tf.Session(graph=graph) as session:

# Execute the operation directly

tf.initialize_all_variables().run()forstepinrange(1000):

# Fetch next 100 examples and labels

x, y = mnist.train.next_batch(100)

# Ignore the result of the optimizer (None)

_, loss_value = session.run(

[optimizer, loss],

feed_dict={examples: x, labels: y})

print(’Loss at step {0}: {1}’.format(step, loss_value))

        这个例子完整的代码参见附录。

C. 抽象与封装

        你可以已经注意到构建模型和训练的过程是需要花费大量的开销在创建一个非常简单的两层网络。通过深度学习的名称“深度”二字,就隐含了,你需要使用携带大量隐藏层的深度神经网络。因此,每一次构建模型都需要花这么多时间构建权重矩阵,偏置矩阵,计算矩阵乘法,加法,和应用非线性激活函数的神经网络是效率低下的,因此,我们需要抽象和封装这一过程。幸好,我们可以使用一些开源的库来完成这一过程,比如PrettyTensor,TFLearn和Keras。下面我们会分别论述PrettyTensor和TFLearn。

         1)PrettyTensor:这是谷歌开发的高级编程接口,主要的是通过Builder模式来调用Tensorflow的API。它允许用户把Tensorflow的算子和张量封装进干净的版本,然后迅速将任意层串接起来。比如,它可以用一行代码完成一个输入张量传输到一个全连接(稠密)神经网络层。下面的样例代码显示了从创建一个占位者到初始化,到创建三层网络到最后输出softmax的一个分布。

examples = tf.placeholder([None, 784], tf.float32)

softmax = (prettytensor.wrap(examples)

.fully_connected(256, tf.nn.relu)

.fully_connected(128, tf.sigmoid)

.fully_connected(64, tf.tanh)

.softmax(10))

2)TFLearn:这是另一个基于Tensorflow本体的封装库,它有高度封装的神经网络层和层连接API。而且,它比PrettyTensor一定要通过Session建立训练和评估模型更进一步,它可以直接添加训练样本和标签来训练模型。在TFLearn里面,有创建完整神经层次的函数,有返回原始Tensorflow对象的函数,有混合Tensorflow本体代码调用的编程。比如,我们可以取代Tensorflow的输出层,自己完整构建它,但是依然保持其它部分不发生改变。下面10行代码完成了附录65行代码才能完成的功能。

importtflearn

importtflearn.datasets.mnist as mnist

X, Y, validX, validY = mnist.load_data(one_hot=True)

# Building our neural network

input_layer = tflearn.input_data(shape=[None, 784])

output_layer = tflearn.fully_connected(input_layer,

10, activation=’softmax’)

# Optimization

sgd = tflearn.SGD(learning_rate=0.5)

net = tflearn.regression(output_layer,

optimizer=sgd)

# Training

model = tflearn.DNN(net)

model.fit(X, Y, validation_set=(validX, validY))

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容