16

Google 最近发布了 Cloud ML,https: //cloud.google.com/ml/,它非常有用。然而,一个限制是 Tensorflow 程序的输入/输出应该支持 gs://。

如果我们使用所有 tensorflow API 来读/写文件,应该没问题,因为这些 API 支持gs://.

但是,如果我们使用原生文件 IO API,例如open,它就不起作用,因为它们不理解gs://

例如:

 with open(vocab_file, 'wb') as f:
        cPickle.dump(self.words, f)

此代码在 Google Cloud ML 中不起作用。

但是,将所有原生文件 IO API 修改为 tensorflow API 或 Google Storage Python API 确实很繁琐。有什么简单的方法可以做到这一点吗?gs://在本机文件 IO 之上支持谷歌存储系统的任何包装器?

正如这里所建议的,将腌制的 scipy 稀疏矩阵作为输入数据?,也许我们可以使用file_io.read_file_to_string('gs://...'),但这仍然需要大量的代码修改。

4

3 回答 3

17

Do it like this:

from tensorflow.python.lib.io import file_io

with file_io.FileIO('gs://.....', mode='w+') as f:
    cPickle.dump(self.words, f)

Or you can read pickle file in like this:

file_stream = file_io.FileIO(train_file, mode='r')
x_train, y_train, x_test, y_test  = pickle.load(file_stream)
于 2017-04-05T21:34:34.063 回答
9

一种解决方案是在程序启动时将所有数据复制到本地磁盘。您可以在运行的 Python 脚本中使用 gsutil 来执行此操作,例如:

vocab_file = 'vocab.pickled'
subprocess.check_call(['gsutil', '-m' , 'cp', '-r',
                       os.path.join('gs://path/to/', vocab_file), '/tmp'])

with open(os.path.join('/tmp', vocab_file), 'wb') as f:
  cPickle.dump(self.words, f)

如果您有任何输出,您可以将它们写入本地磁盘和gsutil rsync它们。(但是,请注意正确处理重新启动,因为您可能会被放在另一台机器上)。

另一种解决方案是猴子补丁open(注意:未经测试):

import __builtin__

# NB: not all modes are compatible; should handle more carefully.
# Probably should be reported on
# https://github.com/tensorflow/tensorflow/issues/4357
def new_open(name, mode='r', buffering=-1):
  return file_io.FileIO(name, mode)

__builtin__.open = new_open

请确保在任何模块实际尝试从 GCS 读取之前执行此操作。

于 2016-11-03T08:42:52.003 回答
2

apache_beam具有gcsio模块,可用于返回标准 Python 文件对象以读取/写入 GCS 对象。您可以将此对象与任何适用于 Python 文件对象的方法一起使用。例如

def open_local_or_gcs(path, mode):
  """Opens the given path."""
  if path.startswith('gs://'):
    try:
      return gcsio.GcsIO().open(path, mode)
    except Exception as e:  # pylint: disable=broad-except
      # Currently we retry exactly once, to work around flaky gcs calls.
      logging.error('Retrying after exception reading gcs file: %s', e)
      time.sleep(10)
      return gcsio.GcsIO().open(path, mode)
  else:
    return open(path, mode)

 with open_local_or_gcs(vocab_file, 'wb') as f:
   cPickle.dump(self.words, f)
于 2016-11-03T14:23:42.503 回答