使用python操作HDF5文件

  • 2021 年 11 月 9 日
  • 筆記

HDF

Hierarchical Data Format,又稱HDF5

  1. 在深度學習中,通常會使用巨量的數據或圖片來訓練網路。對於如此大的數據集,如果對於每張圖片都單獨從硬碟讀取、預處理、之後再送入網路進行訓練、驗證或是測試,這樣效率太低。如果將這些圖片都放入一個文件中再進行處理效率會更高。有多種數據模型和庫可完成這種操作,如HDF5和TFRecord。

  1. 一個HDF5文件是一種存放兩類對象的容器:dataset和group. Dataset是類似於數組的數據集,而group是類似文件夾一樣的容器,存放dataset和其他group。在使用h5py的時候需要牢記一句話:groups類比詞典,dataset類比Numpy中的數組。

  2. img

  1. HDF5 文件一般以 .h5 或者 .hdf5 作為後綴名,需要專門的軟體才能打開預覽文件的內容。HDF5 文件結構中有 2 primary objects: Groups 和 Datasets。

  1. 每個 dataset 可以分成兩部分: 原始數據 (raw) data values 和 元數據 metadata (a set of data that describes and gives information about other data => raw data)。對於每一個dataset 而言,除了數據本身之外,這個數據集還會有很多的屬性 attribute,。在hdf5中,還同時支援存儲數據集對應的屬性資訊,所有的屬性資訊的集合就叫做metadata.

  2. img

安裝:

pip install h5py

對於數據集需要: 先創建h5文件,再去讀h5文件 將dataset放在group里利用group進行層次嵌套.

1 f = filename.file得到文件的根目錄
2 f.create_group("...../group_name")
3 f.create_dataset("...../dataset_name")

 

 

一般:

  1. HDF5格式文件保存的是 : Model weights(字典,沒有順序)

  2. JSON 和 YAML 格式文件保存的是: Model structure(順序靠json描述)

  3. h5格式:可以同時保存weights和structure

利用numpy數據初始化

1 #還可以直接用np數組給dataset初始化,此時data就涵蓋了shape和dtype,即shape = data.shape,....
2 arr = np.arange(100)
3 dset = f.create_dataset("/mydataset1",data = arr)#i4:32位的integer[-2^31,2^31]

 

 

數據處理上的用途

利用python的文件操作及數組等方式將訓練數據及測試數據集標籤,按數據劃分方法,將文件名寫入到python數組,最終將這些處理好的數組寫入hdf5格式文件給dataset初始化.

示例

 1 import h5py
 2 import numpy as np
 3 coco = h5py.File("D:/annot_coco.h5","r")#coco.name == / 根節點
 4 # print(coco)
 5 # print(coco["bndbox"])
 6 #只是遍歷直接相連的一級節點
 7 for name in coco:
 8     # 本身就是字元串
 9     print(coco[name])
10     print(coco[name][:2])
11 12 # def printname(name):
13 #     print(name)
14 #
15 #
16 #
17 # #遍歷整個coco下的節點
18 # coco.visit(printname)
19 #dataset.attrs
20 #dataset對象可以有自己的屬性, 但所有屬性數據的長度加起來不能超過64K, 包括屬性名字.
21 22 dset.attrs['length'] = 100
23 dset.attrs['name'] = 'This is a dataset'
24 for attr in dset.attrs:
25     print attr, ":", dset.attrs[attr]
26 length : 100
27 name : This is a dataset

 

 

注意:

1 imgname_array = coco["imgname"][:]#不一樣的,這是標準用法,還是要先取到全部,再去索引,否則結果維度不一樣
2 # imgname_ = coco["imgname"][:1]#軸不會減少
3 # print(imgname_array.shape)
4 # print(imgname_)#[1,16]
5 # print(type(imgname_dataset))
6 # print(type(imgname_array))
7 img = imgname_array[0]

 

 

寫字元串到h5文件

1 test_h5 = h5py.File("D:/test.h5","w")
2 imgname = np.fromstring('000000262145.jpg',dtype=np.uint8).astype('float64')#str_imgname------>float64
3 test_h5 .create_dataset('imgname', data=imgname)#變成f8之後就可以直接往h5中寫了
4 test_h5.close()
5 """
6 最後得出來的矩陣長度是字元串的長度。---1個字元串的長度就是對應編碼的h5向量的長度
7 如果想將多個字元串拼成一個大的numpy矩陣,寫到h5文件中,必須先將字元串轉換成相同長度。
8 通常的做法是在字元串後面補上\x00。
9 """

 

 

從h5數據讀出字元串格式

1 test_h5 = h5py.File("D:/test.h5","r")
2 img = test_h5['imgname'][:]
3 img = img.astype(np.uint8).tostring().decode('ascii')
4 print(img)
5 test_h5.close()