2015-06-25 16 views
10

Ich versuche, ein Word2Vec-Modell mit einer Datei mit etwa 170K Zeilen, mit einem Satz pro Zeile zu trainieren.Word2vec Training mit Gensim beginnt nach 100K Sätze swapping

Ich denke, dass ich einen speziellen Anwendungsfall darstellen kann, weil die "Sätze" willkürliche Zeichenfolgen anstelle von Wörterbuchwörtern haben. Jeder Satz (Zeile) hat ungefähr 100 Wörter und jedes "Wort" hat ungefähr 20 Zeichen, mit Zeichen wie "/" und auch Zahlen.

Der Code Ausbildung ist sehr einfach:

# as shown in http://rare-technologies.com/word2vec-tutorial/ 
import gensim, logging, os 

logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO) 

class MySentences(object): 
    def __init__(self, dirname): 
     self.dirname = dirname 

    def __iter__(self): 
     for fname in os.listdir(self.dirname): 
      for line in open(os.path.join(self.dirname, fname)): 
       yield line.split() 

current_dir = os.path.dirname(os.path.realpath(__file__)) 

# each line represents a full chess match 
input_dir = current_dir+"/../fen_output" 
output_file = current_dir+"/../learned_vectors/output.model.bin" 

sentences = MySentences(input_dir) 

model = gensim.models.Word2Vec(sentences,workers=8) 

Das Ding ist, die Dinge funktionieren ganz schnell bis zu 100K Sätze (mein RAM steigen stetig), aber dann aus dem RAM ich laufen und ich kann mein PC sehen ist fing an zu tauschen, und das Training kam zum Stillstand. Ich habe nicht viel RAM zur Verfügung, nur etwa 4 GB und word2vec verbraucht alles, bevor Sie anfangen zu tauschen.

Ich glaube, ich habe OpenBLAS richtig numpy verbunden: das ist, was numpy.show_config() sagt mir:

blas_info: 
    libraries = ['blas'] 
    library_dirs = ['/usr/lib'] 
    language = f77 
lapack_info: 
    libraries = ['lapack'] 
    library_dirs = ['/usr/lib'] 
    language = f77 
atlas_threads_info: 
    NOT AVAILABLE 
blas_opt_info: 
    libraries = ['openblas'] 
    library_dirs = ['/usr/lib'] 
    language = f77 
openblas_info: 
    libraries = ['openblas'] 
    library_dirs = ['/usr/lib'] 
    language = f77 
lapack_opt_info: 
    libraries = ['lapack', 'blas'] 
    library_dirs = ['/usr/lib'] 
    language = f77 
    define_macros = [('NO_ATLAS_INFO', 1)] 
openblas_lapack_info: 
    NOT AVAILABLE 
lapack_mkl_info: 
    NOT AVAILABLE 
atlas_3_10_threads_info: 
    NOT AVAILABLE 
atlas_info: 
    NOT AVAILABLE 
atlas_3_10_info: 
    NOT AVAILABLE 
blas_mkl_info: 
    NOT AVAILABLE 
mkl_info: 
    NOT AVAILABLE 

Meine Frage ist: wird diese voraussichtlich auf einer Maschine, die eine Menge verfügbaren RAM nicht hat (wie meiner) und ich sollte mehr RAM bekommen oder das Modell in kleineren Stücken trainieren? oder sieht es so aus, als wäre mein Setup nicht richtig konfiguriert (oder mein Code ist ineffizient)?

Vielen Dank im Voraus.

Antwort

2

sieht es so aus, als wäre mein Setup nicht richtig konfiguriert (oder mein Code ist ineffizient)?

1) Im Allgemeinen würde ich Nein sagen. Da Sie jedoch nur wenig RAM haben, würde ich eine geringere Anzahl von Arbeitern verwenden. Es wird das Training verlangsamen, aber vielleicht können Sie den Wechsel auf diese Weise vermeiden.

2) Sie können Stemming oder besser versuchen: Lemmatisierung. Sie werden die Anzahl der Wörter reduzieren, da zum Beispiel Singular- und Pluralformen als das gleiche Wort gezählt werden.

3) Aber ich denke, 4 GB RAM sind wahrscheinlich Ihr Hauptproblem hier (abgesehen von Ihrem OS, Sie wahrscheinlich nur 1-2 GB, die tatsächlich von den Prozessen/Threads verwendet werden können.Ich würde wirklich darüber nachdenken, in mehr RAM zu investieren.Zum Beispiel können Sie heute gute 16 Gb RAM-Kits für < $ 100 erhalten, wenn Sie einige haben Geld in eine anständige RAM für gemeinsame ML/"Data Science" Aufgabe zu investieren, würde ich empfehlen> 64 GB

3

Als erstes Prinzip sollten Sie immer mehr RAM bekommen, wenn Ihr Budget und Maschine es verwalten können spart so viel Zeit & Problem

Zweitens ist es unklar, wenn Sie meinen, dass bei einem Datensatz mit mehr als 100K-Sätzen das Training nach den ersten 100K-Sätzen langsamer wird, oder wenn Sie meinen, dass die Verwendung eines Datensatzes mit mehr als 100K Sätzen die Verlangsamung verursacht. Ich vermute, es ist letzteres, weil ...

Die Word2Vec-Speicherauslastung ist eine Funktion der Wortschatzgröße (Token-Anzahl) - und nicht die Gesamtmenge der zum Trainieren verwendeten Daten. So können Sie eine größere min_count verwenden, um die verfolgte Anzahl von Wörtern zu verringern, um die RAM-Auslastung während des Trainings zu begrenzen.(Wörter, die nicht vom Modell erfasst werden, werden während des Trainings stillgelegt, als ob sie nicht da wären - und dies für seltene Worte tut nicht viel weh und hilft manchmal sogar, indem sie andere Wörter einander näher bringt.)

Schließlich möchten Sie vielleicht vermeiden, die Korpussätze im Konstruktor zur Verfügung zu stellen - die automatisch scannt und trainiert - und stattdessen die Schritte build_vocab() und train() selbst nach dem Modellaufbau aufrufen, um den Zustand/Größe des Modells zu untersuchen und Ihre Parameter anzupassen wie benötigt.

Insbesondere in den neuesten Versionen von GENSIM können Sie spalten auch die build_vocab(corpus) Schritt in drei Schritten scan_vocab(corpus), scale_vocab(...) und finalize_vocab().

Der scale_vocab(...) Schritt kann mit einem dry_run=True Parametern aufgerufen werden, die eine Vorschau, wie groß Ihre Wortschatz, unterabgetastet Korpus und erwartete Speichernutzung nach dem Versuch, unterschiedliche Werte der min_count und sample Parameter sein werden. Wenn Sie Werte finden, die überschaubar erscheinen, können Sie scale_vocab(...) mit diesen gewählten Parametern aufrufen und ohne dry_run diese auf Ihr Modell anwenden (und dann finalize_vocab(), um die großen Arrays zu initialisieren).