【发布时间】:2023-04-10 13:57:02
【问题描述】:
我正在处理一个大型数据集,其中有 306400 张图像要处理。
但我要做的事情很简单:调整图像大小,然后写入.TFRecords 文件。
但是,我收到了 out of memory 错误。
由于无法追加.TFRecord文件,我无法多次运行脚本,所以我必须一次写入所有数据。
我尝试使用多个for 循环,因为我认为在每个for 循环之后,使用的内存会被释放,但似乎我错了。
然后我尝试使用iter() 来获取迭代器,因为与dict.iter() 相比,使用dict.iteritems() 的dict 对象可以节省内存。
但没有魔法。
所以现在我不知道如何解决这个问题。
def gen_records(record_name, img_path_file, label_map):
writer = tf.python_io.TFRecordWriter(record_name)
classes = []
with open(label_map, 'r') as f:
for l in f.readlines():
classes.append(l.split(',')[0])
with open(img_path_file, 'r') as f:
lines = f.readlines()
num_images = len(lines)
print 'total number to be written' + str(num_images)
print 'start writing...'
patches = []
with open(img_path_file, 'r') as f:
for patch in f.readlines():
patches.append(patch[:-1])
cnt = 0
for patch in patches:
cnt += 1
# print '[' + str(cnt) + ' / ' + str(num_images) + ']' + 'writing ' + str()
img = tf.image.resize_images(np.array(Image.open(patch)), (224, 224), method=tf.image.ResizeMethod.BILINEAR)
img_raw = np.array(img).tostring()
label = classes.index(patch.split('/')[1])
example = tf.train.Example(features=tf.train.Features(feature={
'label': _int64_feature(int(label)),
'image': _bytes_feature(img_raw)
}))
writer.write(example.SerializeToString())
writer.close()
如何在每次迭代后“释放”使用的内存?或者我怎样才能节省内存?
【问题讨论】:
-
第 55 行对
iter的调用是不必要的,并且根本不安全内存,因为原始列表仍然存在。您可以改为定义一个生成补丁的生成器。 -
问题可能是您尝试将所有 306400 张图片加载到内存中,以便通过一次调用
write来保存它们。这意味着即使每张图片只有 100 KB 大小,您也需要超过 30 GB 的工作内存。该错误表明您的内存对于您的数据集来说太小了。 -
我编辑了代码并尝试在每个循环中执行
write,但仍然使用的内存不断增加。问题是,我认为如果我使用for循环,那么每个图像都会被打开和处理,并且在下一个循环中,使用的内存将被自动清理,但它不会。有什么方法可以单独加载图片吗? -
@MaxPowers 另外,在编辑的代码中,每次循环都要重新分配变量,那么巨大的已用内存属于哪里?
-
吞噬你记忆的是
tensorflow,而不是你的Python代码。您必须更深入地研究该模块才能找出这里没有释放内存的原因,我的赌注是tf.python_io.TFRecordWriter。
标签: python for-loop memory tensorflow iterator