You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需安装Caffe,在Python中创建LMDB的其他方法

Great question! You're totally right—installing Caffe just for that Datum protobuf is overkill. Here are some clean, framework-agnostic ways to create LMDB databases in Python without relying on Caffe:

1. Use Python's built-in pickle for serialization

Pickle is the easiest drop-in replacement since it’s part of Python’s standard library. It lets you serialize almost any Python object (numpy arrays, tuples of data/labels, etc.) into bytes, which you can write directly to LMDB.

Pros: No extra dependencies, works with any Python object.
Cons: Pickle files are Python-specific, so other languages might have trouble reading them. Also, not the most space-efficient for large datasets.

Here’s a quick example:

import lmdb
import pickle
import numpy as np

# Initialize LMDB environment (adjust map_size based on your dataset size)
env = lmdb.open('my_lmdb', map_size=1024*1024*1024)  # 1GB map size

# Write data to LMDB
with env.begin(write=True) as txn:
    for idx in range(100):
        # Sample data: 3-channel image tensor + label
        data = np.random.rand(3, 224, 224)
        label = idx % 10
        # Serialize the data-label tuple
        serialized = pickle.dumps((data, label))
        # Write to LMDB with a padded string key (ensures consistent key length)
        txn.put(f'{idx:08d}'.encode(), serialized)

# Read data back from LMDB
with env.begin() as txn:
    cursor = txn.cursor()
    for key, value in cursor:
        data, label = pickle.loads(value)
        print(f'Key: {key.decode()}, Label: {label}, Data shape: {data.shape}')

env.close()

2. Define your own lightweight Protobuf schema

If you want a language-agnostic, efficient serialization format (like Caffe’s Datum but without the Caffe dependency), you can create your own minimal Protobuf schema. This is a great middle ground between pickle and heavyweight framework-specific tools.

First, create a custom_datum.proto file:

syntax = "proto3";

message CustomDatum {
  optional int32 channels = 1;
  optional int32 height = 2;
  optional int32 width = 3;
  optional bytes data = 4;  # Raw byte array (e.g., numpy array converted to bytes)
  optional int32 label = 5;
}

Generate the Python code using the protobuf compiler (install first with pip install protobuf):

protoc --python_out=. custom_datum.proto

Now use it in your LMDB code:

import lmdb
import numpy as np
from custom_datum_pb2 import CustomDatum

env = lmdb.open('custom_lmdb', map_size=1024*1024*1024)

# Write data
with env.begin(write=True) as txn:
    for idx in range(100):
        data = np.random.randint(0, 255, (3, 224, 224), dtype=np.uint8)
        label = idx % 10
        
        datum = CustomDatum()
        datum.channels = 3
        datum.height = 224
        datum.width = 224
        datum.data = data.tobytes()
        datum.label = label
        
        txn.put(f'{idx:08d}'.encode(), datum.SerializeToString())

# Read data
with env.begin() as txn:
    cursor = txn.cursor()
    for key, value in cursor:
        datum = CustomDatum()
        datum.ParseFromString(value)
        data = np.frombuffer(datum.data, dtype=np.uint8).reshape(datum.channels, datum.height, datum.width)
        print(f'Key: {key.decode()}, Label: {datum.label}, Data shape: {data.shape}')

env.close()

3. Store raw NumPy bytes (for numerical data)

If you’re working exclusively with numpy arrays, you can skip serialization libraries altogether and write the raw bytes of the array directly to LMDB. This is super fast and space-efficient.

import lmdb
import numpy as np

env = lmdb.open('numpy_lmdb', map_size=1024*1024*1024)

# Write data: store array bytes and label as separate entries
with env.begin(write=True) as txn:
    for idx in range(100):
        data = np.random.rand(3, 224, 224).astype(np.float32)
        label = idx % 10
        # Store data and label with paired keys
        txn.put(f'data_{idx:08d}'.encode(), data.tobytes())
        txn.put(f'label_{idx:08d}'.encode(), np.int32(label).tobytes())

# Read data
with env.begin() as txn:
    for idx in range(100):
        data_bytes = txn.get(f'data_{idx:08d}'.encode())
        label_bytes = txn.get(f'label_{idx:08d}'.encode())
        
        data = np.frombuffer(data_bytes, dtype=np.float32).reshape(3, 224, 224)
        label = np.frombuffer(label_bytes, dtype=np.int32)[0]
        print(f'Idx: {idx}, Label: {label}, Data shape: {data.shape}')

env.close()

4. Store compressed image bytes (for image datasets)

If your data is images, save space by storing them in compressed formats (JPEG/PNG) instead of raw tensors. Use PIL/Pillow to handle encoding and decoding.

import lmdb
from PIL import Image
import numpy as np

env = lmdb.open('image_lmdb', map_size=1024*1024*1024)

# Write compressed images
with env.begin(write=True) as txn:
    for idx in range(100):
        # Create a sample RGB image (or load from disk with Image.open())
        img_array = np.random.randint(0, 255, (224, 224, 3), dtype=np.uint8)
        img = Image.fromarray(img_array)
        label = idx % 10
        
        # Encode image to JPEG bytes (adjust quality as needed)
        img_bytes = img.tobytes(format='JPEG', quality=90)
        
        # Store image and label
        txn.put(f'img_{idx:08d}'.encode(), img_bytes)
        txn.put(f'label_{idx:08d}'.encode(), np.int32(label).tobytes())

# Read and decode images
with env.begin() as txn:
    for idx in range(100):
        img_bytes = txn.get(f'img_{idx:08d}'.encode())
        label_bytes = txn.get(f'label_{idx:08d}'.encode())
        
        img = Image.frombytes('RGB', (224, 224), img_bytes, 'JPEG')
        label = np.frombuffer(label_bytes, dtype=np.int32)[0]
        print(f'Idx: {idx}, Label: {label}, Image size: {img.size}')

env.close()

内容的提问来源于stack exchange,提问作者Sean Saito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:59:06