Słowo2vec Gensima ma stratę 0 z epoki 1?

Aug 21 2020

Używam modułu Word2vec biblioteki Gensim do szkolenia osadzania słów, zbiór danych to 400 tys. Zdań z 100 tys. Unikalnych słów (nie jest to język angielski)

Używam tego kodu do monitorowania i obliczania strat:

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)

Problem polega na tym, że od epoki 1 strata wynosi 0, a wektor monitorowanych słów w ogóle się nie zmienia!

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

więc na czym polega problem? czy to normalne? tokenizowany korpus to lista list, które są podobne do tokenized_corpus [0] = ["słowo1", "słowo2", ...]

Wyszukałem w Google i wygląda na to, że niektóre ze starych wersji gensima miały problem z obliczeniem funkcji strat, ale są one sprzed prawie roku i wygląda na to, że powinno to zostać naprawione teraz?

Wypróbowałem również kod podany w odpowiedzi na to pytanie, ale nadal strata wynosi 0:

Strata nie zmniejsza się podczas treningu (Word2Vec, Gensim)

EDIT1: po dodaniu compute_loss = True, pojawia się strata, ale rośnie i rośnie, a górne podobne słowa i ich podobieństwo w ogóle się nie zmieniają:

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

Odpowiedzi

1 gojomo Aug 21 2020 at 00:16

Główny problem z Twoim kodem polega na tym, że nie użyłeś Word2Vecparametru inicjalizacji niezbędnego do włączenia śledzenia strat:compute_loss=True

(Zobacz sekcję `` parametry '' w https://radimrehurek.com/gensim/models/word2vec.html#gensim.models.word2vec.Word2Vec )

Nawet z tą poprawką raportowanie strat jest nadal dość błędne (od gensim-3.8.3& tego pisania w sierpniu 2020 r.):

  • nie jest to suma na epokę ani średnia na przykład, jak można by się spodziewać. (Jeśli więc tego potrzebujesz, jako obejście, wywołanie zwrotne powinno zapamiętać ostatnią wartość i obliczyć deltę lub zresetować wewnętrzny licznik do 0.0końca każdej epoki).
  • zdecydowanie traci precyzję przy większych biegach treningowych, w końcu staje się bezużyteczny. (To może nie być dla Ciebie problemem).
  • może stracić niektóre zestawienia z powodu wielowątkowego nadpisywania wartości. (Może to nie być dla Ciebie praktycznym problemem, w zależności od tego, dlaczego konsultujesz wartość straty).