Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?

Nếu bạn đang sử dụng matplotlib và đang cố gắng để có được số liệu tốt trong một tài liệu latex, hãy lưu dưới dạng EPS. Cụ thể, hãy thử một cái gì đó như thế này sau khi chạy các lệnh để vẽ hình ảnh:

plt.savefig('destination_path.eps', format='eps')

Tôi đã thấy rằng các tệp EPS hoạt động tốt nhất và tham số

import numpy as np
import pickle
from pathlib import Path

# Path to the unzipped CIFAR data
data_dir = Path("data/cifar-10-batches-py/")

# Unpickle function provided by the CIFAR hosts
def unpickle(file):
    with open(file, "rb") as fo:
        dict = pickle.load(fo, encoding="bytes")
    return dict

images, labels = [], []
for batch in data_dir.glob("data_batch_*"):
    batch_data = unpickle(batch)
    for i, flat_im in enumerate(batch_data[b"data"]):
        im_channels = []
        # Each image is flattened, with channels in order of R, G, B
        for j in range(3):
            im_channels.append(
                flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
            )
        # Reconstruct the original image
        images.append(np.dstack((im_channels)))
        # Save the label
        labels.append(batch_data[b"labels"][i])

print("Loaded CIFAR-10 training set:")
print(f" - np.shape(images)     {np.shape(images)}")
print(f" - np.shape(labels)     {np.shape(labels)}")
9 là điều thực sự làm cho chúng trông tốt trong một tài liệu.

Để chỉ định hướng của hình trước khi lưu, chỉ cần gọi theo sau cuộc gọi

$ conda install -c conda-forge pillow
0, nhưng sau khi tạo sơ đồ (giả sử bạn đã vẽ bằng cách sử dụng một trục có tên
$ conda install -c conda-forge pillow
1):

ax.view_init(elev=elevation_angle, azim=azimuthal_angle)

Trong đó

$ conda install -c conda-forge pillow
2 là một số (tính bằng độ) chỉ định góc cực (xuống từ trục z dọc) và
$ conda install -c conda-forge pillow
3 chỉ định góc phương vị (xung quanh trục z).

Tôi thấy rằng việc xác định các giá trị này là dễ dàng nhất bằng cách vẽ hình ảnh trước tiên và sau đó xoay nó và xem các giá trị hiện tại của các góc xuất hiện ở dưới cùng của cửa sổ ngay bên dưới cốt truyện thực tế. Hãy nhớ rằng các vị trí X, Y, Z, xuất hiện theo mặc định, nhưng chúng được thay thế bằng hai góc khi bạn bắt đầu nhấp vào+kéo+xoay hình ảnh.

Xem thảo luận

Cải thiện bài viết

Lưu bài viết

  • Đọc
  • Bàn luận
  • Xem thảo luận

    Cải thiện bài viết

    Lưu bài viết

    Điều kiện tiên quyết: Gối Python Python pillow

    PIL là thư viện hình ảnh Python cung cấp cho trình thông dịch Python một hỗ trợ định dạng tệp chuyên sâu, biểu diễn nội bộ hiệu quả và khả năng xử lý hình ảnh khá mạnh mẽ. Thay đổi độ phân giải của hình ảnh chỉ đơn giản là giảm hoặc tăng số lượng pixel trong hình ảnh, mà không thay đổi kích thước của nó hoặc bất kỳ yếu tố nào khác. Trong bài viết này, chúng tôi sẽ tìm hiểu các phương pháp làm thế nào để thay đổi chất lượng/độ phân giải của hình ảnh với sự trợ giúp của thư viện Python Pil (gối).

    Thay đổi độ phân giải hình ảnh

    Sử dụng tham số chất lượng:

    Chất lượng hình ảnh là một thang đo để đo lường và lưu trữ độ phân giải của một hình ảnh. Nó nằm trong phạm vi từ 0 đến 100 trong đó 95 được coi là tốt nhất vì 100 lần vô hiệu hóa một số phần của thuật toán nén JPEG dẫn đến các tệp rất lớn. Mặt khác, mức tăng về chất lượng hoặc độ phân giải hình ảnh cũng không đáng kể từ 95 đến 100. Chức năng có thể đạt được bằng các bước sau:

    1. Nhập mô -đun hình ảnh từ gối.
    2. Mở hình ảnh bằng phương thức .Open () bằng cách chỉ định đường dẫn hình ảnh.
    3. Phương thức Image_File.Save () có một tham số có tên chất lượng, chỉ định độ phân giải của hình ảnh theo tỷ lệ 1-100, trong đó 95 được coi là chất lượng tối ưu.

    Program:

    Python3

    $ conda install -c conda-forge pillow
    
    4
    $ conda install -c conda-forge pillow
    
    5
    $ conda install -c conda-forge pillow
    
    6
    $ conda install -c conda-forge pillow
    
    7

    $ conda install -c conda-forge pillow
    
    8
    $ conda install -c conda-forge pillow
    
    9
    $ conda install -c conda-forge python-lmdb
    
    0

    $ conda install -c conda-forge python-lmdb
    
    1
    $ conda install -c conda-forge pillow
    
    9
    $ conda install -c conda-forge python-lmdb
    
    3
    $ conda install -c conda-forge python-lmdb
    
    4
    $ conda install -c conda-forge python-lmdb
    
    5

    $ conda install -c conda-forge python-lmdb
    
    6
    $ conda install -c conda-forge python-lmdb
    
    7
    $ conda install -c conda-forge python-lmdb
    
    8
    $ conda install -c conda-forge pillow
    
    9
    $ conda install -c conda-forge h5py
    
    0
    $ conda install -c conda-forge h5py
    
    1

    $ conda install -c conda-forge python-lmdb
    
    6
    $ conda install -c conda-forge h5py
    
    3
    $ conda install -c conda-forge python-lmdb
    
    8
    $ conda install -c conda-forge pillow
    
    9
    $ conda install -c conda-forge h5py
    
    6
    $ conda install -c conda-forge h5py
    
    1

    $ conda install -c conda-forge python-lmdb
    
    6
    $ conda install -c conda-forge h5py
    
    9
    $ conda install -c conda-forge python-lmdb
    
    8
    $ conda install -c conda-forge pillow
    
    9
    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    2
    $ conda install -c conda-forge h5py
    
    1

    Ảnh gốc:

    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?

    Output:

    Độ phân giải mặc định/cao (chất lượng = 95):

    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?

    Độ phân giải trung bình (chất lượng = 25):

    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?

    Độ phân giải thấp (chất lượng = 1):

    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?

    Tại sao bạn muốn biết thêm về các cách lưu trữ và truy cập hình ảnh khác nhau trong Python? Nếu bạn phân đoạn một số ít hình ảnh theo màu sắc hoặc phát hiện các đối mặt từng người một bằng OpenCV, thì bạn không cần phải lo lắng về nó. Ngay cả khi bạn sử dụng Thư viện hình ảnh Python (PIL) để vẽ trên vài trăm ảnh, bạn vẫn không cần. Lưu trữ hình ảnh trên đĩa, dưới dạng tệp

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4 hoặc
    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    5, vừa phù hợp và phù hợp.

    Tuy nhiên, ngày càng nhiều hình ảnh cần thiết cho một nhiệm vụ nhất định ngày càng lớn hơn. Các thuật toán như mạng thần kinh tích chập, còn được gọi là Convnets hoặc CNN, có thể xử lý các bộ dữ liệu hình ảnh khổng lồ và thậm chí học hỏi từ chúng. Nếu bạn quan tâm, bạn có thể đọc thêm về cách sử dụng Convnets để xếp hạng ảnh tự sướng hoặc phân tích tình cảm.

    ImageNet là một cơ sở dữ liệu hình ảnh công cộng nổi tiếng được kết hợp cho các mô hình đào tạo về các nhiệm vụ như phân loại đối tượng, phát hiện và phân đoạn và nó bao gồm hơn 14 triệu hình ảnh.

    Hãy suy nghĩ về việc mất bao lâu để tải tất cả vào bộ nhớ để đào tạo, theo các đợt, có lẽ hàng trăm hoặc hàng ngàn lần. Hãy tiếp tục đọc, và bạn sẽ bị thuyết phục rằng sẽ mất khá nhiều thời gian, ít nhất là đủ lâu để rời khỏi máy tính của bạn và làm nhiều việc khác trong khi bạn muốn bạn làm việc tại Google hoặc Nvidia.

    Trong hướng dẫn này, bạn sẽ tìm hiểu về:

    • Lưu trữ hình ảnh trên đĩa dưới dạng tệp
      from pathlib import Path
      
      disk_dir = Path("data/disk/")
      lmdb_dir = Path("data/lmdb/")
      hdf5_dir = Path("data/hdf5/")
      
      4
    • Lưu trữ hình ảnh trong cơ sở dữ liệu ánh xạ bộ nhớ sét (LMDB)
    • Lưu trữ hình ảnh ở định dạng dữ liệu phân cấp (HDF5)

    Bạn cũng sẽ khám phá những điều sau đây:

    • Tại sao các phương pháp lưu trữ thay thế đáng để xem xét
    • Sự khác biệt về hiệu suất là gì khi bạn đọc và viết hình ảnh duy nhất
    • Sự khác biệt về hiệu suất là gì khi bạn đọc và viết nhiều hình ảnh
    • Cách ba phương pháp so sánh về mặt sử dụng đĩa

    Nếu không có phương pháp lưu trữ nào rung chuông, đừng lo lắng: Đối với bài viết này, tất cả những gì bạn cần là một nền tảng vững chắc hợp lý trong Python và một sự hiểu biết cơ bản về hình ảnh (rằng chúng thực sự bao gồm các mảng nhiều chiều) và Bộ nhớ tương đối, chẳng hạn như sự khác biệt giữa 10MB và 10GB.

    Bắt đầu nào!

    Thành lập

    Bạn sẽ cần một bộ dữ liệu hình ảnh để thử nghiệm, cũng như một vài gói Python.

    Một bộ dữ liệu để chơi với

    Chúng tôi sẽ sử dụng Bộ dữ liệu hình ảnh nghiên cứu tiên tiến của Viện nghiên cứu nâng cao, được gọi là CIFAR-10, bao gồm 60.000 hình ảnh màu 32x32 pixel thuộc các lớp đối tượng khác nhau, như chó, mèo và máy bay. Tương đối, CIFAR không phải là một bộ dữ liệu rất lớn, nhưng nếu chúng ta sử dụng bộ dữ liệu Tinyimages đầy đủ, thì bạn sẽ cần khoảng 400GB dung lượng đĩa tự do, có lẽ sẽ là yếu tố hạn chế.

    Các khoản tín dụng cho bộ dữ liệu như được mô tả trong Chương 3 của báo cáo công nghệ này thuộc về Alex Krizhevsky, Vinod Nair và Geoffrey Hinton.

    Nếu bạn muốn theo dõi cùng với các ví dụ mã trong bài viết này, bạn có thể tải xuống CIFAR-10 tại đây, chọn phiên bản Python. Bạn sẽ hy sinh 163MB không gian đĩa:

    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?
    Hình ảnh: A. Krizhevsky

    Khi bạn tải xuống và giải nén thư mục, bạn sẽ phát hiện ra rằng các tệp không phải là tệp hình ảnh có thể đọc được của con người. Chúng thực sự đã được tuần tự hóa và lưu theo lô bằng CPickle.

    Mặc dù chúng tôi sẽ không xem xét

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    7 hoặc
    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    8 trong bài viết này, ngoài việc trích xuất bộ dữ liệu CIFAR, nhưng điều đáng nói là mô -đun Python
    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    7 có lợi thế chính là có thể tuần tự hóa bất kỳ đối tượng Python nào mà không cần thêm mã hoặc chuyển đổi trên phần của bạn . Nó cũng có một nhược điểm nghiêm trọng là gây ra rủi ro bảo mật và không đối phó tốt khi xử lý số lượng dữ liệu rất lớn.

    Mã sau đây giải nén mỗi trong năm tệp hàng loạt và tải tất cả các hình ảnh vào một mảng numpy:

    import numpy as np
    import pickle
    from pathlib import Path
    
    # Path to the unzipped CIFAR data
    data_dir = Path("data/cifar-10-batches-py/")
    
    # Unpickle function provided by the CIFAR hosts
    def unpickle(file):
        with open(file, "rb") as fo:
            dict = pickle.load(fo, encoding="bytes")
        return dict
    
    images, labels = [], []
    for batch in data_dir.glob("data_batch_*"):
        batch_data = unpickle(batch)
        for i, flat_im in enumerate(batch_data[b"data"]):
            im_channels = []
            # Each image is flattened, with channels in order of R, G, B
            for j in range(3):
                im_channels.append(
                    flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
                )
            # Reconstruct the original image
            images.append(np.dstack((im_channels)))
            # Save the label
            labels.append(batch_data[b"labels"][i])
    
    print("Loaded CIFAR-10 training set:")
    print(f" - np.shape(images)     {np.shape(images)}")
    print(f" - np.shape(labels)     {np.shape(labels)}")
    

    Tất cả các hình ảnh hiện đang có trong RAM trong biến

    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    
    0, với dữ liệu meta tương ứng của chúng trong
    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    
    1 và sẵn sàng để bạn thao tác. Tiếp theo, bạn có thể cài đặt các gói Python mà bạn sẽ sử dụng cho ba phương thức.

    Thiết lập để lưu trữ hình ảnh trên đĩa

    Bạn cần phải thiết lập môi trường của mình cho phương pháp tiết kiệm mặc định và truy cập các hình ảnh này từ đĩa. Bài viết này sẽ cho rằng bạn đã cài đặt Python 3.x trên hệ thống của mình và sẽ sử dụng

    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    
    2 cho thao tác hình ảnh:

    Ngoài ra, nếu bạn thích, bạn có thể cài đặt nó bằng Anaconda:

    $ conda install -c conda-forge pillow
    

    Bây giờ bạn đã sẵn sàng để lưu trữ và đọc hình ảnh từ đĩa.

    Bắt đầu với LMDB

    LMDB, đôi khi được gọi là cơ sở dữ liệu Lightning, viết tắt của cơ sở dữ liệu ánh xạ bộ nhớ của Lightning vì nó nhanh và sử dụng các tệp được ánh xạ bộ nhớ. Nó có một cửa hàng giá trị khóa, không phải là cơ sở dữ liệu quan hệ.

    Về mặt thực hiện, LMDB là cây B+, về cơ bản có nghĩa là nó là cấu trúc đồ thị giống như cây được lưu trữ trong bộ nhớ trong đó mỗi phần tử giá trị khóa là một nút và các nút có thể có nhiều trẻ em. Các nút ở cùng cấp độ được liên kết với nhau để đi nhanh.

    Quan trọng, các thành phần chính của cây B+ được đặt thành tương ứng với kích thước trang của hệ điều hành máy chủ, tối đa hóa hiệu quả khi truy cập bất kỳ cặp giá trị khóa nào trong cơ sở dữ liệu. Vì hiệu suất cao của LMDB phụ thuộc nhiều vào điểm cụ thể này, hiệu quả của LMDB đã được chứng minh là phụ thuộc vào hệ thống tệp cơ bản và việc triển khai của nó.

    Một lý do quan trọng khác cho hiệu quả của LMDB là nó được ánh xạ bộ nhớ. Điều này có nghĩa là nó trả về các con trỏ trực tiếp cho các địa chỉ bộ nhớ của cả khóa và giá trị, mà không cần phải sao chép bất cứ điều gì trong bộ nhớ như hầu hết các cơ sở dữ liệu khác làm.it returns direct pointers to the memory addresses of both keys and values, without needing to copy anything in memory as most other databases do.

    Những người muốn đi sâu vào một chút chi tiết triển khai nội bộ của các cây B+ có thể xem bài viết này trên cây B+ và sau đó chơi với hình dung của việc chèn nút này.

    Nếu cây B+ không quan tâm đến bạn, đừng lo lắng. Bạn không cần phải biết nhiều về việc thực hiện nội bộ của họ để sử dụng LMDB. Chúng tôi sẽ sử dụng liên kết Python cho thư viện LMDB C, có thể được cài đặt thông qua PIP:

    Bạn cũng có tùy chọn cài đặt thông qua Anaconda:

    $ conda install -c conda-forge python-lmdb
    

    Kiểm tra xem bạn có thể

    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    
    3 từ vỏ Python không, và bạn có thể đi.

    Bắt đầu với HDF5

    HDF5 là viết tắt của định dạng dữ liệu phân cấp, định dạng tệp được gọi là HDF4 hoặc HDF5. Chúng tôi không cần phải lo lắng về HDF4, vì HDF5 là phiên bản được duy trì hiện tại.

    Thật thú vị, HDF có nguồn gốc trong Trung tâm ứng dụng siêu máy tính quốc gia, như một định dạng dữ liệu khoa học nhỏ gọn, di động. Nếu bạn đang tự hỏi liệu nó có được sử dụng rộng rãi không, hãy xem NASA, Blurb trên HDF5 từ dự án dữ liệu Trái đất của họ.

    Các tệp HDF bao gồm hai loại đối tượng:

    1. Bộ dữ liệu
    2. Các nhóm

    Bộ dữ liệu là các mảng đa chiều và các nhóm bao gồm các bộ dữ liệu hoặc các nhóm khác. Các mảng đa chiều của bất kỳ kích thước và loại có thể được lưu trữ dưới dạng dữ liệu, nhưng kích thước và loại phải đồng đều trong bộ dữ liệu. Mỗi bộ dữ liệu phải chứa một mảng N chiều đồng nhất. Điều đó nói rằng, bởi vì các nhóm và bộ dữ liệu có thể được lồng, bạn vẫn có thể nhận được sự không đồng nhất mà bạn có thể cần:

    Cũng như các thư viện khác, bạn có thể cài đặt xen kẽ qua Anaconda:

    $ conda install -c conda-forge h5py
    

    Nếu bạn có thể

    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    
    4 từ vỏ Python, mọi thứ được thiết lập đúng.

    Lưu trữ một hình ảnh duy nhất

    Bây giờ bạn có một cái nhìn tổng quan chung về các phương pháp, hãy để Lặn đi thẳng vào và xem xét một so sánh định lượng các tác vụ cơ bản mà chúng ta quan tâm: mất bao lâu để đọc và ghi tệp và số lượng bộ nhớ đĩa sẽ được sử dụng. Điều này cũng sẽ phục vụ như một giới thiệu cơ bản về cách thức hoạt động của các phương thức, với các ví dụ về cách sử dụng chúng.how long it takes to read and write files, and how much disk memory will be used. This will also serve as a basic introduction to how the methods work, with code examples of how to use them.

    Khi tôi đề cập đến các tập tin, tôi thường có nghĩa là rất nhiều trong số chúng. Tuy nhiên, điều quan trọng là phải phân biệt vì một số phương pháp có thể được tối ưu hóa cho các hoạt động và số lượng tệp khác nhau.

    Đối với mục đích thử nghiệm, chúng ta có thể so sánh hiệu suất giữa các lượng tệp khác nhau, bằng các yếu tố 10 từ một hình ảnh đến 100.000 hình ảnh. Vì năm lô CIFAR-10 của chúng tôi thêm tới 50.000 hình ảnh, chúng tôi có thể sử dụng mỗi hình ảnh hai lần để có được 100.000 hình ảnh.we can compare the performance between various quantities of files, by factors of 10 from a single image to 100,000 images. Since our five batches of CIFAR-10 add up to 50,000 images, we can use each image twice to get to 100,000 images.

    Để chuẩn bị cho các thử nghiệm, bạn sẽ muốn tạo một thư mục cho từng phương thức, sẽ chứa tất cả các tệp hoặc hình ảnh cơ sở dữ liệu và lưu các đường dẫn đến các thư mục đó theo các biến:

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    

    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    
    5 không tự động tạo các thư mục cho bạn trừ khi bạn hỏi cụ thể nó:

    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    

    Bây giờ bạn có thể chuyển sang chạy các thử nghiệm thực tế, với các ví dụ mã về cách thực hiện các tác vụ cơ bản với ba phương pháp khác nhau. Chúng ta có thể sử dụng mô -đun

    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    
    6, được bao gồm trong thư viện tiêu chuẩn Python, để giúp thời gian các thí nghiệm.

    Mặc dù mục đích chính của bài viết này không phải là tìm hiểu các API của các gói Python khác nhau, nhưng thật hữu ích khi có sự hiểu biết về cách chúng có thể được thực hiện. Chúng tôi sẽ thông qua các nguyên tắc chung cùng với tất cả các mã được sử dụng để tiến hành các thí nghiệm lưu trữ.

    Lưu trữ vào đĩa

    Đầu vào của chúng tôi cho thử nghiệm này là một hình ảnh duy nhất

    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    
    7, hiện đang ở trong bộ nhớ dưới dạng một mảng numpy. Bạn muốn lưu nó đầu tiên vào đĩa dưới dạng hình ảnh
    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4 và đặt tên cho nó bằng ID hình ảnh duy nhất
    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    
    9. Điều này có thể được thực hiện bằng cách sử dụng gói
    disk_dir.mkdir(parents=True, exist_ok=True)
    lmdb_dir.mkdir(parents=True, exist_ok=True)
    hdf5_dir.mkdir(parents=True, exist_ok=True)
    
    2 bạn đã cài đặt trước đó:

    from PIL import Image
    import csv
    
    def store_single_disk(image, image_id, label):
        """ Stores a single image as a .png file on disk.
            Parameters:
            ---------------
            image       image array, (32, 32, 3) to be stored
            image_id    integer unique ID for image
            label       image label
        """
        Image.fromarray(image).save(disk_dir / f"{image_id}.png")
    
        with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
            writer = csv.writer(
                csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([label])
    

    Điều này lưu hình ảnh. Trong tất cả các ứng dụng thực tế, bạn cũng quan tâm đến dữ liệu meta được đính kèm với hình ảnh, trong bộ dữ liệu ví dụ của chúng tôi là nhãn hình ảnh. Khi bạn lưu trữ hình ảnh vào đĩa, có một số tùy chọn để lưu dữ liệu meta.

    Một giải pháp là mã hóa các nhãn thành tên hình ảnh. Điều này có lợi thế là không yêu cầu bất kỳ tập tin bổ sung nào.

    Tuy nhiên, nó cũng có nhược điểm lớn là buộc bạn phải đối phó với tất cả các tệp bất cứ khi nào bạn làm bất cứ điều gì với nhãn. Lưu trữ nhãn trong một tệp riêng cho phép bạn chơi xung quanh với các nhãn mà không phải tải hình ảnh. Ở trên, tôi đã lưu trữ các nhãn trong một tệp

    from PIL import Image
    import csv
    
    def store_single_disk(image, image_id, label):
        """ Stores a single image as a .png file on disk.
            Parameters:
            ---------------
            image       image array, (32, 32, 3) to be stored
            image_id    integer unique ID for image
            label       image label
        """
        Image.fromarray(image).save(disk_dir / f"{image_id}.png")
    
        with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
            writer = csv.writer(
                csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([label])
    
    1 riêng cho thử nghiệm này.

    Bây giờ, hãy để Lừa chuyển sang thực hiện cùng một nhiệm vụ với LMDB.

    Lưu trữ đến LMDB

    Đầu tiên, LMDB là một hệ thống lưu trữ giá trị khóa trong đó mỗi mục được lưu dưới dạng mảng byte, vì vậy trong trường hợp của chúng tôi, các khóa sẽ là một mã định danh duy nhất cho mỗi hình ảnh và giá trị sẽ là chính hình ảnh. Cả các khóa và giá trị được dự kiến ​​là các chuỗi, vì vậy việc sử dụng phổ biến là tuần tự hóa giá trị dưới dạng chuỗi, và sau đó không thể giải quyết được khi đọc nó ra.Both the keys and values are expected to be strings, so the common usage is to serialize the value as a string, and then unserialize it when reading it back out.

    Bạn có thể sử dụng

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    7 để tuần tự hóa. Bất kỳ đối tượng Python nào cũng có thể được tuần tự hóa, vì vậy bạn cũng có thể bao gồm dữ liệu hình ảnh meta trong cơ sở dữ liệu. Điều này giúp bạn tiết kiệm rắc rối khi đính kèm dữ liệu meta trở lại dữ liệu hình ảnh khi chúng tôi tải tập dữ liệu từ đĩa.

    Bạn có thể tạo một lớp Python cơ bản cho hình ảnh và dữ liệu meta của nó:

    class CIFAR_Image:
        def __init__(self, image, label):
            # Dimensions of image for reconstruction - not really necessary 
            # for this dataset, but some datasets may include images of 
            # varying sizes
            self.channels = image.shape[2]
            self.size = image.shape[:2]
    
            self.image = image.tobytes()
            self.label = label
    
        def get_image(self):
            """ Returns the image as a numpy array. """
            image = np.frombuffer(self.image, dtype=np.uint8)
            return image.reshape(*self.size, self.channels)
    

    Thứ hai, vì LMDB được ánh xạ bộ nhớ, cơ sở dữ liệu mới cần phải biết chúng dự kiến ​​sẽ sử dụng bao nhiêu bộ nhớ. Điều này tương đối đơn giản trong trường hợp của chúng tôi, nhưng nó có thể là một nỗi đau lớn trong các trường hợp khác, mà bạn sẽ thấy sâu hơn trong phần sau. LMDB gọi biến này là

    from PIL import Image
    import csv
    
    def store_single_disk(image, image_id, label):
        """ Stores a single image as a .png file on disk.
            Parameters:
            ---------------
            image       image array, (32, 32, 3) to be stored
            image_id    integer unique ID for image
            label       image label
        """
        Image.fromarray(image).save(disk_dir / f"{image_id}.png")
    
        with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
            writer = csv.writer(
                csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([label])
    
    3.

    Cuối cùng, đọc và ghi các hoạt động với LMDB được thực hiện trong

    from PIL import Image
    import csv
    
    def store_single_disk(image, image_id, label):
        """ Stores a single image as a .png file on disk.
            Parameters:
            ---------------
            image       image array, (32, 32, 3) to be stored
            image_id    integer unique ID for image
            label       image label
        """
        Image.fromarray(image).save(disk_dir / f"{image_id}.png")
    
        with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
            writer = csv.writer(
                csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([label])
    
    4. Bạn có thể nghĩ về chúng tương tự như cơ sở dữ liệu truyền thống, bao gồm một nhóm hoạt động trên cơ sở dữ liệu. Điều này có thể trông phức tạp hơn đáng kể so với phiên bản đĩa, nhưng hãy tiếp tục và tiếp tục đọc!

    Với ba điểm đó trong tâm trí, chúng ta hãy nhìn vào mã để lưu một hình ảnh duy nhất vào LMDB:

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    0

    Bây giờ bạn đã sẵn sàng để lưu một hình ảnh vào LMDB. Cuối cùng, hãy để Lôi nhìn vào phương pháp cuối cùng, HDF5.

    Lưu trữ với HDF5

    Hãy nhớ rằng một tệp HDF5 có thể chứa nhiều hơn một bộ dữ liệu. Trong trường hợp khá tầm thường này, bạn có thể tạo hai bộ dữ liệu, một cho hình ảnh và một cho dữ liệu meta của nó:

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    1

    from PIL import Image
    import csv
    
    def store_single_disk(image, image_id, label):
        """ Stores a single image as a .png file on disk.
            Parameters:
            ---------------
            image       image array, (32, 32, 3) to be stored
            image_id    integer unique ID for image
            label       image label
        """
        Image.fromarray(image).save(disk_dir / f"{image_id}.png")
    
        with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
            writer = csv.writer(
                csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([label])
    
    5 Chỉ định loại dữ liệu sẽ được lưu trữ trong bộ dữ liệu, trong trường hợp này là số nguyên 8 bit không dấu. Bạn có thể thấy một danh sách đầy đủ các kiểu dữ liệu được xác định trước của HDF tại đây.

    Bây giờ chúng tôi đã xem xét ba phương pháp lưu một hình ảnh duy nhất, hãy để chuyển sang bước tiếp theo.

    Thử nghiệm lưu trữ một hình ảnh duy nhất

    Bây giờ bạn có thể đặt cả ba chức năng để lưu một hình ảnh duy nhất vào từ điển, có thể được gọi sau này trong các thử nghiệm thời gian:

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    2

    Cuối cùng, mọi thứ đã sẵn sàng để tiến hành thí nghiệm đúng giờ. Hãy cùng thử lưu hình ảnh đầu tiên từ CIFAR và nhãn tương ứng của nó và lưu trữ nó theo ba cách khác nhau:

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    3

    Hãy nhớ rằng chúng tôi quan tâm đến thời gian chạy, được hiển thị ở đây trong vài giây và cả việc sử dụng bộ nhớ:

    Phương phápLưu hình ảnh đơn + metaKỉ niệm
    Đĩa1.915 ms8 k
    LMDB1,203 ms32 k
    HDF58.243 ms8 k

    LMDB

    1. 1,203 ms
    2. 32 k

    HDF5

    8.243 ms

    Có hai lần gặp gỡ ở đây:

    Tất cả các phương pháp đều nhanh chóng.

    Về mặt sử dụng đĩa, LMDB sử dụng nhiều hơn.

    Rõ ràng, mặc dù LMDB có một hiệu suất dẫn đầu, chúng tôi đã thuyết phục bất cứ ai tại sao không chỉ lưu trữ hình ảnh trên đĩa. Rốt cuộc, nó là một định dạng có thể đọc được của con người và bạn có thể mở và xem chúng từ bất kỳ trình duyệt hệ thống tệp nào! Chà, đó là thời gian để xem xét nhiều hình ảnh hơn nữa

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    4

    Lưu trữ nhiều hình ảnh

    Điều chỉnh nhỏ nhất là với phương pháp HDF5. Trong thực tế, có hầu như không có một sự điều chỉnh nào cả! Các tệp HFD5 không có giới hạn về kích thước tệp ngoài các hạn chế bên ngoài hoặc kích thước tập dữ liệu, vì vậy tất cả các hình ảnh được nhồi vào một bộ dữ liệu, giống như trước đây.

    Tiếp theo, bạn sẽ cần chuẩn bị bộ dữ liệu cho các thí nghiệm bằng cách tăng kích thước của nó.

    Chuẩn bị bộ dữ liệu

    Trước khi chạy lại các thử nghiệm, trước tiên hãy để gấp đôi kích thước tập dữ liệu của chúng tôi để chúng tôi có thể kiểm tra với tối đa 100.000 hình ảnh:

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    5

    Bây giờ có đủ hình ảnh, đó là thời gian cho thí nghiệm.

    Thử nghiệm lưu trữ nhiều hình ảnh

    Như bạn đã làm với việc đọc nhiều hình ảnh, bạn có thể tạo một từ điển xử lý tất cả các chức năng với

    class CIFAR_Image:
        def __init__(self, image, label):
            # Dimensions of image for reconstruction - not really necessary 
            # for this dataset, but some datasets may include images of 
            # varying sizes
            self.channels = image.shape[2]
            self.size = image.shape[:2]
    
            self.image = image.tobytes()
            self.label = label
    
        def get_image(self):
            """ Returns the image as a numpy array. """
            image = np.frombuffer(self.image, dtype=np.uint8)
            return image.reshape(*self.size, self.channels)
    
    2 và chạy các thử nghiệm:

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    6

    Nếu bạn theo dõi và tự chạy mã, bạn sẽ cần phải ngồi lại một lúc trong sự hồi hộp và chờ 111.110 hình ảnh được lưu trữ ba lần mỗi đĩa của bạn, ở ba định dạng khác nhau. Bạn cũng cần phải nói lời tạm biệt với khoảng 2 GB không gian đĩa.

    Bây giờ cho khoảnh khắc của sự thật! Tất cả việc lưu trữ đã mất bao lâu? Một bưc tranh đang gia ngan lơi noi:How long did all of that storing take? A picture is worth a thousand words:

    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?
    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?

    Biểu đồ đầu tiên hiển thị thời gian lưu trữ bình thường, không được điều chỉnh, làm nổi bật sự khác biệt mạnh mẽ giữa việc lưu trữ vào các tệp

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4 và LMDB hoặc HDF5.

    Biểu đồ thứ hai cho thấy

    class CIFAR_Image:
        def __init__(self, image, label):
            # Dimensions of image for reconstruction - not really necessary 
            # for this dataset, but some datasets may include images of 
            # varying sizes
            self.channels = image.shape[2]
            self.size = image.shape[:2]
    
            self.image = image.tobytes()
            self.label = label
    
        def get_image(self):
            """ Returns the image as a numpy array. """
            image = np.frombuffer(self.image, dtype=np.uint8)
            return image.reshape(*self.size, self.channels)
    
    4 của thời gian, làm nổi bật rằng HDF5 bắt đầu chậm hơn LMDB, nhưng, với số lượng lớn hình ảnh, đi ra một chút về phía trước.

    Mặc dù kết quả chính xác có thể thay đổi tùy thuộc vào máy của bạn, nhưng đây là lý do tại sao LMDB và HDF5 đáng suy nghĩ. Ở đây, mã đã tạo ra biểu đồ trên:this is why LMDB and HDF5 are worth thinking about. Here’s the code that generated the above graph:

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    7

    Bây giờ, hãy để tiếp tục đọc các hình ảnh trở lại.

    Đọc một hình ảnh duy nhất

    Đầu tiên, hãy để Lừa xem xét trường hợp đọc một hình ảnh trở lại vào một mảng cho mỗi trong ba phương thức.

    Đọc từ đĩa

    Trong ba phương pháp, LMDB yêu cầu nhiều công việc nhất khi đọc các tệp hình ảnh trở lại khỏi bộ nhớ, vì bước tuần tự hóa. Hãy để Lừa đi qua các chức năng đọc một hình ảnh duy nhất cho mỗi trong ba định dạng lưu trữ.

    Đầu tiên, đọc một hình ảnh duy nhất và meta của nó từ tệp

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4 và
    from PIL import Image
    import csv
    
    def store_single_disk(image, image_id, label):
        """ Stores a single image as a .png file on disk.
            Parameters:
            ---------------
            image       image array, (32, 32, 3) to be stored
            image_id    integer unique ID for image
            label       image label
        """
        Image.fromarray(image).save(disk_dir / f"{image_id}.png")
    
        with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
            writer = csv.writer(
                csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([label])
    
    1:

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    8

    Đọc từ LMDB

    Tiếp theo, đọc cùng một hình ảnh và meta từ LMDB bằng cách mở môi trường và bắt đầu một giao dịch đọc:

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    9

    Dưới đây là một vài điểm để không phải về đoạn mã ở trên:

    • Dòng 13: Cờ
      class CIFAR_Image:
          def __init__(self, image, label):
              # Dimensions of image for reconstruction - not really necessary 
              # for this dataset, but some datasets may include images of 
              # varying sizes
              self.channels = image.shape[2]
              self.size = image.shape[:2]
      
              self.image = image.tobytes()
              self.label = label
      
          def get_image(self):
              """ Returns the image as a numpy array. """
              image = np.frombuffer(self.image, dtype=np.uint8)
              return image.reshape(*self.size, self.channels)
      
      7 chỉ định rằng sẽ không được phép ghi nào trên tệp LMDB cho đến khi giao dịch kết thúc. Trong ngôn ngữ cơ sở dữ liệu, nó tương đương với việc lấy một khóa đọc.
      The
      class CIFAR_Image:
          def __init__(self, image, label):
              # Dimensions of image for reconstruction - not really necessary 
              # for this dataset, but some datasets may include images of 
              # varying sizes
              self.channels = image.shape[2]
              self.size = image.shape[:2]
      
              self.image = image.tobytes()
              self.label = label
      
          def get_image(self):
              """ Returns the image as a numpy array. """
              image = np.frombuffer(self.image, dtype=np.uint8)
              return image.reshape(*self.size, self.channels)
      
      7 flag specifies that no writes will be allowed on the LMDB file until the transaction is finished. In database lingo, it’s equivalent to taking a read lock.
    • Dòng 20: Để truy xuất đối tượng CIFAR_IMAGE, bạn cần đảo ngược các bước chúng tôi đã thực hiện để dồn nó khi chúng tôi viết nó. Đây là nơi
      class CIFAR_Image:
          def __init__(self, image, label):
              # Dimensions of image for reconstruction - not really necessary 
              # for this dataset, but some datasets may include images of 
              # varying sizes
              self.channels = image.shape[2]
              self.size = image.shape[:2]
      
              self.image = image.tobytes()
              self.label = label
      
          def get_image(self):
              """ Returns the image as a numpy array. """
              image = np.frombuffer(self.image, dtype=np.uint8)
              return image.reshape(*self.size, self.channels)
      
      8 của đối tượng là hữu ích.
      To retrieve the CIFAR_Image object, you need to reverse the steps we took to pickle it when we were writing it. This is where the
      class CIFAR_Image:
          def __init__(self, image, label):
              # Dimensions of image for reconstruction - not really necessary 
              # for this dataset, but some datasets may include images of 
              # varying sizes
              self.channels = image.shape[2]
              self.size = image.shape[:2]
      
              self.image = image.tobytes()
              self.label = label
      
          def get_image(self):
              """ Returns the image as a numpy array. """
              image = np.frombuffer(self.image, dtype=np.uint8)
              return image.reshape(*self.size, self.channels)
      
      8 of the object is helpful.

    Điều này kết thúc việc đọc hình ảnh trở lại từ LMDB. Cuối cùng, bạn sẽ muốn làm điều tương tự với HDF5.

    Đọc từ HDF5

    Đọc từ HDF5 trông rất giống với quá trình viết. Dưới đây là mã để mở và đọc tệp HDF5 và phân tích cùng một hình ảnh và meta:

    import numpy as np
    import pickle
    from pathlib import Path
    
    # Path to the unzipped CIFAR data
    data_dir = Path("data/cifar-10-batches-py/")
    
    # Unpickle function provided by the CIFAR hosts
    def unpickle(file):
        with open(file, "rb") as fo:
            dict = pickle.load(fo, encoding="bytes")
        return dict
    
    images, labels = [], []
    for batch in data_dir.glob("data_batch_*"):
        batch_data = unpickle(batch)
        for i, flat_im in enumerate(batch_data[b"data"]):
            im_channels = []
            # Each image is flattened, with channels in order of R, G, B
            for j in range(3):
                im_channels.append(
                    flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
                )
            # Reconstruct the original image
            images.append(np.dstack((im_channels)))
            # Save the label
            labels.append(batch_data[b"labels"][i])
    
    print("Loaded CIFAR-10 training set:")
    print(f" - np.shape(images)     {np.shape(images)}")
    print(f" - np.shape(labels)     {np.shape(labels)}")
    
    0

    Lưu ý rằng bạn truy cập các bộ dữ liệu khác nhau trong tệp bằng cách lập chỉ mục cho đối tượng

    class CIFAR_Image:
        def __init__(self, image, label):
            # Dimensions of image for reconstruction - not really necessary 
            # for this dataset, but some datasets may include images of 
            # varying sizes
            self.channels = image.shape[2]
            self.size = image.shape[:2]
    
            self.image = image.tobytes()
            self.label = label
    
        def get_image(self):
            """ Returns the image as a numpy array. """
            image = np.frombuffer(self.image, dtype=np.uint8)
            return image.reshape(*self.size, self.channels)
    
    9 bằng cách sử dụng tên bộ dữ liệu trước một dấu gạch chéo phía trước
    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    00. Như trước đây, bạn có thể tạo một từ điển chứa tất cả các chức năng đọc:

    import numpy as np
    import pickle
    from pathlib import Path
    
    # Path to the unzipped CIFAR data
    data_dir = Path("data/cifar-10-batches-py/")
    
    # Unpickle function provided by the CIFAR hosts
    def unpickle(file):
        with open(file, "rb") as fo:
            dict = pickle.load(fo, encoding="bytes")
        return dict
    
    images, labels = [], []
    for batch in data_dir.glob("data_batch_*"):
        batch_data = unpickle(batch)
        for i, flat_im in enumerate(batch_data[b"data"]):
            im_channels = []
            # Each image is flattened, with channels in order of R, G, B
            for j in range(3):
                im_channels.append(
                    flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
                )
            # Reconstruct the original image
            images.append(np.dstack((im_channels)))
            # Save the label
            labels.append(batch_data[b"labels"][i])
    
    print("Loaded CIFAR-10 training set:")
    print(f" - np.shape(images)     {np.shape(images)}")
    print(f" - np.shape(labels)     {np.shape(labels)}")
    
    1

    Với từ điển này được chuẩn bị, bạn đã sẵn sàng để chạy thử nghiệm.

    Thử nghiệm đọc một hình ảnh duy nhất

    Bạn có thể mong đợi rằng thử nghiệm để đọc một hình ảnh duy nhất trong sẽ có kết quả tầm thường, nhưng ở đây, mã thử nghiệm: mã thử nghiệm:

    import numpy as np
    import pickle
    from pathlib import Path
    
    # Path to the unzipped CIFAR data
    data_dir = Path("data/cifar-10-batches-py/")
    
    # Unpickle function provided by the CIFAR hosts
    def unpickle(file):
        with open(file, "rb") as fo:
            dict = pickle.load(fo, encoding="bytes")
        return dict
    
    images, labels = [], []
    for batch in data_dir.glob("data_batch_*"):
        batch_data = unpickle(batch)
        for i, flat_im in enumerate(batch_data[b"data"]):
            im_channels = []
            # Each image is flattened, with channels in order of R, G, B
            for j in range(3):
                im_channels.append(
                    flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
                )
            # Reconstruct the original image
            images.append(np.dstack((im_channels)))
            # Save the label
            labels.append(batch_data[b"labels"][i])
    
    print("Loaded CIFAR-10 training set:")
    print(f" - np.shape(images)     {np.shape(images)}")
    print(f" - np.shape(labels)     {np.shape(labels)}")
    
    2

    Dưới đây là kết quả của thí nghiệm đọc một hình ảnh duy nhất:

    Phương phápĐọc một hình ảnh + meta
    Đĩa1.61970 ms
    LMDB4.52063 ms
    HDF51.98036 ms

    Nó nhanh hơn một chút để đọc các tệp

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4 và
    from PIL import Image
    import csv
    
    def store_single_disk(image, image_id, label):
        """ Stores a single image as a .png file on disk.
            Parameters:
            ---------------
            image       image array, (32, 32, 3) to be stored
            image_id    integer unique ID for image
            label       image label
        """
        Image.fromarray(image).save(disk_dir / f"{image_id}.png")
    
        with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
            writer = csv.writer(
                csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([label])
    
    1 trực tiếp từ đĩa, nhưng cả ba phương pháp đều thực hiện nhanh chóng. Các thí nghiệm mà chúng tôi sẽ làm tiếp theo là thú vị hơn nhiều.

    Đọc nhiều hình ảnh

    Bây giờ bạn có thể điều chỉnh mã để đọc nhiều hình ảnh cùng một lúc. Đây có thể là hành động mà bạn sẽ thực hiện thường xuyên nhất, vì vậy hiệu suất thời gian chạy là rất cần thiết.

    Điều chỉnh mã cho nhiều hình ảnh

    Mở rộng các chức năng ở trên, bạn có thể tạo các chức năng với

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    03, có thể được sử dụng cho các thí nghiệm tiếp theo. Giống như trước đây, thật thú vị khi so sánh hiệu suất khi đọc các lượng hình ảnh khác nhau, được lặp lại trong mã bên dưới để tham khảo:

    import numpy as np
    import pickle
    from pathlib import Path
    
    # Path to the unzipped CIFAR data
    data_dir = Path("data/cifar-10-batches-py/")
    
    # Unpickle function provided by the CIFAR hosts
    def unpickle(file):
        with open(file, "rb") as fo:
            dict = pickle.load(fo, encoding="bytes")
        return dict
    
    images, labels = [], []
    for batch in data_dir.glob("data_batch_*"):
        batch_data = unpickle(batch)
        for i, flat_im in enumerate(batch_data[b"data"]):
            im_channels = []
            # Each image is flattened, with channels in order of R, G, B
            for j in range(3):
                im_channels.append(
                    flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
                )
            # Reconstruct the original image
            images.append(np.dstack((im_channels)))
            # Save the label
            labels.append(batch_data[b"labels"][i])
    
    print("Loaded CIFAR-10 training set:")
    print(f" - np.shape(images)     {np.shape(images)}")
    print(f" - np.shape(labels)     {np.shape(labels)}")
    
    3

    Với các chức năng đọc được lưu trữ trong một từ điển như với các chức năng viết, bạn đã đặt tất cả cho thử nghiệm.

    Thử nghiệm đọc nhiều hình ảnh

    Bây giờ bạn có thể chạy thử nghiệm để đọc nhiều hình ảnh:

    import numpy as np
    import pickle
    from pathlib import Path
    
    # Path to the unzipped CIFAR data
    data_dir = Path("data/cifar-10-batches-py/")
    
    # Unpickle function provided by the CIFAR hosts
    def unpickle(file):
        with open(file, "rb") as fo:
            dict = pickle.load(fo, encoding="bytes")
        return dict
    
    images, labels = [], []
    for batch in data_dir.glob("data_batch_*"):
        batch_data = unpickle(batch)
        for i, flat_im in enumerate(batch_data[b"data"]):
            im_channels = []
            # Each image is flattened, with channels in order of R, G, B
            for j in range(3):
                im_channels.append(
                    flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
                )
            # Reconstruct the original image
            images.append(np.dstack((im_channels)))
            # Save the label
            labels.append(batch_data[b"labels"][i])
    
    print("Loaded CIFAR-10 training set:")
    print(f" - np.shape(images)     {np.shape(images)}")
    print(f" - np.shape(labels)     {np.shape(labels)}")
    
    4

    Như chúng tôi đã làm trước đây, bạn có thể vẽ đồ thị kết quả thử nghiệm đọc:

    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?
    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?

    Biểu đồ trên cùng hiển thị thời gian đọc bình thường, không được điều chỉnh, cho thấy sự khác biệt mạnh mẽ giữa việc đọc từ các tệp

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4 và LMDB hoặc HDF5.

    Ngược lại, biểu đồ ở phía dưới cho thấy

    class CIFAR_Image:
        def __init__(self, image, label):
            # Dimensions of image for reconstruction - not really necessary 
            # for this dataset, but some datasets may include images of 
            # varying sizes
            self.channels = image.shape[2]
            self.size = image.shape[:2]
    
            self.image = image.tobytes()
            self.label = label
    
        def get_image(self):
            """ Returns the image as a numpy array. """
            image = np.frombuffer(self.image, dtype=np.uint8)
            return image.reshape(*self.size, self.channels)
    
    4 của thời gian, làm nổi bật sự khác biệt tương đối với ít hình ảnh hơn. Cụ thể, chúng ta có thể thấy HDF5 bắt đầu như thế nào, nhưng với nhiều hình ảnh hơn, trở nên nhanh hơn LMDB bởi một biên độ nhỏ.

    Sử dụng cùng một hàm âm mưu như đối với thời gian ghi, chúng tôi có những điều sau đây:

    import numpy as np
    import pickle
    from pathlib import Path
    
    # Path to the unzipped CIFAR data
    data_dir = Path("data/cifar-10-batches-py/")
    
    # Unpickle function provided by the CIFAR hosts
    def unpickle(file):
        with open(file, "rb") as fo:
            dict = pickle.load(fo, encoding="bytes")
        return dict
    
    images, labels = [], []
    for batch in data_dir.glob("data_batch_*"):
        batch_data = unpickle(batch)
        for i, flat_im in enumerate(batch_data[b"data"]):
            im_channels = []
            # Each image is flattened, with channels in order of R, G, B
            for j in range(3):
                im_channels.append(
                    flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
                )
            # Reconstruct the original image
            images.append(np.dstack((im_channels)))
            # Save the label
            labels.append(batch_data[b"labels"][i])
    
    print("Loaded CIFAR-10 training set:")
    print(f" - np.shape(images)     {np.shape(images)}")
    print(f" - np.shape(labels)     {np.shape(labels)}")
    
    5

    Trong thực tế, thời gian viết thường ít quan trọng hơn thời gian đọc. Hãy tưởng tượng rằng bạn đang đào tạo một mạng lưới thần kinh sâu trên hình ảnh và chỉ một nửa toàn bộ bộ dữ liệu hình ảnh của bạn phù hợp với RAM cùng một lúc. Mỗi kỷ nguyên đào tạo một mạng đòi hỏi toàn bộ bộ dữ liệu và mô hình cần vài trăm kỷ nguyên để hội tụ. Về cơ bản, bạn sẽ đọc một nửa bộ dữ liệu vào bộ nhớ mỗi kỷ nguyên. Imagine that you are training a deep neural network on images, and only half of your entire image dataset fits into RAM at once. Each epoch of training a network requires the entire dataset, and the model needs a few hundred epochs to converge. You will essentially be reading half of the dataset into memory every epoch.

    Có một số thủ thuật mà mọi người làm, chẳng hạn như đào tạo pseudo-epoch để làm cho điều này tốt hơn một chút, nhưng bạn có ý tưởng.

    Bây giờ, hãy nhìn lại biểu đồ đọc ở trên. Sự khác biệt giữa thời gian đọc 40 giây và 4 giây đột nhiên là sự khác biệt giữa chờ sáu giờ để mô hình của bạn đào tạo, hoặc bốn mươi phút!

    Nếu chúng ta xem thời gian đọc và ghi trên cùng một biểu đồ, chúng ta có những điều sau đây:

    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?

    Bạn có thể vẽ tất cả thời gian đọc và ghi trên một biểu đồ bằng cùng một hàm vẽ âm mưu:

    import numpy as np
    import pickle
    from pathlib import Path
    
    # Path to the unzipped CIFAR data
    data_dir = Path("data/cifar-10-batches-py/")
    
    # Unpickle function provided by the CIFAR hosts
    def unpickle(file):
        with open(file, "rb") as fo:
            dict = pickle.load(fo, encoding="bytes")
        return dict
    
    images, labels = [], []
    for batch in data_dir.glob("data_batch_*"):
        batch_data = unpickle(batch)
        for i, flat_im in enumerate(batch_data[b"data"]):
            im_channels = []
            # Each image is flattened, with channels in order of R, G, B
            for j in range(3):
                im_channels.append(
                    flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
                )
            # Reconstruct the original image
            images.append(np.dstack((im_channels)))
            # Save the label
            labels.append(batch_data[b"labels"][i])
    
    print("Loaded CIFAR-10 training set:")
    print(f" - np.shape(images)     {np.shape(images)}")
    print(f" - np.shape(labels)     {np.shape(labels)}")
    
    6

    Khi bạn lưu trữ hình ảnh dưới dạng tệp

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4, có một sự khác biệt lớn giữa thời gian viết và đọc. Tuy nhiên, với LMDB và HDF5, sự khác biệt ít được đánh dấu hơn nhiều. Nhìn chung, ngay cả khi thời gian đọc quan trọng hơn thời gian viết, có một đối số mạnh mẽ để lưu trữ hình ảnh bằng LMDB hoặc HDF5.

    Bây giờ, bạn đã thấy những lợi ích hiệu suất của LMDB và HDF5, hãy để Lôi nhìn vào một số liệu quan trọng khác: sử dụng đĩa.

    Xem xét việc sử dụng đĩa

    Tốc độ không phải là số liệu hiệu suất duy nhất mà bạn có thể quan tâm. Chúng tôi đã xử lý các bộ dữ liệu rất lớn, vì vậy không gian đĩa cũng là một mối quan tâm rất hợp lệ và có liên quan.

    Giả sử bạn có một bộ dữ liệu hình ảnh là 3TB. Có lẽ, bạn đã có chúng trên đĩa ở đâu đó, không giống như ví dụ CIFAR của chúng tôi, vì vậy bằng cách sử dụng phương pháp lưu trữ thay thế, về cơ bản bạn đang tạo một bản sao của chúng, cũng phải được lưu trữ. Làm như vậy sẽ mang lại cho bạn những lợi ích hiệu suất rất lớn khi bạn sử dụng hình ảnh, nhưng bạn sẽ cần đảm bảo rằng bạn có đủ dung lượng đĩa.

    Các phương pháp lưu trữ khác nhau sử dụng bao nhiêu đĩa? Ở đây, không gian đĩa được sử dụng cho từng phương thức cho từng số lượng hình ảnh: Here’s the disk space used for each method for each quantity of images:

    Hướng dẫn how do i save a high quality image in python? - làm cách nào để lưu hình ảnh chất lượng cao trong python?

    Tôi đã sử dụng lệnh Linux

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    07 để tính toán việc sử dụng đĩa trên hệ thống của mình. Có một số xấp xỉ vốn có với phương pháp này do làm tròn, nhưng ở đây, so sánh chung:

    import numpy as np
    import pickle
    from pathlib import Path
    
    # Path to the unzipped CIFAR data
    data_dir = Path("data/cifar-10-batches-py/")
    
    # Unpickle function provided by the CIFAR hosts
    def unpickle(file):
        with open(file, "rb") as fo:
            dict = pickle.load(fo, encoding="bytes")
        return dict
    
    images, labels = [], []
    for batch in data_dir.glob("data_batch_*"):
        batch_data = unpickle(batch)
        for i, flat_im in enumerate(batch_data[b"data"]):
            im_channels = []
            # Each image is flattened, with channels in order of R, G, B
            for j in range(3):
                im_channels.append(
                    flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
                )
            # Reconstruct the original image
            images.append(np.dstack((im_channels)))
            # Save the label
            labels.append(batch_data[b"labels"][i])
    
    print("Loaded CIFAR-10 training set:")
    print(f" - np.shape(images)     {np.shape(images)}")
    print(f" - np.shape(labels)     {np.shape(labels)}")
    
    7

    Cả HDF5 và LMDB đều chiếm nhiều không gian đĩa hơn nếu bạn lưu trữ bằng hình ảnh

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4 bình thường. Điều quan trọng cần lưu ý là cả việc sử dụng và hiệu suất của đĩa LMDB và HDF5 đều phụ thuộc rất nhiều vào các yếu tố khác nhau, bao gồm hệ điều hành và, quan trọng hơn là kích thước của dữ liệu bạn lưu trữ.depend highly on various factors, including operating system and, more critically, the size of the data you store.

    LMDB đạt được hiệu quả từ bộ nhớ đệm và tận dụng các kích thước trang hệ điều hành. Bạn không cần hiểu hoạt động bên trong của nó, nhưng lưu ý rằng với hình ảnh lớn hơn, bạn sẽ kết thúc với việc sử dụng đĩa nhiều hơn đáng kể với LMDB, bởi vì hình ảnh sẽ không phù hợp với các trang lá của LMDB, vị trí lưu trữ thông thường trong cây và Thay vào đó bạn sẽ có nhiều trang tràn. Thanh LMDB trong biểu đồ trên sẽ bắn ra biểu đồ.with larger images, you will end up with significantly more disk usage with LMDB, because images won’t fit on LMDB’s leaf pages, the regular storage location in the tree, and instead you will have many overflow pages. The LMDB bar in the chart above will shoot off the chart.

    Hình ảnh pixel 32x32x3 của chúng tôi tương đối nhỏ so với hình ảnh trung bình bạn có thể sử dụng và chúng cho phép hiệu suất LMDB tối ưu.

    Mặc dù chúng tôi đã giành chiến thắng khám phá nó ở đây bằng thực nghiệm, nhưng theo trải nghiệm của riêng tôi với hình ảnh 256x256x3 hoặc 512x512x3 pixel, HDF5 thường hiệu quả hơn một chút về việc sử dụng đĩa so với LMDB. Đây là một sự chuyển đổi tốt vào phần cuối cùng, một cuộc thảo luận định tính về sự khác biệt giữa các phương pháp.

    Thảo luận

    Có những tính năng khác biệt khác của LMDB và HDF5 đáng để biết, và nó cũng rất quan trọng để thảo luận ngắn gọn về một số lời chỉ trích của cả hai phương pháp. Một số liên kết được bao gồm cùng với các cuộc thảo luận nếu bạn muốn tìm hiểu thêm.

    Truy cập song song

    Một so sánh quan trọng mà chúng tôi đã thử nghiệm trong các thí nghiệm trên là các lần đọc và ghi đồng thời. Thông thường, với các bộ dữ liệu lớn như vậy, bạn có thể muốn tăng tốc hoạt động của mình thông qua song song hóa.Often, with such large datasets, you may want to speed up your operation through parallelization.

    Trong phần lớn các trường hợp, bạn đã thắng được quan tâm đến việc đọc các phần của cùng một hình ảnh cùng một lúc, nhưng bạn sẽ muốn đọc nhiều hình ảnh cùng một lúc. Với định nghĩa về đồng thời này, việc lưu trữ vào đĩa dưới dạng các tệp

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4 thực sự cho phép hoàn toàn đồng thời. Không có gì ngăn bạn đọc một số hình ảnh cùng một lúc từ các luồng khác nhau hoặc viết nhiều tệp cùng một lúc, miễn là các tên hình ảnh khác nhau.

    Làm thế nào về LMDB? Có thể có nhiều độc giả trên môi trường LMDB tại một thời điểm, nhưng chỉ có một nhà văn và các nhà văn không chặn độc giả. Bạn có thể đọc thêm về điều đó tại trang web LMDB Technology.

    Nhiều ứng dụng có thể truy cập cùng một cơ sở dữ liệu LMDB cùng một lúc và nhiều luồng từ cùng một quy trình cũng có thể truy cập đồng thời LMDB để đọc. Điều này cho phép thời gian đọc nhanh hơn thậm chí: Nếu bạn chia tất cả CIFAR thành mười bộ, thì bạn có thể thiết lập mười quy trình cho mỗi lần đọc trong một bộ và nó sẽ chia thời gian tải cho mười.

    HDF5 cũng cung cấp I/O song song, cho phép ghi và ghi đồng thời. Tuy nhiên, trong việc thực hiện, khóa ghi được giữ và truy cập là tuần tự, trừ khi bạn có một hệ thống tệp song song.

    Có hai tùy chọn chính nếu bạn đang làm việc trên một hệ thống như vậy, được thảo luận sâu hơn về bài viết này bởi nhóm HDF trên IO song song. Nó có thể trở nên khá phức tạp và tùy chọn đơn giản nhất là chia bộ dữ liệu của bạn thành nhiều tệp HDF5, do đó mỗi quy trình có thể xử lý một tệp

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    10 độc lập với các tệp khác.

    Tài liệu

    Nếu bạn Google

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    11, ít nhất là ở Vương quốc Anh, kết quả tìm kiếm thứ ba là IMDB, cơ sở dữ liệu phim Internet. Đó không phải là những gì bạn đang tìm kiếm!

    Trên thực tế, có một nguồn tài liệu chính cho ràng buộc Python của LMDB, được lưu trữ trên Read the Docs LMDB. Mặc dù gói Python thậm chí đã đạt đến phiên bản> 0,94, nhưng nó được sử dụng khá rộng rãi và được coi là ổn định.

    Đối với chính công nghệ LMDB, có nhiều tài liệu chi tiết hơn tại trang web LMDB Technology, có thể cảm thấy hơi giống như học tính toán ở lớp hai, trừ khi bạn bắt đầu từ trang bắt đầu của họ.

    Đối với HDF5, có tài liệu rất rõ ràng tại trang web H5Py Docs, cũng như một bài đăng trên blog hữu ích của Christopher Lovell, đây là một tổng quan tuyệt vời về cách sử dụng gói

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    12. Cuốn sách O hèReilly, Python và HDF5 cũng là một cách tốt để bắt đầu.

    Mặc dù không được ghi nhận như có lẽ người mới bắt đầu sẽ đánh giá cao, cả LMDB và HDF5 đều có cộng đồng người dùng lớn, do đó, một tìm kiếm sâu hơn của Google thường mang lại kết quả hữu ích.

    Một cái nhìn quan trọng hơn về việc thực hiện

    Không có điều gì không tưởng trong các hệ thống lưu trữ, và cả LMDB và HDF5 đều có phần cạm bẫy.

    Một điểm quan trọng để hiểu về LMDB là dữ liệu mới được viết mà không ghi đè hoặc di chuyển dữ liệu hiện có. Đây là một quyết định thiết kế cho phép đọc cực kỳ nhanh mà bạn đã chứng kiến ​​trong các thử nghiệm của chúng tôi và cũng đảm bảo tính toàn vẹn và độ tin cậy của dữ liệu mà không cần thêm nhật ký giao dịch.without overwriting or moving existing data. This is a design decision that allows for the extremely quick reads you witnessed in our experiments, and also guarantees data integrity and reliability without the additional need of keeping transaction logs.

    Tuy nhiên, hãy nhớ rằng bạn cần xác định tham số

    from PIL import Image
    import csv
    
    def store_single_disk(image, image_id, label):
        """ Stores a single image as a .png file on disk.
            Parameters:
            ---------------
            image       image array, (32, 32, 3) to be stored
            image_id    integer unique ID for image
            label       image label
        """
        Image.fromarray(image).save(disk_dir / f"{image_id}.png")
    
        with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
            writer = csv.writer(
                csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([label])
    
    3 để phân bổ bộ nhớ trước khi ghi vào cơ sở dữ liệu mới? Đây là nơi LMDB có thể là một rắc rối. Giả sử bạn đã tạo ra một cơ sở dữ liệu LMDB và mọi thứ đều tuyệt vời. Bạn đã kiên nhẫn chờ đợi bộ dữ liệu khổng lồ của mình được đóng gói vào LMDB.

    Sau đó, sau đó xuống dòng, bạn nhớ rằng bạn cần thêm dữ liệu mới. Ngay cả với bộ đệm bạn đã chỉ định trên

    from PIL import Image
    import csv
    
    def store_single_disk(image, image_id, label):
        """ Stores a single image as a .png file on disk.
            Parameters:
            ---------------
            image       image array, (32, 32, 3) to be stored
            image_id    integer unique ID for image
            label       image label
        """
        Image.fromarray(image).save(disk_dir / f"{image_id}.png")
    
        with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
            writer = csv.writer(
                csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([label])
    
    3 của mình, bạn có thể dễ dàng thấy lỗi
    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    15. Trừ khi bạn muốn viết lại toàn bộ cơ sở dữ liệu của mình, với
    from PIL import Image
    import csv
    
    def store_single_disk(image, image_id, label):
        """ Stores a single image as a .png file on disk.
            Parameters:
            ---------------
            image       image array, (32, 32, 3) to be stored
            image_id    integer unique ID for image
            label       image label
        """
        Image.fromarray(image).save(disk_dir / f"{image_id}.png")
    
        with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
            writer = csv.writer(
                csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([label])
    
    3 được cập nhật, bạn sẽ phải lưu trữ dữ liệu mới đó trong một tệp LMDB riêng biệt. Mặc dù một giao dịch có thể kéo dài nhiều tệp LMDB, nhưng có nhiều tệp vẫn có thể là một nỗi đau.

    Ngoài ra, một số hệ thống có hạn chế về số lượng bộ nhớ có thể được yêu cầu cùng một lúc. Theo kinh nghiệm của riêng tôi, làm việc với các hệ thống điện toán hiệu suất cao (HPC), điều này đã tỏ ra vô cùng bực bội và thường khiến tôi thích HDF5 hơn LMDB.

    Với cả LMDB và HDF5, chỉ có mục được yêu cầu được đọc vào bộ nhớ cùng một lúc. Với LMDB, các cặp đơn vị khóa được đọc vào bộ nhớ từng cái một, trong khi với HDF5, đối tượng

    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    17 có thể được truy cập như một mảng Python, với việc lập chỉ mục
    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    18, phạm vi,
    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    19 và các kết nối khác
    ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
    
    20.

    Do cách các hệ thống được tối ưu hóa và tùy thuộc vào hệ điều hành của bạn, thứ tự bạn truy cập các mục có thể ảnh hưởng đến hiệu suất.

    Theo kinh nghiệm của tôi, nói chung là đối với LMDB, bạn có thể có được hiệu suất tốt hơn khi truy cập các mục theo tuần tự bằng khóa (các cặp giá trị khóa được giữ trong bộ nhớ được đặt hàng theo chữ cái bằng khóa) và đối với HDF5, việc truy cập các phạm vi lớn sẽ hoạt động tốt hơn so với đọc Mỗi yếu tố của tập dữ liệu một bằng cách sử dụng một cách sau:

    import numpy as np
    import pickle
    from pathlib import Path
    
    # Path to the unzipped CIFAR data
    data_dir = Path("data/cifar-10-batches-py/")
    
    # Unpickle function provided by the CIFAR hosts
    def unpickle(file):
        with open(file, "rb") as fo:
            dict = pickle.load(fo, encoding="bytes")
        return dict
    
    images, labels = [], []
    for batch in data_dir.glob("data_batch_*"):
        batch_data = unpickle(batch)
        for i, flat_im in enumerate(batch_data[b"data"]):
            im_channels = []
            # Each image is flattened, with channels in order of R, G, B
            for j in range(3):
                im_channels.append(
                    flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
                )
            # Reconstruct the original image
            images.append(np.dstack((im_channels)))
            # Save the label
            labels.append(batch_data[b"labels"][i])
    
    print("Loaded CIFAR-10 training set:")
    print(f" - np.shape(images)     {np.shape(images)}")
    print(f" - np.shape(labels)     {np.shape(labels)}")
    
    8

    Nếu bạn đang xem xét lựa chọn định dạng lưu trữ tệp để viết phần mềm của bạn xung quanh, sẽ không được đề cập đến việc di chuyển ra khỏi HDF5 bởi Cyrille Rossant về những cạm bẫy của HDF5 và phản ứng của Konrad Hinsen về HDF5 và tương lai của quản lý dữ liệu, trong đó cho thấy làm thế nào một số cạm bẫy có thể tránh được trong các trường hợp sử dụng của chính mình với nhiều bộ dữ liệu nhỏ hơn là một vài cạm bẫy. Lưu ý rằng một bộ dữ liệu tương đối nhỏ hơn vẫn có kích thước GB.

    Tích hợp với các thư viện khác

    Nếu bạn xử lý các bộ dữ liệu thực sự lớn, thì rất có thể bạn sẽ làm điều gì đó có ý nghĩa với chúng. Nó có giá trị để xem xét các thư viện học tập sâu và loại tích hợp nào với LMDB và HDF5.

    Trước hết, tất cả các thư viện đều hỗ trợ đọc hình ảnh từ đĩa dưới dạng các tệp

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4, miễn là bạn chuyển đổi chúng thành các mảng numpy của định dạng dự kiến. Điều này đúng với tất cả các phương pháp, và chúng tôi đã thấy ở trên rằng việc đọc trong hình ảnh dưới dạng tương đối đơn giản.

    Dưới đây là một số thư viện học tập sâu phổ biến nhất và tích hợp LMDB và HDF5 của họ:

    • Caffe có tích hợp LMDB ổn định, được hỗ trợ tốt và nó xử lý bước đọc trong suốt. Lớp LMDB cũng có thể dễ dàng được thay thế bằng cơ sở dữ liệu HDF5. has a stable, well-supported LMDB integration, and it handles the reading step transparently. The LMDB layer can also easily be replaced with a HDF5 database.

    • Keras sử dụng định dạng HDF5 để lưu và khôi phục các mô hình. Điều này ngụ ý rằng Tensorflow cũng có thể. uses the HDF5 format to save and restore models. This implies that TensorFlow can as well.

    • TensorFlow có lớp tích hợp

      ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
      
      22 cung cấp giao diện để đọc dữ liệu đầu vào từ tệp LMDB và có thể tạo trình lặp và tenxơ theo các đợt. TensorFlow không có lớp tích hợp cho HDF5, nhưng người ta có thể được viết kế thừa từ lớp
      ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
      
      23. Cá nhân tôi sử dụng một lớp tùy chỉnh hoàn toàn được thiết kế để truy cập đọc tối ưu dựa trên cách tôi cấu trúc các tệp HDF5 của mình.
      has a built-in class
      ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
      
      22 that provides an interface for reading in input data from an LMDB file and can produce iterators and tensors in batches. TensorFlow does not have a built-in class for HDF5, but one can be written that inherits from the
      ax.view_init(elev=elevation_angle, azim=azimuthal_angle)
      
      23 class. I personally use a custom class altogether that is designed for optimal read access based on the way I structure my HDF5 files.

    • Theano không hỗ trợ bất kỳ định dạng tệp hoặc cơ sở dữ liệu cụ thể nào, nhưng như đã nêu trước đây, có thể sử dụng bất cứ điều gì miễn là nó được đọc dưới dạng một mảng chiều n. does not natively support any particular file format or database, but as previously stated, can use anything as long as it is read in as an N-dimensional array.

    Mặc dù xa toàn diện, nhưng điều này hy vọng sẽ mang lại cho bạn cảm giác tích hợp LMDB/HDF5 bởi một số thư viện học tập sâu quan trọng.

    Một vài hiểu biết cá nhân về lưu trữ hình ảnh trong Python

    Trong công việc hàng ngày của riêng tôi phân tích terabyte của hình ảnh y tế, tôi sử dụng cả LMDB và HDF5, và đã học được rằng, với bất kỳ phương pháp lưu trữ nào, được coi là rất quan trọng.forethought is critical.

    Thông thường, các mô hình cần được đào tạo bằng cách sử dụng xác thực chéo K, liên quan đến việc chia toàn bộ bộ dữ liệu thành các bộ K (K thường là 10) và các mô hình K được đào tạo, mỗi mô hình có một bộ K khác nhau được sử dụng làm bộ thử nghiệm. Điều này đảm bảo rằng mô hình không quá mức dữ liệu, hoặc, nói cách khác, không thể đưa ra dự đoán tốt về dữ liệu chưa từng thấy.

    Một cách tiêu chuẩn để tạo ra một tập hợp K là đặt một biểu diễn bình đẳng của từng loại dữ liệu được biểu diễn trong bộ dữ liệu trong mỗi bộ K. Do đó, lưu mỗi bộ K vào một bộ dữ liệu HDF5 riêng biệt tối đa hóa hiệu quả. Đôi khi, một bộ K duy nhất không thể được tải vào bộ nhớ cùng một lúc, do đó, ngay cả việc đặt hàng dữ liệu trong bộ dữ liệu cũng yêu cầu một số suy nghĩ.

    Với LMDB, tôi cũng cẩn thận lên kế hoạch trước trước khi tạo (các) cơ sở dữ liệu. Có một vài câu hỏi hay đáng để hỏi trước khi bạn lưu hình ảnh:

    • Làm thế nào tôi có thể lưu các hình ảnh sao cho hầu hết các lần đọc sẽ được tuần tự?
    • Chìa khóa tốt là gì?
    • Làm thế nào tôi có thể tính toán
      from PIL import Image
      import csv
      
      def store_single_disk(image, image_id, label):
          """ Stores a single image as a .png file on disk.
              Parameters:
              ---------------
              image       image array, (32, 32, 3) to be stored
              image_id    integer unique ID for image
              label       image label
          """
          Image.fromarray(image).save(disk_dir / f"{image_id}.png")
      
          with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
              writer = csv.writer(
                  csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
              )
              writer.writerow([label])
      
      3 tốt, dự đoán các thay đổi tiềm năng trong tương lai trong bộ dữ liệu?
    • Một giao dịch có thể lớn đến mức nào và các giao dịch nên được chia nhỏ như thế nào?

    Bất kể phương pháp lưu trữ nào, khi bạn xử lý các bộ dữ liệu hình ảnh lớn, một kế hoạch nhỏ đi một chặng đường dài.

    Sự kết luận

    Bạn đã làm cho nó đến cùng! Bây giờ bạn đã có một cái nhìn chim chim về một chủ đề lớn.

    Trong bài viết này, bạn đã được giới thiệu ba cách lưu trữ và truy cập nhiều hình ảnh trong Python, và có lẽ có cơ hội chơi với một số trong số chúng. Tất cả các mã cho bài viết này là trong một cuốn sổ tay Jupyter ở đây hoặc tập lệnh Python ở đây. Chạy có nguy cơ của riêng bạn, vì một vài GB không gian đĩa của bạn sẽ bị vượt qua bởi những hình ảnh vuông nhỏ của xe hơi, thuyền, v.v.

    Bạn đã thấy bằng chứng về cách các phương pháp lưu trữ khác nhau có thể ảnh hưởng đáng kể đến thời gian đọc và ghi, cũng như một vài ưu và nhược điểm của ba phương pháp được xem xét trong bài viết này. Mặc dù lưu trữ hình ảnh dưới dạng các tệp

    from pathlib import Path
    
    disk_dir = Path("data/disk/")
    lmdb_dir = Path("data/lmdb/")
    hdf5_dir = Path("data/hdf5/")
    
    4 có thể là trực quan nhất, có những lợi ích hiệu suất lớn khi xem xét các phương pháp như HDF5 hoặc LMDB.

    Vui lòng thảo luận trong phần Nhận xét Các phương pháp lưu trữ tuyệt vời không được đề cập trong bài viết này, chẳng hạn như LevelDB, Feather, TileB, Badger, Boltdb hoặc bất cứ điều gì khác. Không có phương pháp lưu trữ hoàn hảo và phương pháp tốt nhất phụ thuộc vào bộ dữ liệu cụ thể của bạn và các trường hợp sử dụng.There is no perfect storage method, and the best method depends on your specific dataset and use cases.

    Đọc thêm

    Dưới đây là một số tài liệu tham khảo liên quan đến ba phương pháp được đề cập trong bài viết này:

    • Python ràng buộc cho LMDB
    • Tài liệu LMDB: Bắt đầu
    • Liên kết Python cho HDF5 (H5PY)
    • Nhóm HDF5
    • Cấm Python và HDF5 từ O hèReilly
    • Cái gối

    Bạn cũng có thể đánh giá cao sự phân tích của các hệ thống lưu trữ hình ảnh để đào tạo các mạng lưới thần kinh sâu có thể mở rộng của Lim, Young và Patton. Giấy đó bao gồm các thí nghiệm tương tự như những bài trong bài viết này, nhưng ở quy mô lớn hơn nhiều, xem xét bộ đệm lạnh và ấm áp cũng như các yếu tố khác.

    Làm thế nào để bạn tăng độ phân giải trong Python?

    Để thực hiện điều này, trong thiết bị đầu cuối của bạn, hãy chạy lệnh bên dưới nếu bạn không được cài đặt sẵn ...
    PIP Cài đặt OpenCV-Python. ....
    Pip cài đặt Numpy. ....
    Pip Cài đặt gối. ....
    C: \ Users \ Lizpa \ PyCharmProjects \ Jupyter \ Venv \ Scripts \ Python.exe -M Pip Cài đặt -nâng cấp Pip ..

    Làm thế nào để tôi tăng chất lượng của một âm mưu python?

    Đặt kích thước hình và điều chỉnh phần đệm giữa và xung quanh các ô phụ ..
    Tạo ra một raster dữ liệu 2D bằng NP. mảng..
    Hiển thị dữ liệu dưới dạng hình ảnh, tức là, trên một raster thường xuyên 2D ..
    Lưu hình ảnh hiện tại bằng SaveFig () với DPI = 1200 và. Định dạng EPS,.
    Để hiển thị hình, sử dụng phương thức show () ..

    Làm cách nào để lưu một hình ảnh dưới dạng JPEG trong Python?

    Lưu một hình ảnh Mở hình ảnh đơn giản như gọi phương thức Open ().Tiết kiệm một hình ảnh trong Python cũng đơn giản như vậy.Bạn chỉ cần gọi Save () và truyền trong tên bạn muốn được sử dụng để lưu hình ảnh của bạn.Phương thức này sẽ lưu hình ảnh theo định dạng được xác định bởi phần mở rộng trên tên tệp bạn truyền vào.call save() and pass in the name you want used to save your image. This method will save the image in the format identified by the extension on the filename you pass in.

    SaveFig PLT DPI là gì?

    DPI trong SaveFig là gì?SaveFig (Tên tệp, DPI = Không) để lưu MatPlotLib.Hình Pyplot là một hình ảnh có tên Filename với độ phân giải DPI tính bằng các chấm trên mỗi inch.Giá trị DPI cao như 200 trở lên cho thấy hình ảnh có độ phân giải cao, trong khi giá trị DPI thấp như 10 cho thấy hình ảnh độ phân giải thấp hơn.dots per inch. A high dpi value such as 200 or more indicates a high resolution image, while a low dpi value such as 10 indicates a lower resolution image.