Tensorflow:Graph Session Op

本文深入探讨了TensorFlow中图(graph)与会话(session)的工作原理。解释了图如何定义计算流程,会话如何执行图并分配计算资源。同时,介绍了op的操作,包括常量、变量、占位符及它们在图中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接 https://www.cnblogs.com/jiaxblog/p/9054051.html

graph即tf.Graph(),session即tf.Session()

  • graph定义了计算方式,是一些加减乘除等运算的组合,类似于一个函数。它本身不会进行任何计算,也不保存任何中间计算结果。
  • session用来运行一个graph,或者运行graph的一部分。它类似于一个执行者,给graph灌入输入数据,得到输出,并保存中间的计算结果。同时它也给graph分配计算资源(如内存、显卡等)。

TensorFlow是一种符号式编程框架

首先要构造一个图(graph),然后在这个图上做运算。打个比方,graph就像一条生产线,session就像生产者。生产线具有一系列的加工步骤(加减乘除等运算),生产者把原料投进去,就能得到产品。不同生产者都可以使用这条生产线,只要他们的加工步骤是一样的就行。同样的,一个graph可以供多个session使用,而一个session不一定需要使用graph的全部,可以只使用其中的一部分。

关于graph

定义一个图: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.

可以把所有的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分配合适的计算资源。

关于session

x = tf.constant(2)
y = tf.constant(3)
z = tf.add(x, y)

with tf.Session() as sess:
    result = sess.run(z)
    print(result)

 

关于op

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:

  • x.initializer # 对x做初始化,即赋值为初始值[2, 3]
  • x.value() # 获取x的值
  • x.assign(...) # 赋值操作
  • x.assign_add(...) # 加法操作

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())

一个特殊的op: tf.placeholder()

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是更好的选择。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

我已经用1.15的tensorflow冻结生成了pb模型,同时也用1.15的tensorflow转为rknn但是报错了 W load_tensorflow: Catch exception when loading tensorflow model: ./frozen_facenet.pb! W load_tensorflow: Make sure that the tensorflow version of './frozen_facenet.pb' is consistent with the installed tensorflow version '1.15.0'! E load_tensorflow: Traceback (most recent call last): E load_tensorflow: File "/home/book/anaconda3/envs/rknn/lib/python3.7/site-packages/tensorflow_core/python/framework/importer.py", line 501, in _import_graph_def_internal E load_tensorflow: graph._c_graph, serialized, options) # pylint: disable=protected-access E load_tensorflow: tensorflow.python.framework.errors_impl.InvalidArgumentError: Input 0 of node InceptionResnetV1/Bottleneck/BatchNorm/cond_1/AssignMovingAvg_1/Switch was passed float from InceptionResnetV1/Bottleneck/BatchNorm/moving_variance:0 incompatible with expected float_ref. E load_tensorflow: During handling of the above exception, another exception occurred: E load_tensorflow: Traceback (most recent call last): E load_tensorflow: File "rknn/api/rknn_base.py", line 1271, in rknn.api.rknn_base.RKNNBase.load_tensorflow E load_tensorflow: File "rknn/base/convertor/tensorflow2onnx/tf2onnx/convert.py", line 631, in rknn.base.convertor.tensorflow2onnx.tf2onnx.convert.from_graph_def E load_tensorflow: File "rknn/base/convertor/tensorflow2onnx/tf2onnx/convert.py", line 632, in rknn.base.convertor.tensorflow2onnx.tf2onnx.convert.from_graph_def E load_tensorflow: File "rknn/base/convertor/tensorflow2onnx/tf2onnx/convert.py", line 633, in rknn.base.convertor.tensorflow2onnx.tf2onnx.convert.from_graph_def E load_tensorflow: File "rknn/base/convertor/tensorflow2onnx/tf2onnx/convert.py", line 634, in rknn.base.convertor.tensorflow2onnx.tf2onnx.convert.from_graph_def E load_tensorflow: File "/home/book/anaconda3/envs/rknn/lib/python3.7/site-packages/tensorflow_core/python/util/deprecation.py", line 507, in new_func E load_tensorflow: return func(*args, **kwargs) E load_tensorflow: File "/home/book/anaconda3/envs/rknn/lib/python3.7/site-packages/tensorflow_core/python/framework/importer.py", line 405, in import_graph_def E load_tensorflow: producer_op_list=producer_op_list) E load_tensorflow: File "/home/book/anaconda3/envs/rknn/lib/python3.7/site-packages/tensorflow_core/python/framework/importer.py", line 505, in _import_graph_def_internal E load_tensorflow: raise ValueError(str(e)) E load_tensorflow: ValueError: Input 0 of node InceptionResnetV1/Bottleneck/BatchNorm/cond_1/AssignMovingAvg_1/Switch was passed float from InceptionResnetV1/Bottleneck/BatchNorm/moving_variance:0 incompatible with expected float_ref. W If you can't handle this error, please try updating to the latest version of the toolkit2 and runtime from: https://console.zbox.filez.com/l/I00fc3 (Pwd: rknn) Path: RKNPU2_SDK / 2.X.X / develop / If the error still exists in the latest version, please collect the corresponding error logs and the model, convert script, and input data that can reproduce the problem, and then submit an issue on: https://redmine.rock-chips.com (Please consult our sales or FAE for the redmine account) E build: The model has not been loaded, please load it first! E export_rknn: RKNN model does not exist, please load & build model first!
最新发布
03-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值