La parola2vec di Gensim ha una perdita di 0 dall'epoca 1?

Aug 21 2020

Sto usando il modulo Word2vec della libreria Gensim per addestrare un incorporamento di parole, il set di dati è composto da 400.000 frasi con 100.000 parole univoche (non è inglese)

Sto usando questo codice per monitorare e calcolare la perdita:

class MonitorCallback(CallbackAny2Vec):
    def __init__(self, test_words):
        self._test_words = test_words

    def on_epoch_end(self, model):
        print("Model loss:", model.get_latest_training_loss())  # print loss
        for word in self._test_words:  # show wv logic changes
            print(model.wv.most_similar(word))


monitor = MonitorCallback(["MyWord"])  # monitor with demo words

w2v_model = gensim.models.word2vec.Word2Vec(size=W2V_SIZE, window=W2V_WINDOW, min_count=W2V_MIN_COUNT  , callbacks=[monitor])

w2v_model.build_vocab(tokenized_corpus)

words = w2v_model.wv.vocab.keys()
vocab_size = len(words)
print("Vocab size", vocab_size)

print("[*] Training...")

# Train Word Embeddings
w2v_model.train(tokenized_corpus, total_examples=len(tokenized_corpus), epochs=W2V_EPOCH)

Il problema è che dall'epoca 1 la perdita è 0 e il vettore delle parole monitorate non cambia affatto!

[*] Training...
Model loss: 0.0
Model loss: 0.0
Model loss: 0.0
Model loss: 0.0

quindi qual è il problema qui? è normale? il corpus tokenizzato è un elenco di elenchi simili a tokenized_corpus[0] = [ "word1" , "word2" , ...]

Ho cercato su Google e sembra che alcune delle vecchie versioni di gensim abbiano avuto problemi con il calcolo della funzione di perdita, ma risalgono a quasi un anno fa e sembra che dovrebbe essere risolto in questo momento?

Ho provato anche il codice fornito nella risposta a questa domanda, ma la perdita è ancora 0:

La perdita non diminuisce durante l'allenamento (Word2Vec, Gensim)

EDIT1: dopo aver aggiunto compute_loss=True, la perdita si presenta, ma continua ad andare sempre più in alto, e le prime parole simili e la loro somiglianza non cambiano affatto:

Model loss: 2187903.5
Model loss: 3245492.0
Model loss: 4103624.5
Model loss: 4798541.0
Model loss: 5413940.0
Model loss: 5993822.5
Model loss: 6532631.0
Model loss: 7048384.5
Model loss: 7547147.0

Risposte

1 gojomo Aug 21 2020 at 00:16

Il problema principale con il tuo codice è che non hai utilizzato il Word2Vecparametro di inizializzazione necessario per attivare il monitoraggio delle perdite:compute_loss=True

(Vedi la sezione 'parametri' dihttps://radimrehurek.com/gensim/models/word2vec.html#gensim.models.word2vec.Word2Vec)

Anche con quella correzione, la segnalazione delle perdite è ancora piuttosto buggata (al momento della gensim-3.8.3stesura di questo articolo nell'agosto 2020):

  • non è il totale per epoca o la media per esempio, ci si potrebbe aspettare. (Quindi, se ne hai bisogno, come soluzione alternativa, il tuo callback dovrebbe ricordare l'ultimo valore e calcolare il delta, o reimpostare il contatore interno su 0.0, la fine di ogni epoca.)
  • perde decisamente precisione nelle corse di allenamento più grandi, diventando infine inutile. (Questo potrebbe non essere un problema per te.)
  • potrebbe perdere alcuni conteggi a causa della sovrascrittura del valore multithread. (Questo potrebbe non essere un problema pratico per te, a seconda del motivo per cui stai consultando il valore di perdita.)