2015-07-27 14 views
6

Tạo các tập dữ liệu để đào tạo với Caffe Tôi đã thử sử dụng HDF5 và LMDB. Tuy nhiên, việc tạo một LMDB rất chậm thậm chí còn chậm hơn HDF5. Tôi đang cố gắng viết ~ 20.000 hình ảnh.Ghi dữ liệu vào LMDB bằng Python rất chậm

Tôi đang làm điều gì đó khủng khiếp sai? Có điều gì tôi không biết?

Đây là mã của tôi để tạo 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() 

Như bạn có thể thấy tôi đang tạo ra một giao dịch cho mỗi 1.000 hình ảnh, bởi vì tôi nghĩ rằng việc tạo ra một giao dịch cho mỗi hình ảnh sẽ tạo ra một chi phí, nhưng có vẻ như điều này không ảnh hưởng đến hiệu suất quá nhiều.

+0

tại sao bạn không sử dụng [ 'convert_imageset'] (http://stackoverflow.com/a/31431716/1714410) công cụ? – Shai

+0

@Shai: Thực ra tôi không biết, nhưng tôi cũng không có hình ảnh của tôi dưới dạng tệp. Mặc dù, tại sao nó phải nhanh hơn? Việc triển khai Python có chậm không? – Simikolon

+0

Tôi đang làm việc với 'convert_imageset' để woek trên ilsvrc12 (imagenet) chuyển đổi tập dữ liệu của ~ 1M hình ảnh, phải mất một lúc nhưng nó hoạt động. – Shai

Trả lời

3

Hãy thử điều này:

DB_KEY_FORMAT = "{:0>10d}" 
db = lmdb.open(path, map_size=int(1e12)) 
    curr_idx = 0 
    commit_size = 1000 
    with in_db_data.begin(write=True) as in_txn: 
     for curr_commit_idx in range(0, num_data, commit_size): 
      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() 

with in_db_data.begin(write=True) as in_txn: 

mất nhiều thời gian.

6

Theo kinh nghiệm của tôi, tôi đã có 50-100 ms ghi vào LMDB từ Python ghi dữ liệu Caffe trên đĩa cứng ext4 trên Ubuntu. Đó là lý do tại sao tôi sử dụng tmpfs (đĩa RAM chức năng được tích hợp trong Linux) và nhận các ghi này được thực hiện trong khoảng 0,07 ms. Bạn có thể tạo các cơ sở dữ liệu nhỏ hơn trên đĩa RAM của bạn và sao chép chúng vào một đĩa cứng và sau đó đào tạo trên tất cả chúng. Tôi đang làm cho khoảng 20-40GB những người như tôi có 64 GB RAM.

Một số đoạn mã để giúp các bạn tự động tạo, điền và di chuyển LMDB để lưu trữ. Vui lòng chỉnh sửa nó để phù hợp với trường hợp của bạn. Nó sẽ giúp bạn tiết kiệm một số thời gian nhận được đầu của bạn xung quanh cách LMDB và thao tác tập tin hoạt động trong 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()) 
+1

Bạn có thể cung cấp thêm một chút ngữ cảnh 'tempfs' là gì không? –

+0

Bạn có thể vui lòng cung cấp mã cụ thể mô tả giải pháp/quy trình làm việc của mình không? – Shai

+2

Đây là một gợi ý tuyệt vời! @SteveHeim Xem [bài đăng này] (http://askubuntu.com/questions/152868/how-do-i-make-a-ram-disk) để biết chi tiết về cách tạo đĩa RAM trong Ubuntu. Thay vì ghi dữ liệu vào một đĩa cứng, điều này có thể rất chậm khi một số lượng lớn các bản ghi được tham gia, bạn có thể gắn một thư mục vào một vị trí RAM.Trong khi giao diện cũng giống như bất kỳ thư mục nào khác, quyền truy cập đọc và ghi vào thư mục được gắn sẽ là các đơn đặt hàng có cường độ nhanh hơn. Khi bạn hoàn tất việc sử dụng cơ sở dữ liệu của mình, bạn có thể chuyển nó sang một thư mục khác trên đĩa cứng để lưu trữ lâu dài. – Jake

0

viết LMDB rất nhạy cảm để đặt hàng - Nếu bạn có thể sắp xếp các dữ liệu trước khi tốc độ chèn sẽ cải thiện đáng kể

Các vấn đề liên quan