为什么酸洗张量流张量失败?

时间:2017-05-03 20:26:22

标签: python tensorflow pickle dill

以下是使用dill成功序列化的代码段,但pickle失败。令人惊讶的是,Tensor对象本身不可拾取。这是线程感知Tensors的基本限制,还是只是没有实现?

import dill
import pickle
import tensorflow as tf

dill.dumps(tf.zeros((1,1)))
print("Dill succeeded")
pickle.dumps(tf.zeros((1,1)))
print("Pickle succeeded")

输出:

$ python foo.py
Dill succeeded
Traceback (most recent call last):
  File "foo.py", line 7, in <module>
    pickle.dumps(tf.zeros((1,1)))
TypeError: can't pickle _thread.lock objects

2 个答案:

答案 0 :(得分:2)

简单回答是pickle无法序列化python中的大多数对象,包括thread.lock对象。如果要序列化其中一个对象,请使用高级序列化库,如dill。至于为什么pickle不可能,我认为最初它源于GIL的实现和frame对象呈现一些不可序列化的对象,因此没有驱动器序列化语言中的所有内容。一直都在讨论源于所有python对象序列化的安全问题,但我认为这是一个红色的鲱鱼。没有完整的语言序列化限制了在并行计算中运行的能力,因此希望pickle将从dill学习如何序列化更多对象。

答案 1 :(得分:0)

我发现我无法再现eqzx's脚本的输出,并且dillpickle的序列化均失败。

虽然这个问题已有好几年了,但我认为问题并不在于泡菜,而是在于不会立即评估tensorflow 1.x中的张量的事实。而是在执行其图形时对它们进行评估。 (在tensorflow 2.0中,默认情况下急切执行是启用的,因此您实际上不必处理这种范例。)

使用tf.enable_eager_execution()或在tf.Session()上下文中评估张量

使用Pickle或Dill时,以下脚本不会引发错误:

import tensorflow as tf
tf.enable_eager_execution()
import pickle 
# import dill

n = tf.zeros((1,1))
pickle.dumps(n)
# dill.dumps(n)

print('Success')

使用Session.run()的相同脚本不会引发错误:

import tensorflow as tf
import pickle
# import dill

with tf.Session() as sess:
    n = sess.run(tf.zeros((1,1)))
pickle.dumps(n)
# dill.dumps(n)

print('Success')