Tensorflow:print输出控制

本文介绍了在TensorFlow中调试代码和输出中间结果的方法,包括使用Session.run(), tf.Print(), summary等工具,以及解决Tensor输出省略号等问题。

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

http://blog.csdn.net/pipisorry/article/details/22680397

 Tensorflow输出

tensorflow由于其基于静态图的模式,导致写代码的时候很难调试,除了用官方的调试工具外,最直接的方法就是把中间结果输出出来查看,然而,直接用print函数只能输出tensor变量的形状(如("Placeholder:0", shape=(128, 346), dtype=float32),原因是:A Tensor object is a symbolic handle to the result of an operation, but does not actually hold the values of the operation’s output.),而不是数值,而我们通常想要输出tensor的具体数值。

print tensor属性信息

如shape,直接使用(必须使用int()转换,否则float(num_features)报错:TypeError: float() argument must be a string or a number, not 'Dimension')

num_features = int(batch_samples.shape[1])

或者int(batch_samples.get_shape()[1])

或者传入sess后使用tf.shape(batch_samples).eval(session=sess)

输出的shape为?即None怎么办?

输出的shape为(batch_size,?)不能直接输入到dense layer中,否则报错:flatten dense ValueError: The last dimension of the inputs to `Dense` should be defined. Found `None`.

        如果是keras,main_input = Input(shape=(max_seq_len,), dtype='float64', name='main_input')的维度为shape=(?, max_seq_len)。可以加上main_input = Input(shape=(max_seq_len,), batch_shape=(batch_size,) + tuple((maxlen,)), dtype='float64', name='main_input')这样输出就是shape=(batch_size, max_seq_len)。通过下面的debug找到的:进入Input函数的代码文件input_layer.py:

if shape is not None and not batch_shape:
    batch_shape = (None,) + tuple(shape)
    # batch_shape = (128,) + tuple(shape) # batch_size = 128

        如果是tensorflow dataset.padded_batch(params.get('batch_size', 20), shapes, defaults, drop_remainder=True)可以加上drop_remainder=True,即the last batch should be dropped in the case it has fewer than batch_size elements。这样所有的batch大小才都是batch_size,输出的dataset的shape为shapes: (((20, max_seq_len), (20,)), (20, ?)),而不是shapes: (((?, max_seq_len), (?,)), (?, ?))。通过进入函数padded_batch文件内部多层后,dataset_ops.py中这句发现的:

tensor_shape.vector(
    tensor_util.constant_value(self._batch_size) if smart_cond.
    smart_constant_value(self._drop_remainder) else None)

-柚子皮-

print tensor数值

1 Session.run()Tensor.eval()

所以评估Tensor对象的实际值的最简单的方法是将其传递给Session.run()方法,或者在有默认会话时调用Tensor.eval()(即在with tf.Session():块中)。一般来说,不能在会话中运行某些代码时打印张量的值。

使用Session.run()方法时,placeholder需要feed才能有值,所以需要在函数中返回这个placeholder进行feed,通过run it inside a session输出结果。

但是如果想要输出函数中的中间值而该值又未传回主函数呢?如estimator这种端到端的高级封装,这种情况下无法在函数中开启一个新的Session,但是可以用tf.Print建立op来实现。

示例

import tensorflow as tf

x = tf.constant([[[1, 2, 3],
                  [4, 5, 6]],
                 [[7, 8, 9],
                  [10, 11, 12]]])

y = tf.constant([[[11, 12, 13],
                  [14, 15, 16]],
                 [[17, 18, 19],
                  [110, 111, 112]]])

print(x.shape)  # (2, 2, 3)
with tf.Session().as_default() as sess:
   print(x.eval())   
print(y.eval(session=sess))
print(sess.run(y))

2 tf.Print

计算一个变量的同时,指定打印一组变量

tf.Print(
    input_,
    data,
    message=None,
    first_n=None,
    summarize=None,
    name=None
)

input_:通过这个操作的张量。 (流入的数据流)
data:计算 op 时要打印的张量列表。(用[ ]引起来的一串需要打印的东西,用逗号隔开)
message:一个字符串,错误消息的前缀。
first_n:只记录 first_n 次数。负数日志,这是默认的。
summarize:只打印每个张量的固定数目的条目(忽略维度信息)。如果没有,则每个输入张量最多打印3个元素。summarize=-1打印所有数值。

name:操作的名称(可选)

如:pred_id = tf.Print(pred_id, [pred_id], summarize=20, message='*pred_id*')

        x=tf.Print(x,[x.shape,'test', x],message='Debug message:',summarize=100)

示例1:

import tensorflow as tf

score = tf.constant([[0.0], [0.2], [0.3],
                         [0.2], [1.0], [4.0]])

score = tf.Print(score, ['score: ', score], summarize=10)
score_sig = tf.sigmoid(score)
score_sig = tf.Print(score_sig, ['score_sig: ', score_sig], summarize=10)
score_scale = score_sig * 2.0 - 1.0
score_scale = tf.Print(score_scale, ['score_scale: ', score_scale], summarize=10)

with tf.Session() as sess:
  sess.run(score_scale)

[score: ][[0][0.2][0.3][0.2][1][4]]
[score_sig: ][[0.5][0.549833953][0.574442506][0.549833953][0.731058598][0.982013762]]
[score_scale: ][[0][0.0996679068][0.148885012][0.0996679068][0.462117195][0.964027524]]

示例2:

def test():
    a=tf.constant(0)
    a_print = tf.Print(a,['a_value: ',a])
    for i in range(10):  
        a=a_print+1
    return a
    
if __name__=='__main__':
    with tf.Session() as sess:
        sess.run(test())

会输出几次值呢?这其实并不是看下文中a_print被使用了几次,而是看数据流要从该节点上流经几次,可以理解为a_print这个op被“定义”了几次。

但是如果for循环中改成a_print=a_print+1,就不会输出任何东西,因为a_print这个op没有和别的变量发生关系,它没有被别的变量使用,在图里为孤立的一个节点,没有数据流过,就不会被执行。

像计算loss的logits这种方法可以每次输出,但是像计算acc指标的pred_id可能只会在每次batch执行完执行一次以及在load checkpoint时执行多次(这个不知道为什么,可能是分析不行)。

[tensorflow在函数中用tf.Print输出中间值的方法]

示例3:

        输出estimator这种端到端的高级封装中后面没有用到的tensor。如想输出其中一个 tensor变量,但它又不是返回的结果,没有数据流过,所以即使tf.Print()也不会打印出来。

解决:在返回时可以返回dict的tensor,加一个额外的other_print_tensor就可以,也会有数据流过。如predict时的:

other_print_tensor = tf.Print(other_print_tensor, [other_print_tensor])
predictions = {
    ...,
    'other_print_tensor': other_print_tensor
}
return tf.estimator.EstimatorSpec(mode, predictions=predictions)

但是这里dict返回的tensor的batch size必须是一样大小,否则会出错:ValueError: Batch length of predictions should be same. pred_strings1 has different batch length than others.而在estimator中dict其它的shape又是(None, None)的没法获取。

reverse_vocab_tags = tf.contrib.lookup.index_to_string_table_from_file(params['tags'])
other_print_tensor = tf.Print(reverse_vocab_tags.export()[0], [reverse_vocab_tags.export()[0]])

所以像这种index_to_string_table_from_file最好在外面另起一个代码用sess.run()测试下。

3 使用summary方法,在tensorboard中观测

[How to print the value of a Tensor object in TensorFlow?][如何在TensorFlow中打印Tensor对象的值?]

[Tensorflow print in function]

[Tensorflow之调试(Debug)及打印变量]*

4 logging方法(不行)

tf.logging.set_verbosity(tf.logging.INFO)
...
tf.logging.info("Created vocabulary with %d words" % len(vocab))

5 第三方debug/可视化工具[https://github.com/ericjang/tdb]

3. tf.print()

前面不管是直接使用python的print函数,还是使用tf.Print都需要构建一个会话对象session,然后再会话里面运行,而tf.print()则不在需要了,但是需要用到eager_execution模式。

示例:tf2.0

import tensorflow as tf

doc_score = tf.constant([[1.0, 2, 3], [3, 4, 5]])
doc_score_mean = tf.reduce_mean(doc_score, axis=0)  # , keepdims=True
tf.print(doc_score_mean)

doc_score_mean_, doc_score_var = tf.nn.moments(doc_score, axes=0)
tf.print(doc_score_mean_)
tf.print(doc_score_var)
[2 3 4]
[2 3 4]
[1 1 1]

[tensorflow Debugger教程(二)——tf.Print()与tf.print()函数-CSDN博客]

格式控制

禁用科学记数法

np.set_printoptions(suppress=True)

解决tensorflow打印tensor有省略号的问题

np.set_printoptions(threshold=np.inf)

但是这个只对run出来的打印有效,对tf.Print无效。

[numpy教程:基本输入输出和文件输入输出Input and output_np输出-CSDN博客]

 tensorflow去除warning信息输出

import warnings

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    warnings.warn("deprecated", DeprecationWarning)
    import tensorflow as tf

from tensorflow.python.util import deprecation

deprecation._PRINT_DEPRECATION_WARNINGS = False

[warnings — Warning control]

如何查看TensorFlow中Tensor, Variable, Constant的值?

模型训练完成后,如何获取模型的参数?

通过tf.trainable_variables()得到训练参数

[TensorFlow中遇到的问题及解决方法]

tensorflow创建变量以及根据名称查找变量

[tensorflow创建变量以及根据名称查找变量]

from:-柚子皮-

ref:

我已经用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、付费专栏及课程。

余额充值