如何处理Google Cloud Machine Learning中大量的HDF5文件?
如何处理Google Cloud Machine Learning中大量的HDF5文件?
我有大约5k个原始数据输入文件和15k个原始数据测试文件,总共几个GB。由于这些是原始数据文件,我必须在Matlab中迭代处理它们,以便获得我想要用来训练我的实际分类器(CNN)的特征。因此,我为每个原始数据文件生成了一个HDF5 mat文件。我使用Keras在本地开发了我的模型,并修改了DirectoryIterator,在其中有类似以下内容的东西
for i, j in enumerate(batch_index_array): arr = np.array(h5py.File(os.path.join(self.directory, self.filenames[j]), "r").get(self.variable)) # process them further
文件结构如下
| |--train | |--Class1 | | |-- 2,5k .mat files | | | |--Class2 | |-- 2,5k .mat files |--eval | |--Class1 | | |-- 2k .mat files | | | |--Class2 | |-- 13k .mat files
这是我现在在Google ML Storage存储桶中拥有的文件结构。使用小模型在本地工作,但现在我想利用Google ML超参数调整功能,因为我的模型更大了。问题是,我在互联网上读到HDF5文件不能直接从Google ML Storage中轻松读取。我试图修改我的脚本如下:
import tensorflow as tf from tensorflow.python.lib.io import file_io for i, j in enumerate(batch_index_array): with file_io.FileIO((os.path.join(self.directory, self.filenames[j], mode='r') as input_f: arr = np.array(h5py.File(input_f.read(), "r").get(self.variable)) # process them further
但它给我一个错误,类似于这个错误UnicodeDecodeError:\'utf-8\'编解码器无法解码字节0xff在位置0处:无效的起始字节,只是其他十六进制和位置512的错误。
我还有类似于这样的东西:
import tensorflow as tf from tensorflow.python.lib.io import file_io for i, j in enumerate(batch_index_array): with file_io.FileIO((os.path.join(self.directory, self.filenames[j], mode='rb') as input_f: arr = np.fromstring(input_f.read()) # process them further
但它也无法工作。
问题
我该如何修改我的脚本以能够在Google ML中读取这些HDF5文件?我知道数据捕捉练习,但问题是从15k个文件(几GB)创建的pickle加载到内存中似乎不太有效率。
从类似于临时文件的对象中读取数据
我没有直接访问Google ML的权限,如果这个答案不起作用,我要道歉。我曾经尝试过直接从被压缩的文件夹中读取h5文件,但我希望这里也能起作用。
from scipy import io import numpy as np from io import BytesIO #Creating a Testfile Array=np.random.rand(10,10,10) d = {"Array":Array} io.savemat("Test.mat",d) #Reading the data using a in memory file-like object with open('Test.mat', mode='rb') as input_f: output = BytesIO() num_b=output.write(input_f.read()) ab = io.loadmat(output)
HDF是一种非常常用的文件格式,不幸的是,它不太适合在云环境中使用。有关具体原因,请参见此博客文章。
鉴于HDF在云端的固有复杂性,我建议采用以下方法之一:
- 将您的数据转换为另一种文件格式,例如CSV或TFRecord of tf.Example
- 将数据复制到本地计算机的/tmp目录下
转换可能会有不便之处,对于某些数据集,可能需要进行一些复杂操作。简单搜索互联网上可以发现多个教程。您可以参考这个。
同样,有多种方法可以将数据复制到本地计算机上,但请注意,在数据复制完成之前,您的工作任务将不会开始进行任何实际训练。此外,如果工作进程崩溃,其将必须在重新启动时重新复制所有数据。如果主服务器崩溃,并且您正在进行分布式训练,那么可能会丢失很多工作量。
尽管如此,如果您觉得这是一种可行的方法(例如,您不进行分布式训练和/或愿意等待上述数据传输),只需使用类似以下命令启动Python:
import os import subprocess if os.environ.get('TFCONFIG', {}).get('task', {}).get('type') != 'ps': subprocess.check_call(['mkdir', '/tmp/my_files']) subprocess.check_call(['gsutil', '-m', 'cp', '-r', 'gs://my/bucket/my_subdir', '/tmp/myfiles'])