Khi làm việc với Deep Learning, bạn chuẩn bị tinh thần làm việc với đủ loại dữ liệu khác nhau: ảnh, số, text.... Sử dụng CSDL quan hệ có vẻ hơi thừa thãi bởi để huấn luyện chúng ta cần một bảng dữ liệu đã được phẳng hóa không còn liên kết chỉ mục đến bảng khác nữa. Trong bài này mình bàn tới chuẩn định dạng file HDF5  để lưu trữ, đọc dữ liệu.

Đặc điểm của HDF5 là:

  1. Dễ dàng chia sẻ vì nó ở dạng file mà !
  2. Truy vấn tốc độ cao và tiết kiệm dung lượng lưu trữ
  3. Đa nền tảng, thư viện thao tác HDF5 có nhiều ngôn ngữ như C/C++, Java, Python, Golang....
  4. Không giới hạn kích thước
  5. Lưu mô tả định dạng cùng với dữ liệu !

Với Python, Deep Learning, bạn đọc dữ liệu dạng mảng, ma trận Numpy hay dạng dictionary vào ra HDF5 rất dễ dàng.

Keras lưu hệ số weights các node sau khi huấn luyện vào file hd5.

# serialize model to JSON
model_json = model.to_json()
with open("model.json", "w") as json_file:
    json_file.write(model_json)
# serialize weights to HDF5
model.save_weights("model.h5")
print("Saved model to disk")

Line 4: lưu cấu trúc model ra file model.json
Line 6: lưu weight ra model.h5
Quá trình đọc ngược lại từ file vào Keras model như sau

# load json and create model
json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()


model = tf.keras.models.model_from_json(loaded_model_json)
# load weights into new model
model.load_weights("model.h5")


Lưu bổ các dữ liệu ảnh vào h5

Mình đang có một dự án nghịch sẽ kêu gọi cộng đồng (anh đi qua, chị đi lại) mỗi người vẽ vài chữ số từ 0 đến 9 để huấn luyện thay thế cho bộ chữ số MNIST. Ban đầu khiêm tốn là vậy, sau đó theo như anh Vũ Hữu Tiệp gợi ý nhờ mọi người vẽ ký tự chữ cái tiếng Việt.  Bộ dữ liệu này cũng chia sẻ lại.

Vấn đề đặt ra là làm sao lưu được các ảnh chữ số vào một mảng chứ không lưu ra từng file png nhỏ lẻ. Phần giao diện màn hình tôi đang vẽ giờ bằng SketchApp. Song song với đó, tôi thí nghiệm lấy một số ảnh từ dữ liệu MNIST, rồi lưu lại vào h5 xem sao. Chạy thử ứng dụng này ban đầu là ghi vào h5, sau đó đọc ra từ h5 rồi vẽ bằng MatplotLib khoảng 15 ảnh.

import h5py
import matplotlib.pyplot as plt
import numpy as np
from keras.datasets import mnist

# Load dữ liệu từ dữ liệuKeras mnist có sẵn trong
(_, _), (test_images, _) = mnist.load_data()

small_set = test_images[:15]  # Lấy ra 15 phần tử đầu tiên
file_name = 'smallset.h5'
dataset_name = 'mnist20'

h5f = h5py.File(file_name, 'w')  # Chuẩn bị file để ghi ra
h5f.create_dataset(dataset_name, data=small_set, maxshape=(100, 28, 28))  # Ghi small_set vào file
h5f.create_dataset("100numbers", data=np.random.randint(low=1, high=100, size=100))
h5f.close()

h5f = h5py.File(file_name, 'r')  # Giờ thì đọc ra
data = h5f[dataset_name][:]
numbers = h5f["100numbers"][:5]
h5f.close()

print(data.shape)
print(numbers)

# Xuất ra 15 ô trên
fig = plt.figure(figsize=(12, 8))
fig.subplots_adjust(hspace=0.3, wspace=0.1)

for i in range(data.shape[0]):
    axes = fig.add_subplot(3, 5, i + 1)
    axes.set(title="")
    axes.grid(False)
    axes.set_xticks([])
    axes.set_yticks([])

    axes.imshow(data[i], cmap='gray', vmin=0, vmax=255)

plt.show()

Rút ra được 2 điểm:

  1. h5 có thể lưu nhiều dataset có cấu trúc khác nhau. Cứ đặt tên riêng từng dataset là sẽ ghi vào và lấy ra được
  2. dataset có thể ghi thêm (append) các bản ghi mới, miễn là phải đúng cấu trúc

Chú ý line 16 h5f.create_dataset(dataset_name, data=small_set, maxshape=(100, 28, 28))
Tôi khai báo thêm lựa chọn maxshape=(100, 28, 28) để cho phép dataset có thể lưu đến 100 ảnh. Không có lựa chọn này, bạn sẽ không thể bổ xung dữ liệu thêm vào dataset sẵn có.

Bổ xung thêm dữ liệu vào h5

import h5py
from keras.datasets import mnist
import matplotlib.pyplot as plt

file_name = 'smallset.h5'
dataset_name = 'mnist20'

(_, _), (test_images, _) = mnist.load_data()
more_set = test_images[15:19]


h5f = h5py.File(file_name, 'a')
h5f[dataset_name].resize(h5f[dataset_name].shape[0] + more_set.shape[0], axis = 0)
h5f[dataset_name][-more_set.shape[0]:] = more_set
data = h5f[dataset_name]

Line 13: chỉnh lại kích thước, nới rộng ra bằng đúng kích thước dữ liệu sẽ thêm vào
Line 14: khoanh vùng dữ liệu tính từ điểm cuối và có kích thước bằng dữ liệu thêm vào, sau đó gán dữ liệu cần thêm vào vùng này...

h5 hỗ trợ đọc ghi xong xong từ nhiều process

Đây là một chức năng rất cần thiết của h5. Nếu không có nó, thì các tác vụ xử lý song song (parallel) khi đọc ghi vào ổ cứng sẽ biến thành tuần tự hết.
Tôi chưa có điều kiện thử nghiệm trong hôm này, để mai mốt khi hệ thống nhận dữ liệu đóng góp từ cộng đồng tối sẽ thực hiện