我有一个在大型数据集上运行的模型-并非按大数据标准那么大,但是远远超出了我的家庭服务器可以容纳的内存。因此,我正在使用fit_generator
一次加载一个块,因此它永远不必一次在内存中保留一个以上的小批处理。
...至少,这是理论。但是,当Keras甚至没有开始“训练”动画就挂在Epoch 1/10
上时,我(最终)遇到了Out of Memory异常-迷你批处理很大,但我仍然可以一次将其中几个存储在内存中而没有麻烦-我变得可疑,并在生成器中加入了一系列测试print
语句。瞧,Keras甚至在启动之前(似乎要启动?)调用了发电机三到四次。
那么...这是怎么回事?这是正常现象,还是我以某种方式实现生成器错误?我该如何避免一次加载多个批处理?
下面的代码可以帮助您:
def data_gen(directory):
def epsilon_div(x, y):
return (x + K.epsilon()) / (y + K.epsilon())
while(True):
filelist = os.listdir(directory + "/data")
order = np.random.permutation(len(filelist))
for i in order:
dataf = directory + "/data/" + filelist[i]
labelf = directory + "/labels/" + filelist[i]
with open(dataf, 'rb') as f:
databook = sb.Songbook.FromString(f.read())
with open(labelf, 'rb') as f:
labelbook = sb.Songbook.FromString(f.read())
print('Booked')
l, _, r, _ = sb_np_extract(databook)
ll, _, lr, _ = sb_np_extract(labelbook)
databook = None
labelbook = None
print('Extracted')
l = l.transpose([0, 2, 1])
r = r.transpose([0, 2, 1])
ll = ll.transpose([0, 2, 1])
lr = lr.transpose([0, 2, 1])
print('Chosen')
mask_l = epsilon_div(ll, l)
mask_r = epsilon_div(lr, r)
print('Done')
yield [[l, r], [mask_l, mask_r]]
答案 0 :(得分:0)
我建议您将文件名保存在一个数组中,然后将其随机播放。我用完整路径调用文件列表,并分别打乱listname_data
和listname_labels
。
步骤=文件数
def生成器(步骤):
i = 1
while True:
dataf = filelist_data[i]
labelf = filelist_labels[i]
...
if i == steps:
i = 1
c = list(zip(listname_data,listname_data))
shuffle(c)
listname_data, listname_data = zip(*c)
else:
i +=1
yield [[l, r], [mask_l, mask_r]]