2015-06-25 17 views
10

Sto provando ad addestrare un modello word2vec usando un file con circa 170K linee, con una frase per riga.La formazione di Word2vec che utilizza gensim inizia lo scambio dopo 100.000 frasi

Penso che potrei rappresentare un caso di utilizzo speciale perché le "frasi" hanno stringhe arbitrarie piuttosto che parole di dizionario. Ogni frase (riga) ha circa 100 parole e ogni "parola" ha circa 20 caratteri, con caratteri come "/" e anche numeri.

Il codice di formazione è molto semplice:

# 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) 

Il fatto è che le cose funzionano molto velocemente fino a 100K frasi (la mia RAM costantemente andando verso l'alto), ma poi ho esaurito la memoria RAM e posso vedere il mio PC ha ha iniziato lo scambio e l'allenamento si è fermato. Non ho molta RAM disponibile, solo circa 4 GB e word2vec consumano tutto prima di iniziare a scambiare.

penso di avere OpenBLAS correttamente legati a NumPy: questo è ciò che numpy.show_config() mi dice:

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 

La mia domanda è: è questo previsto su una macchina che non ha avuto un sacco di RAM disponibile (come il mio) e dovrei ottenere più RAM o allenare il modello in pezzi più piccoli? o sembra che la mia configurazione non sia configurata correttamente (o che il mio codice sia inefficiente)?

Grazie in anticipo.

risposta

2

sembra che la mia configurazione non sia configurata correttamente (o il mio codice è inefficiente)?

1) In generale, direi di no. Tuttavia, dato che hai solo una piccola quantità di RAM, userei un numero inferiore di lavoratori. Rallenterà l'allenamento, ma forse puoi evitare lo scambio in questo modo.

2) Puoi provare ad arginare o meglio: lemmatizzazione. Riducete il numero di parole poiché, ad esempio, le forme singolari e plurali verranno contate come la stessa parola

3) Tuttavia, penso che 4 GB di RAM siano probabilmente il vostro problema principale qui (a parte il vostro sistema operativo, voi probabilmente hanno solo 1-2 GB che possono essere effettivamente utilizzati dai processi/thread. Vorrei davvero pensare di investire in più RAM.Ad esempio, al giorno d'oggi è possibile ottenere buoni kit da 16 GB di RAM per < $ 100, tuttavia, se si dispone di alcuni soldi per investire in una RAM decente per attività comuni di ML/"data science", raccomanderei> 64 GB

3

Come primo principio, si dovrebbe sempre ottenere più RAM, se il budget e la macchina possono gestirlo. risparmia così tanto tempo & trouble

In secondo luogo, non è chiaro se si intende che su un set di dati di più di 100K frasi, l'allenamento inizia a rallentare dopo che si incontrano le prime frasi da 100K o se si intende che l'utilizzo di un set di dati più grande di 100K frasi subisce il rallentamento. Sospetto che sia quest'ultimo, perché ...

L'utilizzo della memoria di Word2Vec è una funzione della dimensione del vocabolario (conteggio dei token) - e non della quantità totale di dati utilizzati per la formazione. Quindi potresti voler usare un più grande min_count, per snellire il numero di parole tracciato, per limitare l'utilizzo della RAM durante l'allenamento.(Le parole non tracciate dal modello verranno silenziosamente rilasciate durante l'allenamento, come se non fossero lì - e farlo per parole rare non fa molto male e talvolta aiuta anche, mettendo le parole più vicine l'una all'altra.)

Infine, si potrebbe desiderare di evitare di fornire le frasi corpus nel costruttore - che esegue automaticamente scansioni e treni - e invece chiamare esplicitamente i passi build_vocab() e train() dopo la costruzione del modello, per esaminare lo stato/le dimensioni del modello e regolare i parametri come necessario.

In particolare, nelle ultime versioni di gensim, si può anche dividere il build_vocab(corpus) passo in avanti in tre fasi scan_vocab(corpus), scale_vocab(...), e finalize_vocab().

Il scale_vocab(...) passo può essere chiamato con un parametro dry_run=True che prevede quanto è grande il tuo vocabolario, corpus subsampled, e si aspettava la memoria-utilizzo saranno dopo aver provato diversi valori dei parametri min_count e sample. Quando trovi valori apparentemente gestibili, puoi chiamare scale_vocab(...) con quei parametri scelti e senza dry_run, per applicarli al tuo modello (e quindi finalize_vocab() per inizializzare gli array di grandi dimensioni).

Problemi correlati