graph即tf.Graph()
,session即tf.Session()
,不少人常常将二者混淆,其实两者彻底不是同一个东西。python
TensorFlow是一种符号式编程框架,首先要构造一个图(graph),而后在这个图上作运算。打个比方,graph就像一条生产线,session就像生产者。生产线具备一系列的加工步骤(加减乘除等运算),生产者把原料投进去,就能获得产品。不一样生产者均可以使用这条生产线,只要他们的加工步骤是同样的就行。一样的,一个graph能够供多个session使用,而一个session不必定须要使用graph的所有,能够只使用其中的一部分。编程
g = tf.Graph() a = tf.constant(2) b = tf.constant(3) x = tf.add(a, b)
上面就定义了一个graph。tensorflow会默认给咱们创建一个graph,因此g = tf.Graph()
这句实际上是能够省略的。上面的graph包含3个操做,即op,但凡是op,都须要经过session运行以后,才能获得结果。若是你直接执行print(a)
,那么输出结果是:安全
Tensor("a:0", shape=(), dtype=int32)
是一个张量(Tensor)。若是你执行print(tf.Session().run(a))
,才能获得2.session
你能够定义多个graph,例如一个graph实现z = x + y,另外一个graph实现u = 2 * v框架
g1 = tf.Graph() g2 = tf.Graph() with g1.as_default(): x = tf.constant(2) y = tf.constant(3) z = tf.add(x, y) with g2.as_default(): v = tf.constant(4) u = tf.mul(2, v)
但一般不建议这么作,缘由以下:函数
事实上,你能够把全部的op都定义在一个graph中:翻译
x = tf.constant(2) y = tf.constant(3) z = tf.add(x, y) v = tf.constant(4) u = tf.mul(2, v)
从上面graph的定义能够看到,x/y/z是一波,u/v是另外一波,两者没有任何交集。这至关于在一个graph里有两个独立的subgraph。当你要计算z = x + y时,执行tf.Session().run(z)
;当你想计算u = 2 * v,就执行tf.Session().run(u)
,两者彻底独立。但更重要的是,两者在同一个session上运行,系统会均衡地给两个subgraph分配合适的计算资源。code
一般咱们会显示地定义一个session来运行graph:orm
x = tf.constant(2) y = tf.constant(3) z = tf.add(x, y) with tf.Session() as sess: result = sess.run(z) print(result)
输出结果是5。内存
tensorflow是一个符号式编程的框架,首先要定义一个graph,而后用一个session来运行这个graph获得结果。graph就是由一系列op构成的。上面的tf.constant()
,tf.add()
,tf.mul()
都是op,都要现用session运行,才能获得结果。
不少人会觉得tf.Variable()
也是op,其实不是的。tensorflow里,首字母大写的类,首字母小写的才是op。tf.Variable()
就是一个类,不过它包含了各类op,好比你定义了x = tf.Variable([2, 3], name = 'vector')
,那么x就具备以下op:
tf.Variable()
必须先初始化,再作运算,不然会报错。下面的写法就不是很安全,容易致使错误:
W = tf.Variable(tf.truncated_normal([700, 10])) U = tf.Variable(2 * W)
要把W赋值给U,必须现把W初始化。但不少人每每忘记初始化,从而出错。保险起见,应该按照下面这样写:
W = tf.Variable(tf.truncated_normal([700, 10])) U = tf.Variable(2 * W.intialized_value())
placeholder,翻译过来就是占位符。其实它相似于函数里的自变量。好比z = x + y,那么x和y就能够定义成占位符。占位符,顾名思义,就这是占一个位子,平时不用关心它们的值,当你作运算的时候,你再把你的数据灌进去就好了。是否是和自变量很像?看下面的代码:
a = tf.placeholder(tf.float32, shape=[3]) # a是一个3维向量 b = tf.constant([5, 5, 5], tf.float32) c = a + b with tf.Session() as sess: print sess.run(c, feed_dict = {a: [1, 2, 3]}) # 把[1, 2, 3]灌到a里去
输出结果是[6, 7, 8]。上面代码中出现了feed_dict
的概念,其实就是用[1, 2, 3]代替a的意思。至关于在本轮计算中,自变量a的取值为[1, 2, 3]。其实不只仅是tf.placeholder
才能够用feed_dict
,不少op均可以。只要tf.Graph.is_feedable(tensor)
返回值是True,那么这个tensor就可用用feed_dict来灌入数据。
tf.constant()
是直接定义在graph里的,它是graph的一部分,会随着graph一块儿加载。若是经过tf.constant()
定义了一个维度很高的张量,那么graph占用的内存就会变大,加载也会变慢。而tf.placeholder
就没有这个问题,因此若是数据维度很高的话,定义成tf.placeholder
是更好的选择。