當你的數據集是hdf5格式的文件時,腫么辦?


最近,自己構建了一個卷積神經網絡,從網上下載到的數據集是hdf5格式的,希望用這個數據集來訓練一下自己構建的這個神經網絡。

1. 什么是hdf5?

HDF5是二進制數據格式,用於在磁盤上存儲巨大的數值數據集(數據太大無法存儲在內存中),同時便於對數據集的行進行遍歷和計算。HDF5中的數據是分層存儲的,類似於文件系統存儲數據的方式。它可以存儲兩類數據對象;
1.dataset:類比於文件系統中的文件,可以操作list/ndarray的方式老操作它
2.group:類比於文件系統的文件夾,可以用操作dict的方式來操作它

數據是定義在group中,group類似層次容器的結構,可以包含零個或多個group或dataset的實例,以及支持元數據(metadata)。一旦定義了一個group,就可以在group中創建一個dataset。dataset可以理解為是一個多維數組(例如一個NumPy數組),注意:同一個多維數組中數據類型是相同的(整數、浮點數、unicode等)。圖3.2顯示了一個包含具有多個dataset的group的HDF5文件示例。本文我們將編寫一個定制的Python類,使我們能夠有效地接受輸入數據並將其寫入HDF5數據集。

圖3.2

HDF5是用C編寫的,但是,通過使用h5py模塊(h5py.org),我們可以使用Python編程語言訪問底層的C語言API。h5py之所以如此出色,是因為它易於與數據交互。我們可以在HDF5數據集中存儲大量數據,並以類似於numpy的方式操作數據。例如,我們可以使用標准的Python語法訪問和分割存儲在磁盤上的tb級別數據集中的行,像加載到內存中操作一樣簡單。由於特殊的數據結構,這些分片和行訪問速度非常快。當使用HDF5和h5py時,你可以將數據看作一個巨大的NumPy數組,雖然數據太大無法加載到內存中,但是仍然可以像在內存一樣的訪問和操作數據。

這個標准庫最主要的一點在於開發者對它的積極維護以及在向下兼容方面花費的巨大精力。標准庫的向下兼容不僅僅是API的兼容,亦包括文件格式的兼容,這意味着以HDF5格式存儲的數據集本質上是可移植性的,可以被使用不同編程語言(如C、MATLAB和Java)的其他開發人員訪問。

2. 如何使用hdf5?

上面我們已經知道了什么是hdf5文件以及他需要用h5py庫來處理,但是,如何把數據送到神經網絡中訓練呢?

data_path = ""
import h5py

with h5py.File("{}".format(data_path),"r") as f:
    col_list = []
    f.visit(col_list.append)
    print("{}文件的group包括:{}\n".format(data_path, col_list))
    for i in col_list:
        data_i = f["{}".format(i)]

此時,我們已經將hdf5文件中的各個group用不同的變量保存起來,那么下來該怎么做呢?本人沒有理解hdf5文件的精髓(由於數據太大的情況下,電腦無法同時將數據加載到電腦的運行內存上,所以出現了hdf5文件來解決這個問題),把提取出的各個group寫到了txt文件中,結果原本5G左右的數據一下飆升到30G左右,因此,我們需要直接將該文件遞交給深度神經網絡來訓練。上述代碼說明了如何訪問以及提取各個group接下來說說如何使用。

# 上面的操作形式讓我們想起了使用open()函數對txt文件的操作,沒錯,我們還可以用另外一種形式對文件進行操作,這種方法在jupyter notebook環境中更是棒棒的

hdf5_file = h5py.File("{}".format(data_path),"r")
col_list = []
hdf5_file.visit(col_list.append)
print("{}文件的group包括:{}\n".format(data_path, col_list))
for i in col_list:
    data_i = hdf5_file["{}".format(i)]
# 假設該hdf5文件中含有的group有"X"、"Y",且"X"表示訓練數據,"Y"表示標簽
# 使用zip()函數將二者合在一起,用於訓練集、測試集的划分,或許還有別的辦法,希望讀者能夠提供
data = list(zip(data_X,data_Y))

from sklearn.model_selection import train_test_split
train,test = train_test_spilt(data)

x_train,y_train = zip(*train)
x_test,y_test = zip(*test)

# 理論上上述命令操作之后已經構建成功了訓練集、測試集,但是當把他們導入模型時,出了問題
# 報錯:TypeError:Error when checking input data: it should be numpy array, or list/dict.Found:(array(****************))
# 大致是這么個意思,由於之前的問題解決了,搜索的網頁沒有保留
# 該問題的主要原因是經過zip操作之后,將原來的array格式的數據變成了元組形式,我們主要把他們變回去就好了

x_train_lst = list(x_train)
y_train_lst = list(y_train)

x_test_lst = list(x_test)
y_test_lst = list(y_test)

# 這樣就可以了,可以把他們送入模型中
from keras.models import Model
from keras.layers import Input

# 最簡單的模型
input = Input((max_len,))
output = Dense()(input)

model = Model(inputs=input, outputs=output)
model.compile(optimizer="adam",loss="MSE",metrics=["accuracy"])

history = model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          callbacks=my_callbacks,
          validation_data=(x_test, y_test))

# 完成,關閉hdf5文件
hdf5_file.close()

對於keras構建模型,可以看這篇文章,keras構建1D卷積神經網絡


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM