2016-11-03 11 views
8

Google은 최근 Clould ML, https://cloud.google.com/ml/을 발표했으며 매우 유용합니다. 그러나 한 가지 제한 사항은 Tensorflow 프로그램의 입/출력이 gs : //를 지원해야한다는 것입니다.클라우드 ML 용 Google 스토리지 (gs) 래퍼 파일 입/출력?

파일을 읽고 쓰는 데 모든 tensorflow APIS를 사용하는 경우이 API가 gs://을 지원하므로 파일을 읽거나 쓸 수는 있습니다.

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

이 코드에서 작동하지 않습니다 : 우리가 기본 파일을 사용하는 경우가 예를 들어 gs://

을 이해하지 않기 때문에

그러나, IO API는 같은 open, 그것은 작동하지 않습니다 Google Cloud ML.

그러나 모든 원시 파일 IO API를 tensorflow API 또는 Google Storage Python API로 수정하는 것은 정말 지루합니다. 이 작업을 수행하는 간단한 방법이 있습니까? Google 스토리지 시스템을 지원하는 모든 래퍼, 기본 파일 IO 위에 gs://?

Pickled scipy sparse matrix as input data?에서 제안한대로 아마도 file_io.read_file_to_string('gs://...')을 사용할 수 있지만 여전히 중요한 코드 수정이 필요합니다.

답변

4

한 가지 해결책은 프로그램 시작시 모든 데이터를 로컬 디스크에 복사하는 것입니다. 당신이 어떤 출력이있는 경우

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 그들에게 쓸 수 있습니다 : 당신은 같은 파이썬 실행됩니다 스크립트, 뭔가 내부는 gsutil 사용하는 것을 할 수 있습니다. (그러나 다른 컴퓨터에있을 수 있기 때문에 다시 시작을 올바르게 처리해야합니다.)

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에서 읽기를 시도하기 전에 그렇게해야합니다 :

다른 솔루션은 원숭이 패치 open (: 안된 주)입니다.

1

apache_beam에는 표준 Python 파일 객체를 반환하여 GCS 객체를 읽고 쓸 수있는 모듈이 있습니다. 이 객체는 Python 파일 객체와 함께 작동하는 모든 메서드에서 사용할 수 있습니다.

from tensorflow.python.lib.io import file_io 

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

을 또는 당신은 피클이 같이에서 파일을 읽을 수 있습니다 : 예를

를 들어
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) 
+0

감사합니다! 이것은 아주 좋아 보인다. 나는 Tensorflow file_io가 해결책 일 수도 있다고 생각한다. 'file_io.FileIO (file_path, mode = "w")를 f'로 사용합니다. 그것도 괜찮다고 생각하니? 나는 아직 완전히 테스트하지 않았다. –

+2

나는 당신의 질문을 모든 open() 함수 호출을 특별한 함수로 대체하지 않아도되도록하고 싶다고 해석했다. 그렇지 않은 경우 즉, open()에 대한 호출을 대체하려는 경우 gcsio.open_local_or_gcs 및 file_io.FileIO는 매우 비슷합니다. 사용자가 가져 오는 종속성에 영향을줍니다. file_io는 이미 TF의 일부입니다. 그러나 FileIO는 비표준 모드를 ​​사용하기 때문에 결정에 영향을 미칠 수 있습니다. – rhaertel80

3

은 이런 식으로 작업을 수행

file_stream = file_io.FileIO(train_file, mode='r') 
x_train, y_train, x_test, y_test = pickle.load(file_stream)