Tensorflow核心要点

 

TensorFlow与别的框架不同之处就是它按照当前存在的计算图来进行计算,而不是传统的按照我们的代码的顺序来执行计算,个人觉得这个才是理解TensorFlow的核心要点。

在tensorflow中,是以计算图的方式来求值的,计算图在代码首次执行的时候就构建好了并存在内存中,因此之后调用sess.run求值都是根据当前存在的计算图来求的,且按照节点之间的依赖关系往前推导其依赖值,直到所有的依赖值已知(如Variable,placeholder,const等都是已知类型),不在依赖之中的不予计算,也就是说并不是简单地计算整个图。根据当前构建好的计算图来求值这句话很重要,看一个例子

import tensorflow as tf

a = tf.get_variable(name="a",initializer=tf.constant(0))

def add():
    print("add()")
    b = tf.add(a, 1)
    return b

c = add()

init = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess = tf.Session()
sess.run(init)

print(c)
print(sess.run(c))
sess.run(tf.assign(a,1))
print(sess.run(c))

分析代码可知我们先创建了Variable a,且初始值为0,此时tensorflow内部模块捕捉到了这个信息,将计算图更新为

接着定义了一个 add() 函数,由于没有真正执行,tensorflow内部模块没有接受到任何信息,于是计算图仍为

紧接着 add() 被调用,于是输出 "add()",然后将 a+1 赋值给 b,这下tensorflow内部模块又捕捉到了这个信息将计算图更新为

接着 b 的值又被赋给 c,于是计算图更新为

紧接着,我们将所有变量初始化,于是计算图变为

然后输出一下 c 并调用 print(sess.run(c)) 计算 c 的值,此时 c 依赖于 b,因此应先计算 b,由于 b 在 add() 中被计算,因此再次调用 add(),输出“add()”,然后计算b,b 依赖于 a,而 a 的值已知为 0,因此算出 b 为 1,于是 c 也为1,输出“1”。

接着通过 sess.run(tf.assign(a,1)),a 被重新赋值为 1,计算图更新为

然后我们调用 print(sess.run(c)) 计算 c 的值,此时 c 依赖于 b,因此应先计算 b,由于 b 在 add() 中被计算,因此再次调用 add(),输出“add()”,然后计算b,b 依赖于 a,而 a 的值已知为 1,因此算出 b 为 2,于是 c 也为2,输出“2”。

然后观看结果:

(红色字体为系统输出,可忽略)

咦?!不对呀,按照推理,最后应该输出3次“add()”,然而结果却只在最开始的时候输出了一次,那么到底是哪里出错了?

根据当前构建好的计算图来求值,我再强调一次这句话。什么意思?

也就是说在调用 sess.run(c) 的时候,此时要计算 b 的值,而计算 b 并不是通过add() 函数实现的,而是按照现存的计算图来计算的,比如第一次计算 b 的时候,此时的计算图为

于是求得 b 为 a+1 = 1,这个计算过程发生在内部模块中,而不是我们的 add() 函数,因此并不会有输出“add()”。

是不是觉得豁然开朗,又有了新的理解? 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值