创建数据集进行Caffe训练我都尝试使用HDF5和LMDB。但是,创建LMDB非常慢,甚至比HDF5还慢。我正在尝试写约20,000张图片。
我做错什么了吗?有我不知道的事吗?
这是我创建LMDB的代码:
DB_KEY_FORMAT = "{:0>10d}"
db = lmdb.open(path, map_size=int(1e12))
curr_idx = 0
commit_size = 1000
for curr_commit_idx in range(0, num_data, commit_size):
with in_db_data.begin(write=True) as in_txn:
for i in range(curr_commit_idx, min(curr_commit_idx + commit_size, num_data)):
d, l = data[i], labels[i]
im_dat = caffe.io.array_to_datum(d.astype(float), label=int(l))
key = DB_KEY_FORMAT.format(curr_idx)
in_txn.put(key, im_dat.SerializeToString())
curr_idx += 1
db.close()
如您所见,我正在为每1,000个图像创建一个事务,因为我认为为每个图像创建一个事务会产生开销,但这似乎并不会对性能产生太大影响。
最佳答案
以我的经验,我曾经从Python的到LMDB的 50-100毫秒的写入中,在Ubuntu的ext4硬盘上写入Caffe数据。 这就是为什么我使用tmpfs (Linux内置的 RAM磁盘功能)并在 0.07 ms 左右完成这些写入的原因。您可以在虚拟磁盘上创建较小的数据库,然后将它们复制到硬盘上,然后在所有数据库上进行训练。我有大约20-40GB的存储空间,因为我有64 GB的RAM。
一些代码段可帮助您动态创建,填充LMDB并将其移动到存储中。随时对其进行编辑以适合您的情况。它应该为您节省一些时间来了解LMDB和Python的工作方式。import shutil
import lmdb
import random
def move_db():
global image_db
image_db.close();
rnd = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(5))
shutil.move( fold + 'ram/train_images', '/storage/lmdb/'+rnd)
open_db()
def open_db():
global image_db
image_db = lmdb.open(os.path.join(fold, 'ram/train_images'),
map_async=True,
max_dbs=0)
def write_to_lmdb(db, key, value):
"""
Write (key,value) to db
"""
success = False
while not success:
txn = db.begin(write=True)
try:
txn.put(key, value)
txn.commit()
success = True
except lmdb.MapFullError:
txn.abort()
# double the map_size
curr_limit = db.info()['map_size']
new_limit = curr_limit*2
print '>>> Doubling LMDB map size to %sMB ...' % (new_limit>>20,)
db.set_mapsize(new_limit) # double it
...
image_datum = caffe.io.array_to_datum( transformed_image, label )
write_to_lmdb(image_db, str(itr), image_datum.SerializeToString())