在Google Cloud Bucket中保存Keras ModelCheckpoints

Kev*_*zke 11 hdf5 h5py google-cloud-platform keras tensorflow

我正在使用带有TensorFlow后端的Keras在Google Cloud Machine Learning Engine上培训LSTM网络.在对gcloud和我的python脚本进行一些调整之后,我设法部署我的模型并执行成功的训练任务.

然后我尝试使用Keras modelCheckpoint回调使我的模型在每个纪元后保存检查点.使用Google Cloud运行本地培训工作可以完美地按预期运行.在每个纪元之后,权重将存储在指定的路径中.但是,当我尝试在Google云端机器学习引擎上在线运行相同的工作时weights.hdf5,不会将其写入我的Google Cloud Bucket.相反,我收到以下错误:

...
File "h5f.pyx", line 71, in h5py.h5f.open (h5py/h5f.c:1797)
IOError: Unable to open file (Unable to open file: name = 
'gs://.../weights.hdf5', errno = 2, error message = 'no such file or
directory', flags = 0, o_flags = 0)
Run Code Online (Sandbox Code Playgroud)

我调查了这个问题,事实证明,Bucket本身没有问题,因为Keras Tensorboard回调确实正常工作并将预期输出写入同一个存储桶.我还确保h5py通过在以下setup.py位置提供它来包含它:

??? setup.py
    ??? trainer
    ??? __init__.py
    ??? ...
Run Code Online (Sandbox Code Playgroud)

实际包含setup.py如下所示:

# setup.py
from setuptools import setup, find_packages

setup(name='kerasLSTM',
      version='0.1',
      packages=find_packages(),
      author='Kevin Katzke',
      install_requires=['keras','h5py','simplejson'],
      zip_safe=False)
Run Code Online (Sandbox Code Playgroud)

我想这个问题归结为这样一个事实:GCS不能用Pythons访问openI/O,因为它提供了一个自定义实现:

import tensorflow as tf
from tensorflow.python.lib.io import file_io

with file_io.FileIO("gs://...", 'r') as f:
    f.write("Hi!")
Run Code Online (Sandbox Code Playgroud)

在检查了Keras modelCheckpoint回调如何实现实际文件写入之后,结果是它正在使用h5py.File()进行I/O:

 with h5py.File(filepath, mode='w') as f:
    f.attrs['keras_version'] = str(keras_version).encode('utf8')
    f.attrs['backend'] = K.backend().encode('utf8')
    f.attrs['model_config'] = json.dumps({
        'class_name': model.__class__.__name__,
        'config': model.get_config()
 }, default=get_json_type).encode('utf8')
Run Code Online (Sandbox Code Playgroud)

而作为h5py package一个Python化的界面到HDF5 binary data formath5py.File()似乎调用底层HDF5Fortran语言编写的,据我可以告诉功能:,文档.

如何解决此问题并使modelCheckpoint回调写入我的GCS Bucket?有没有办法"猴子修补"以某种方式覆盖如何打开hdf5文件以使其使用GCS file_io.FileIO()

Yul*_*lia 13

我可能会有点迟到,但为了将来的访问者,我将描述如何调整以前在本地运行的代码从IO角度来看是GoogleML感知的整个过程.

  1. Python标准open(file_name, mode)不适用于bucket(gs://...../file_name).一个人需要from tensorflow.python.lib.io import file_io和所有呼叫变为open(file_name, mode)file_io.FileIO(file_name, mode=mode)(注意命名的mode参数).打开的手柄的界面是相同的.
  2. Keras和/或其他库大多在open(file_name, mode)内部使用标准.也就是说,trained_model.save(file_path)调用第三方库的方法无法将结果存储到存储桶中.在作业成功完成后检索模型的唯一方法是将其存储在本地,然后移动到存储桶.

下面的代码是非常低效的,因为它一次加载整个模型然后将其转储到存储桶,但它适用于相对较小的模型:

model.save(file_path)

with file_io.FileIO(file_path, mode='rb') as if:
    with file_io.FileIO(os.path.join(model_dir, file_path), mode='wb+') as of:
        of.write(if.read())
Run Code Online (Sandbox Code Playgroud)

对于读取和写入,必须将模式设置为二进制.

当文件相对较大时,以块的形式读取和写入以减少内存消耗是有意义的.

  1. 在运行实际任务之前,我建议运行一个简单地将文件保存到远程存储桶的存根.

暂时放入而不是真正train_model调用的实现应该:

if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    parser.add_argument(
        '--job-dir',
        help='GCS location with read/write access',
        required=True
    )

    args = parser.parse_args()
    arguments = args.__dict__
    job_dir = arguments.pop('job_dir')

    with file_io.FileIO(os.path.join(job_dir, "test.txt"), mode='wb+') as of:
        of.write("Test passed.")
Run Code Online (Sandbox Code Playgroud)

成功执行后,您应该会看到test.txt包含内容的文件"Test passed.".


Kev*_*zke 5

这个问题可以用下面的一段代码解决:

# Save Keras ModelCheckpoints locally
model.save('model.h5')

# Copy model.h5 over to Google Cloud Storage
with file_io.FileIO('model.h5', mode='r') as input_f:
    with file_io.FileIO('model.h5', mode='w+') as output_f:
        output_f.write(input_f.read())
        print("Saved model.h5 to GCS")
Run Code Online (Sandbox Code Playgroud)

model.h5 保存在本地文件系统中并复制到 GCS。正如Jochen指出的那样,目前没有简单的支持将 HDF5 模型检查点写入 GCS。有了这个 hack,就可以写入数据,直到提供更简单的解决方案。