【发布时间】:2021-10-12 18:52:02
【问题描述】:
我的数据以 .h5 格式存储。我使用数据生成器来拟合模型,它非常慢。下面提供了我的代码的 sn-p。
def open_data_file(filename, readwrite="r"):
return tables.open_file(filename, readwrite)
data_file_opened = open_data_file(os.path.abspath("../data/data.h5"))
train_generator, validation_generator, n_train_steps, n_validation_steps = get_training_and_validation_generators(
data_file_opened,
......)
地点:
def get_training_and_validation_generators(data_file, batch_size, ...):
training_generator = data_generator(data_file, training_list,....)
data_generator函数如下:
def data_generator(data_file, index_list,....):
orig_index_list = index_list
while True:
x_list = list()
y_list = list()
if patch_shape:
index_list = create_patch_index_list(orig_index_list, data_file, patch_shape,
patch_overlap, patch_start_offset,pred_specific=pred_specific)
else:
index_list = copy.copy(orig_index_list)
while len(index_list) > 0:
index = index_list.pop()
add_data(x_list, y_list, data_file, index, augment=augment, augment_flip=augment_flip,
augment_distortion_factor=augment_distortion_factor, patch_shape=patch_shape,
skip_blank=skip_blank, permute=permute)
if len(x_list) == batch_size or (len(index_list) == 0 and len(x_list) > 0):
yield convert_data(x_list, y_list, n_labels=n_labels, labels=labels, num_model=num_model,overlap_label=overlap_label)
x_list = list()
y_list = list()
add_data()如下:
def add_data(x_list, y_list, data_file, index, augment=False, augment_flip=False, augment_distortion_factor=0.25,
patch_shape=False, skip_blank=True, permute=False):
'''
add qualified x,y to the generator list
'''
# pdb.set_trace()
data, truth = get_data_from_file(data_file, index, patch_shape=patch_shape)
if np.sum(truth) == 0:
return
if augment:
affine = np.load('affine.npy')
data, truth = augment_data(data, truth, affine, flip=augment_flip, scale_deviation=augment_distortion_factor)
if permute:
if data.shape[-3] != data.shape[-2] or data.shape[-2] != data.shape[-1]:
raise ValueError("To utilize permutations, data array must be in 3D cube shape with all dimensions having "
"the same length.")
data, truth = random_permutation_x_y(data, truth[np.newaxis])
else:
truth = truth[np.newaxis]
if not skip_blank or np.any(truth != 0):
x_list.append(data)
y_list.append(truth)
模型训练:
def train_model(model, model_file,....):
model.fit(training_generator,
steps_per_epoch=steps_per_epoch,
epochs=n_epochs,
verbose = 2,
validation_data=validation_generator,
validation_steps=validation_steps)
我的数据集很大:data.h5 为 55GB。完成一个纪元大约需要 7000 秒。并且在 6 个 epoch 之后出现分段错误错误。批量大小设置为 1,否则会出现资源耗尽错误。有没有一种有效的方法来读取生成器中的 data.h5,以便训练更快并且不会导致内存不足错误?
【问题讨论】:
-
.h5 文件有多大?
-
看起来您使用的是 pytables,而不是 h5py。
-
数据集大小为 55GB。数据以 .h5 格式存储为 data.h5。我使用 pytables 打开文件。
-
您在 1 个 epoch 中从 .h5 文件中读取了多少次数据? (多少次调用读取函数?)速度随着 I/O 操作的数量而降低。另外,您是否使用精美的索引?这比简单的切片要慢。
-
@Salmonstrikes 提出了一个关于压缩的好观点——它减慢了 I/O。有时它可能很重要(特别是在更高的压缩级别 - 我只使用 level=1)。解压缩文件并比较性能很容易。 PyTables 有一个
ptrepack实用程序可以做到这一点。这是将数据文件解压缩到新文件的方法:ptrepack --complevel 0 data.h5 data_unc.h5。将代码中数据文件的名称改为data_unc.h5
标签: python generator hdf5 h5py pytables