python - 加载具有各种数据类型的字典列表时出现 EOFError
问题描述
我有字典列表,其中每个字典包含多个不同的项目。它在强化学习的训练过程中用作记忆回放,我需要创建一个备份文件以防万一该过程中断。每个 dict 代表一个环境步骤,因此结构相同,只有值不同。
每个 dict 包含的数据类型是:numpy.array、int、bool、string、 numpy 数组列表和float。Np 数组经过预处理,因此它确实包含实数浮点数 - 没有 NaN 或 Inf。
我的问题是,我尝试了多种方法,如何存储和加载文件,并且所有文件的行为都相似 - 备份创建没有问题,但有时(甚至根本没有 - 加载时根本没有发现其他地方错误的模式)它,它引发了EOFError。
列表中的最大数据量现在限制为 100k,创建的文件通常在 128MB 左右。
目前我正在通过pickle.dumps尝试它,但过去我尝试过简单的joblib转储/加载和copy.deepcopy来转储。
def _save_backup(self, path:str, name:str) -> dict:
file_path = path+name+'_memory.joblib'
with open(file_path, "wb") as f:
serialized_mem = pickle.dumps(self._memory,protocol=pickle.HIGHEST_PROTOCOL)
dump(serialized_mem,f)
return {'memory':file_path}
def _load_backup(self, data:dict):
if os.path.exists(data['memory']):
with open(data['memory'], "rb") as f:
serialized_mem = load(f)
self._memory = pickle.loads(serialized_mem)
编辑
回答tdelaney评论:
- load 和 dump 来自 joblib
from joblib import dump, load
import pickle
想法是通过pickle.dumps将对象序列化为字符串,因为它只创建字符串但不保存到文件中,然后我使用joblib.dump创建这样的文件。
确实引发了错误
serialized_mem = load(f)
保存期间不抑制任何异常
转储后,文件路径作为dict(以保持基类的继承)传递给主类,并与其他备份文件路径合并,如神经网络、优化器等。
错误文件大小不是确定性的 - 有时它在列表达到其全部容量(100k 个样本)之前失败,然后它的 ofc 更小,有时错误发生在例如 500k 步之后,所以大小是正常的。但是你让我记住了一个非常重要的细节......
self._memory
实际上是deque (from collections import deque
) 类型(它继承自父级并允许像使用列表一样使用它,这就是我忘记它的原因)。作为双端队列,保存“未满”对象可能会出现问题,这可以解释 EOFError 的含义。我会做一些测试并报告结果。
解决方案
几天没有错误,所以我猜它已修复。最后我使用了一些不同的东西,因为我MemoryError
在保存过程中体验到在 32GB RAM 上运行 64 位 python 版本,其中一半以上可用。
这个实现似乎解决了加载MemoryError
和EOFError
加载时
def save_backup(self, path:str, name:str) -> dict:
# save memory
file_path = path+name+'_memory.joblib'
with open(file_path, "wb") as f:
for data in list(self._memory):
pickle.dump(data,f)
# save other files
d = self._save_backup(path,name) # child class method
# merge dicts
d.update({'memory':file_path})
return d
def load_backup(self, data:dict):
# load memory
if os.path.exists(data['memory']):
with open(data['memory'], "rb") as f:
self._memory.clear()
while True:
try:
self._memory.append(pickle.load(f))
except EOFError:
break
# load others
self._load_backup(data) # child class method
推荐阅读
- git - 使用启动脚本克隆私有 Github 存储库?
- amazon-cognito - AWS Cognito:您应该为 UID 创建自定义属性吗?
- asp.net-core - EF Core 不会按顺序创建子实体
- javascript - Discord.js 使用来自其他消息的附件来更新嵌入中的图像
- unit-testing - spock中不可预测的存根初始化
- oracle-apex - 项目值更改时在新选项卡中调用页面
- python - 没有这样的文件或目录:'tree2.txt'
- node.js - 集合中每个 mongo 文档的 Elasticsearch 和 MongoDB n-gram 索引
- jupyter-notebook - 如何在 Jupyter Notebook 中禁用工具提示建议
- amazon-web-services - AWS CDK 事件桥和 api 网关 AWS 示例不起作用