У меня есть список диктов, где каждый дикт содержит несколько разных предметов. Он используется в качестве воспроизведения памяти в процессе обучения обучению подкреплению, и мне нужно создать файл резервной копии на случай, если что-то прервет этот процесс. Каждый dict представляет один шаг среды, поэтому структура одинакова, отличаются только значения.
Типы данных, которые содержит каждый dict: numpy .array, int, bool, string, list из numpy массивов и float . Массив Np предварительно обработан, поэтому он содержит реальные числа с плавающей точкой - без NaN или Inf.
Моя проблема в том, что я пробовал несколько способов, как хранить и загружать файлы, и все они вели себя одинаково - резервное копирование создано без проблем, но иногда (или даже не совсем - просто без шаблона, чтобы обнаружить ошибку в другом месте) при загрузке это вызывает EOFError.
Максимальный объем данных в списке теперь ограничен 100 КБ, и созданный файл обычно около 128 МБ.
В настоящее время я пытаюсь сделать это с помощью 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 комментарий:
- загрузка и выгрузка из joblib
from joblib import dump, load
import pickle
Идея заключалась в том, чтобы сериализовать объект в строку с помощью pickle.dumps, и поскольку он только создает строку, но не сохраняет в файл, я затем использую joblib.dump для создания такого файла.
ошибка действительно возникает в serialized_mem = load(f)
* 1 038 *
Никакие исключения не подавляются при сохранении
после дампа filepath передается как dict (для сохранения наследования базового класса) в основной класс и объединяется с другими путями файлов резервных копий, такими как нейронная сеть, оптимизатор и т. д. c.
Размер файла ошибки не определен c - иногда происходит сбой до того, как список достигает полной емкости (100k образцов), а затем его c меньше, и иногда возникает ошибка, например, после 500 тыс. шагов, поэтому размер нормальный Но вы заставили меня вспомнить довольно важную деталь ... на самом деле self._memory
имеет тип deque (from collections import deque
) (он унаследован от parent и позволяет работать с ним как со списком, поэтому Я забыл об этом). И в качестве deque это может быть проблема с сохранением «недопустимого» объекта, что объясняет значение EOFError. Я сделаю несколько тестов и сообщу результат.