[英]EOFError when loading list of dicts with various datatypes
我有字典列表,其中每個字典包含多個不同的項目。 它在強化學習的訓練過程中用作記憶重放,我需要創建一個備份文件,以防該過程中斷。 每個字典代表一個環境步驟,因此結構相同,只有值不同。
每個 dict 包含的數據類型是: numpy.array、int、bool、string、 numpy 數組列表和float 。 Np 數組經過預處理,因此它確實包含真正的浮點數 - 沒有 NaN 或 Inf。
我的問題是,我嘗試了多種方法,如何存儲和加載文件,並且所有文件的行為都相似 - 創建備份沒有問題,但有時(甚至根本沒有 - 根本沒有模式可以在其他地方發現錯誤)加載時它,它會引發 EOFError。
列表中的最大數據量現在限制為 100k,創建的文件通常約為 128MB。
目前我正在通過 pickle.dumps 嘗試它,但在過去我嘗試過普通的 joblib dump/load 和 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評論:
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 的含義。 我會做一些測試並報告結果。
幾天沒有錯誤,所以我想它是固定的。 最后我使用了一些不同的東西,因為在 32GB RAM 上運行 64 位 python 版本時,我在保存過程中遇到了MemoryError
,其中一半以上可以使用。
這個實現似乎解決了加載時的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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.