使用h5py庫讀寫超過內存的大數據
思路
在簡單數據的讀操作中,我們通常一次性把數據全部讀入到內存中。讀寫超過內存的大數據時,有別於簡單數據的讀寫操作,受限於內存大小,通常需要指定位置、指定區域讀寫操作,避免無關數據的讀寫。
h5py庫剛好可以實現這一功能。
h5py讀寫小數據示例
import h5py
X= np.random.rand(100, 1000, 1000).astype('float32')
y = np.random.rand(1, 1000, 1000).astype('float32')
h5f = h5py.File('data.h5', 'w')
h5f.create_dataset('X_train', data=X)
h5f.create_dataset('y_train', data=y)
h5f.close()
# Load hdf5 dataset
h5f = h5py.File('data.h5', 'r')
X = h5f['X_train']
Y = h5f['y_train']
h5f.close()
主要操作路線
- 打開文件頭與文件中的數據頭
- 預留存儲空間判斷
- 數據指定位置賦值
- | mode |
---|---|
r | Readonly, file must exist |
r+ | Read/write, file must exist |
w | Create file, truncate if exists |
w- or x | Create file, fail if exists |
a | Read/write if exists, create otherwise (default) |
分塊讀寫示例
import sys
import h5py
import numpy as np
def save_h5(times=0):
if times == 0:
h5f = h5py.File('data.h5', 'w')
dataset = h5f.create_dataset("data", (100, 1000, 1000),
maxshape=(None, 1000, 1000),
# chunks=(1, 1000, 1000),
dtype='float32')
else:
h5f = h5py.File('data.h5', 'a')
dataset = h5f['data']
# 關鍵:這里的h5f與dataset並不包含真正的數據,
# 只是包含了數據的相關信息,不會占據內存空間
#
# 僅當使用數組索引操作(eg. dataset[0:10])
# 或類方法.value(eg. dataset.value() or dataset.[()])時數據被讀入內存中
a = np.random.rand(100, 1000, 1000).astype('float32')
# 調整數據預留存儲空間(可以一次性調大些)
dataset.resize([times*100+100, 1000, 1000])
# 數據被讀入內存
dataset[times*100:times*100+100] = a
# print(sys.getsizeof(h5f))
h5f.close()
def load_h5():
h5f = h5py.File('data.h5', 'r')
data = h5f['data'][0:10]
# print(data)
if __name__ == '__main__':
# save_h5(0)
for i in range(20):
save_h5(i)
# 部分數據導入內存
load_h5()
腳本在第一次保存時設置為創建模式,之后調整為追加模式。
完整項目實戰
有人可能會有疑惑,你說了這么多,但我還是不知道這玩意到底該怎么用。
別急,基於keras框架與SRCNN網絡,利用HDF5庫能夠讀寫超過內存的大數據的特點,我自己寫了個單圖像超分辨率demo以供參考。
https://github.com/JiJingYu/SRCNN-keras-hdf5
補充資料
- h5py項目主頁
http://www.h5py.org/ - github上的h5py例程合集
https://github.com/quintusdias/hdf5examples - 基於tensorflow框架實現DNN網絡cifar10數據集分類demo
https://github.com/tensorflow/tensorflow/blob/r1.0/tensorflow/examples/learn/hdf5_classification.py