¿Word2vec de Gensim tiene una pérdida de 0 desde la época 1?

Aug 21 2020

Estoy usando el módulo Word2vec de la biblioteca Gensim para entrenar una incrustación de palabras, el conjunto de datos es de 400k oraciones con 100k palabras únicas (no es inglés)

Estoy usando este código para monitorear y calcular la pérdida:

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)

¡El problema es que a partir de la época 1, la pérdida es 0 y el vector de las palabras monitoreadas no cambia en absoluto!

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

¿Entonces, cuál es el problema aquí? ¿esto es normal? el corpus tokenizado es una lista de listas que son algo así como tokenized_corpus[0] = [ "palabra1", "palabra2", ...]

Busqué en Google y parece que algunas de las versiones anteriores de gensim tenían problemas con el cálculo de la función de pérdida, pero son de hace casi un año y parece que deberían arreglarse ahora.

También probé el código provisto en la respuesta de esta pregunta, pero aún así la pérdida es 0:

La pérdida no disminuye durante el entrenamiento (Word2Vec, Gensim)

EDIT1: después de agregar compute_loss=True, la pérdida aparece, pero sigue subiendo más y más, y las principales palabras similares y su similitud no cambian en absoluto:

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

Respuestas

1 gojomo Aug 21 2020 at 00:16

El principal problema con su código es que no ha utilizado el Word2Vecparámetro de inicialización necesario para activar el seguimiento de pérdidas:compute_loss=True

(Consulte la sección 'parámetros' dehttps://radimrehurek.com/gensim/models/word2vec.html#gensim.models.word2vec.Word2Vec)

Incluso con esa solución, el informe de pérdidas sigue siendo bastante defectuoso (a partir de gensim-3.8.3este escrito en agosto de 2020):

  • no es el total por época, o el promedio por ejemplo, como cabría esperar. (Entonces, si necesita eso, como solución alternativa, su devolución de llamada debe recordar el último valor y calcular el delta, o restablecer el contador interno al 0.0final de cada época).
  • definitivamente pierde precisión en carreras de entrenamiento más grandes, y finalmente se vuelve inútil. (Es posible que esto no sea un problema para usted).
  • podría perder algunas cuentas debido a la sobrescritura de valores de subprocesos múltiples. (Es posible que esto no sea un problema práctico para usted, dependiendo de por qué está consultando el valor de la pérdida).