TensorFlow对于初学者来说可能像是一门外星语言。但在参加了几次TensorFlow的会议后,开始掌握了它。发现这个话题非常有趣,因此深入研究了它。
在阅读TensorFlow相关资料时,明白了一个道理:要理解TensorFlow,首先需要理解张量和图。这两个基本概念是谷歌在其深度学习框架中尝试整合的。
在本文中,将解释张量和图的基础知识,以帮助更好地理解TensorFlow。
根据维基百科对张量的定义:张量是描述几何向量、标量和其他张量之间的线性关系的几何对象。这些关系的简单例子包括点积、叉积和线性映射。几何向量通常用于物理和工程应用,标量本身也是张量。
根据定义,深度学习希望把张量看作是多维数组。在最近一次同事的演讲中,他需要展示使用NumPy构建的神经网络和张量之间的差异。在准备演讲材料时,他发现NumPy和张量几乎需要相同的运行时间(使用不同的优化器)。
两人都为此头疼,试图证明TensorFlow更好,但不能。这让感到不安,决定进一步深入研究。
现在,需要首先理解张量和NumPy。根据NumPy官方网站的说法,NumPy也可以用作高效的多维通用数据容器。可以定义任意数据类型。这使得NumPy能够与各种数据库无缝且快速地集成。
阅读完这些后,确信脑海中浮现的问题与一样。张量和N维数组之间有什么区别?根据Stackexchange的说法,张量:多维数组 :: 线性变换:矩阵。上述表达式意味着张量和多维数组是不同类型的对象。前者是一种函数类型,后者是一种适合在坐标系中表示张量的数据结构。
从数学上讲,张量被定义为多线性函数。多线性函数由各种向量变量组成。张量场是一个张量值函数。对于严格的数学解释,可以在这里阅读。这意味着张量是需要定义的函数或容器。当有数据输入时,实际计算发生。所看到的NumPy数组(1D、2D、...、ND)可以被认为是通用张量。
希望现在对什么是张量有了一定的了解。
现在,大问题是为什么需要在TensorFlow中处理张量。大启示是NumPy缺少创建张量的功能。可以将张量转换为NumPy,反之亦然。这是可能的,因为这些结构被明确定义为数组/矩阵。
通过阅读和搜索张量和NumPy数组得到了一些答案。对于更多阅读,没有比官方文档更好的资源了。
Theano的元编程结构似乎是谷歌创建TensorFlow的灵感来源,但谷歌的团队将其提升到了一个新的水平。
根据TensorFlow官方博客的入门指南:计算图是一系列TensorFlow操作排列成的节点图。
import tensorflow as tf
# 如果考虑一个简单的乘法 a = 2 b = 3 mul = a*b
print ("The multiplication produces:::", mul)
# 但考虑一个tensorflow程序来复制上述 at = tf.constant(3) bt = tf.constant(4)
mult = tf.mul(at, bt)
print ("The multiplication produces:::", mult)
每个节点接收零个或多个张量作为输入,并产生一个张量作为输出。常量节点就是其中一种。像所有TensorFlow常量一样,它不接收输入,并输出它内部存储的值。
认为上述陈述是正确的,因为已经看到构建一个计算图来乘以两个值是一个相当直接的任务。但需要最终的值。已经定义了两个常量at和bt,以及它们的值。如果不定义值会怎样?
at = tf.constant() bt
= tf.constant()
mult = tf.mul(at, bt)
print ("The multiplication produces:::", mult)
TypeError Traceback (most recent call last)
猜常量需要一个值。下一步是找出为什么没有得到任何输出。看来要评估制作的图,它需要在一个会话中运行。
要理解这种复杂性,需要了解计算图有什么:张量:at, bt 操作:mult 要执行mult,计算图需要一个会话,其中张量和操作将被评估。现在让在一个会话中评估图。
sess = tf.Session()
# 执行会话
print ("The actual multiplication result:::", sess.run(mult))
上述图将打印相同的值,因为使用的是常量。还有另外两种方法可以将值发送到图 - 变量和占位符。
当训练模型时,使用变量来保存和更新参数。变量是包含张量的内存缓冲区。它们必须显式初始化,并且可以在训练期间和训练后保存到磁盘。可以稍后恢复保存的值以进行练习或分析模型。
变量初始化器必须在模型中的其他操作运行之前显式运行。最简单的方法是添加一个运行所有变量初始化器的操作,并在使用模型之前运行该操作。
可以从另一个变量初始化变量。常量不能更新,这在任何地方都是一个遗憾。需要检查是否可以动态创建变量。
可以得出结论,占位符是在创建计算图时定义变量的一种方式,而实际上没有定义要传递给它的值。
tf.placeholder() 是规范,由所有编写TensorFlow代码的人每天使用。
对于更深入的阅读:
TensorFlow的I/O。
将在下面检查变量和占位符。
var1 = tf.Variable(2, name="var1") var2
= tf.Variable(3, name="var2")
mulv = tf.mul(var1, var2)
print (mulv)
Tensor("Mul_2:0", shape=(), dtype=int32)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) # 总是需要初始化变量
print ("The variable var1 is:::", sess.run(var1))
print ("The variable var2 is:::", sess.run(var2))
print ("The computational result is:::", sess.run(mulv))
变量var1是::: 2
变量var2是::: 3
计算结果是::: 6
pl = tf.placeholder(tf.float32, name="p")
pi = tf.constant(3.) c = tf.add(pl, pi)
print (c)
Tensor("Add_1:0", dtype=float32)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) # 总是需要初始化变量
writer = tf.train.SummaryWriter("output", sess.graph)
#print("The placeholder value passed:::", sess.run(pl, {pl:3}))
print("The calculation result is:::", sess.run(c, {pl:3}))
writer.close()
WARNING:tensorflow:From
removed after 2016‐11‐30.
Instructions for updating:
Please switch to tf.summary.FileWriter. The interface and behavior is the same; this is just a rename.
计算结果是::: 6.0
在本文中,观察了张量和计算图中的作用。创建这个的实际目标是使张量流经图。编写张量,并通过会话使它们流动。
希望喜欢阅读这篇文章。如果有任何问题或疑问,请随时在下面发表。
1. TensorFlow 入门指南
2. CS224d
3. MetaFlow博客
4. Theano与TensorFlow
5. 使用TensorFlow进行机器学习