我已经为机器学习项目创建了一个将图像映射到其标签的数据集。我想将数据集保存在一个脚本中并将其加载到另一个脚本中,以便每次重新运行模型代码时节省时间。 数据集的输出为我提供了一个元组列表,其中包含一个 ImagingCore 对象和 2 个字符串类型对象。
print(dataset)
的输出是
[(<ImagingCore object at 0x12091a825>, 'R', 'FIRST'),(<ImagingCore object at 0x12091a850>, 'L', 'THIRD'),...]
每个元组的第二个元素要么是左要么是右,第三个元素从第一个到第四个。
我尝试使用以下结构保存带有 pickle、json、dill、hickle 的数据集
with open('data.pickle', 'wb') as f:
pickle.dump(dataset, f)
但我总是遇到同样的错误:
类型错误:无法腌制“ImagingCore”对象
有人可以帮忙吗?这几周来真的让我发疯
该错误告诉我 PIL 的对象不可 pickle。它们是本机对象(就像 C 而不是 Python 代码),因此它们不自动支持 pickling 是有道理的。您可以pickle 一组不同的数据(代理对象)或使用自定义Pickler 来支持pickle 其数据。
请参阅 Pickleable Image Object 问题,了解如何从
PIL.Image
中提取可以 进行腌制的数据。
展示了如何编写自己的pickler。看起来代码应该是这样的(未经测试):
pickle
我认为您的
import pickle
from PIL import Image # Assuming Pillow
from collections import namedtuple
# Proxy the PIL.Image by storing the bytes.
ImageProxy = namedtuple("ImageProxy", "pixels, size, mode")
class PilPickler(pickle.Pickler):
def persistent_id(self, obj):
if isinstance(obj, Image):
# Create our proxy that (I think) will get pickled in lieu of a PIL object.
return ImageProxy(
pixels=obj.tobytes(),
size=obj.size,
mode=obj.mode,
)
else:
# Fallback to default pickle.
return None
class PilUnpickler(pickle.Unpickler):
def persistent_load(self, pid):
# pid is the object returned by PilPickler.
if isinstance(pid, ImageProxy):
return Image.frombytes(pid.mode, pid.size, pid.pixels)
else:
# Always raise an error if you cannot return the correct object.
raise pickle.UnpicklingError("unsupported persistent object")
def main():
import io
import pprint
images = [] # [... make images here ...]
# Save the records using our custom PilPickler.
file = io.BytesIO()
PilPickler(file).dump(images)
print("Pickled records:")
pprint.pprint(images)
# Load the records from the pickle data stream.
file.seek(0)
images = PilUnpickler(file).load()
print("Unpickled records:")
pprint.pprint(images)
if __name__ == "__main__":
main()
是
ImagingCore
的本机部分,因此此自定义 Pickler 解决方案允许您保留现有设置,并且数据结构内的任何 PIL.Image
都将被腌制。如果您正在使用其他 PIL.Image
对象,您可能需要通过更多 PIL
检查和代理对象来添加对它们的支持。