2016-11-03 4 views
8

Google hat vor kurzem die Clould ML, https://cloud.google.com/ml/ angekündigt und es ist sehr nützlich. Eine Einschränkung ist jedoch, dass die Eingabe/Ausgabe eines Tensorflow-Programms gs: // unterstützen sollte.Google Storage (gs) Wrapper-Datei für Cloud ML ein/aus?

Wenn wir alle Tensorflow APIS zum Lesen/Schreiben von Dateien verwenden, sollte es in Ordnung sein, da diese APIs gs:// unterstützen.

Wenn wir jedoch native Datei verwenden IO APIs wie open, funktioniert es nicht, weil sie gs://

Zum Beispiel nicht verstehen:

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

Dieser Code wird nicht funktionieren in Google Cloud ML.

Das Ändern aller nativen Datei-IO-APIs in Tensorflow-APIs oder Google Storage Python-APIs ist jedoch sehr mühsam. Gibt es einen einfachen Weg, dies zu tun? Alle Wrapper zur Unterstützung von Google Storage Systems, gs:// auf der nativen Datei IO?

Wie hier vorgeschlagen Pickled scipy sparse matrix as input data?, vielleicht können wir file_io.read_file_to_string('gs://...') verwenden, aber immer noch dies erfordert signifikante Code-Änderung.

Antwort

4

Eine Lösung besteht darin, beim Start des Programms alle Daten auf die lokale Festplatte zu kopieren. Sie können tun, dass innerhalb des Python-Skript mit gsutil, die ausgeführt wird, so etwas wie:

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) 

Und wenn Sie irgendwelche Ausgaben haben, können Sie sie auf der lokalen Festplatte schreiben können und gsutil rsync sie. (Achten Sie jedoch darauf, Neustarts korrekt zu handhaben, da Sie möglicherweise auf eine andere Maschine gestellt werden).

Die andere Lösung ist, Affe Patch open (Anmerkung: nicht getestet):

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 

Nur sicher sein, das zu tun, bevor ein Modul versucht tatsächlich von GCS zu lesen.

1

apache_beam enthält das Modul gcsio, mit dem ein Python-Standarddateiobjekt zum Lesen/Schreiben von GCS-Objekten zurückgegeben werden kann. Sie können dieses Objekt mit jeder Methode verwenden, die mit Python-Dateiobjekten arbeitet. Zum Beispiel

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

Dank! Das sieht sehr gut aus. Ich denke, Tensorflow file_io könnte auch eine Lösung sein. 'mit file_io.FileIO (Dateipfad, mode =" w ") als f'. Denkst du, dass es auch OK ist? Ich habe es noch nicht vollständig getestet. –

+2

Ich interpretierte Ihre Frage so, als wolle ich vermeiden, alle offenen() Funktionsaufrufe durch spezielle Funktionen ersetzen zu müssen. Wenn das nicht der Fall ist, d. H. Sie sind bereit, Aufrufe von open() zu ersetzen, dann sind gcsio.open_local_or_gcs und file_io.FileIO ziemlich ähnlich, beeinflusst nur, welche Abhängigkeiten Sie mitbringen - file_io ist bereits Teil von TF. Aber FileIO verwendet einige Nicht-Standard-Modi, so dass dies auch Ihre Entscheidung beeinflussen kann. – rhaertel80

3

es wie folgt tun:

from tensorflow.python.lib.io import file_io 

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

Oder Sie können Gurken wie diese Datei in gelesen:

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