【问题标题】:How to deal with large amount of HDF5 files in Google Cloud Machine Learning?如何处理谷歌云机器学习中的大量 HDF5 文件?
【发布时间】:2018-03-20 12:33:37
【问题描述】:

我有大约 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 存储桶中的文件结构。它在本地使用带有小模型的 python 工作,但现在我想利用 Google ML 超参数调整功能,因为我的模型要大得多。问题是我在互联网上读到 HDF5 文件无法直接轻松地从 Google ML 存储中读取。我试图像这样修改我的脚本:

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

但它给了我类似于 error UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte 的错误,只是其他十六进制和位置 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)创建的泡菜加载到内存似乎效率不高。

【问题讨论】:

  • 尝试阅读模式 rb 而不是 r。我猜 r 试图将数据解释为字符串。
  • 这就是我尝试过的,它在一定程度上有效,但后来出现了一些错误,我可能会再次检查它。问题是当我从mat 文件中打印字节字符串时,一开始有一行描述了文件属性、创建文件的 Matlab 版本等。
  • 格式文件使用docs.scipy.org/doc/scipy/reference/generated/… 这应该是最简单的阅读方式了。为什么你创建了这么多文件而不是创建一个包含所有数据的简单数据集?读起来会很慢,但不是因为hdf5。通过网络访问数据具有很高的延迟。还可以看看stackoverflow.com/a/44961222/4045774 这将显示块大小对 I/O 速度的影响。通过网络,您将需要相当大的块大小才能获得良好的性能。
  • 我使用的是别人创建的Matlab脚本,并没有真正看到里面发生了什么
  • 如果将“arr = np.fromstring(input_f.read())”替换为“arr = scipy.io.loadmat(input_f.read())”真的不行吗?也试试“arr = scipy.io.loadmat(input_f)”

标签: python tensorflow h5py google-cloud-ml


【解决方案1】:

HDF 是一种非常常见的文件格式,不幸的是,它在云中并不是最佳的。有关原因的一些解释,请参阅this 博客文章。

鉴于云上 HDF 的固有复杂性,我建议采用以下方法之一:

  1. 将您的数据转换为另一种文件格式,例如 CSV 或 tf.Example 的 TFRecord
  2. 将数据本地复制到/tmp

转换充其量是不方便的,而且,对于某些数据集,可能需要体操。在互联网上的粗略搜索发现了多个关于如何做到这一点的教程。 Here's one你可以参考。

同样,有多种方法可以将数据复制到本地计算机,但请注意,在复制数据之前,您的工作不会开始进行任何实际训练。此外,如果其中一名工人死亡,它必须在再次启动时重新复制所有数据。如果 master 死了,而你正在进行分布式训练,这可能会导致大量工作丢失。

也就是说,如果您认为这在您的情况下是一种可行的方法(例如,您没有进行分布式训练和/或您愿意等待如上所述的数据传输),只需启动您的 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']) 

【讨论】:

    【解决方案2】:

    从类似文件的临时对象中读取数据

    我没有直接访问 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)
    

    【讨论】:

    • 您不必拥有访问权限。 Google ML 使用 Tensorflow,所以技术上的问题是“在 Tensorflow 中读取 HDF5 文件”。至少我猜是这样。无论如何,我想我将创建一个巨大的 CSV 文件而不是数千个文件,我认为这会更容易。
    • 你不能把一个简单的numpy-array放到tensorflow上吗?如此处所述stackoverflow.com/q/37620330/4045774 或者您没有正常的方式来访问文件?那么如何访问 csv 文件呢?如果是这样,我会在这里放弃。从二进制数据中写入csv文件(文本文件)然后解析它,就像打印电子书然后扫描它......
    • 可以,但无法读取 Google ML 中的 HDF5 文件,但可以读取 CSV
    • 然后使用 TFRecords 文件格式。 machinelearninguru.com/deep_learning/tensorflow/basics/tfrecord/… 必须避免使用文本文件存储数 GB 大小的数据,您不会对此感到满意。它会炸毁数据的整体大小,并且读写速度将远非最佳。
    • 好的,会检查的
    猜你喜欢
    • 2017-08-03
    • 2018-09-23
    • 2016-01-11
    • 2018-06-01
    • 2013-06-23
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    • 2018-01-31
    相关资源
    最近更新 更多