以下是使用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
答案 0 :(得分:2)
简单回答是pickle
无法序列化python中的大多数对象,包括thread.lock
对象。如果要序列化其中一个对象,请使用高级序列化库,如dill
。至于为什么pickle
不可能,我认为最初它源于GIL的实现和frame
对象呈现一些不可序列化的对象,因此没有驱动器序列化语言中的所有内容。一直都在讨论源于所有python对象序列化的安全问题,但我认为这是一个红色的鲱鱼。没有完整的语言序列化限制了在并行计算中运行的能力,因此希望pickle
将从dill
学习如何序列化更多对象。
答案 1 :(得分:0)
我发现我无法再现eqzx's脚本的输出,并且dill
和pickle
的序列化均失败。
虽然这个问题已有好几年了,但我认为问题并不在于泡菜,而是在于不会立即评估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')