Word2vec Gensim имеет потерю 0 из эпохи 1?

Aug 21 2020

Я использую модуль Word2vec библиотеки Gensim для обучения встраиванию слов, набор данных составляет 400 тыс. Предложений с 100 тыс. Уникальных слов (это не английский)

Я использую этот код для отслеживания и расчета потерь:

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)

Проблема в том, что с эпохи 1 потеря равна 0, а вектор отслеживаемых слов вообще не меняется!

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

так в чем тут проблема? это нормально? токенизированный корпус - это список списков, которые похожи на tokenized_corpus [0] = ["word1", "word2", ...]

Я погуглил, и похоже, что у некоторых старых версий gensim были проблемы с вычислением функции потерь, но они созданы почти год назад, и кажется, что это нужно исправить прямо сейчас?

Я тоже попробовал код, приведенный в ответе на этот вопрос, но все равно потеря 0:

Потери при обучении не уменьшаются (Word2Vec, Gensim)

РЕДАКТИРОВАТЬ1: после добавления compute_loss = True убыток проявляется, но он продолжает расти все выше и выше, а верхние похожие слова и их сходство вообще не меняются:

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

Ответы

1 gojomo Aug 21 2020 at 00:16

Основная проблема вашего кода заключается в том, что вы не использовали Word2Vecпараметр инициализации, необходимый для включения отслеживания потерь:compute_loss=True

(См. Раздел «Параметры» в https://radimrehurek.com/gensim/models/word2vec.html#gensim.models.word2vec.Word2Vec )

Даже с этим исправлением отчет о потерях все еще содержит ошибки (на момент gensim-3.8.3написания этой статьи в августе 2020 года):

  • это не общее за эпоху или среднее значение для каждого примера, как можно было бы ожидать. (Так что, если вам это нужно, в качестве обходного пути ваш обратный вызов должен запоминать последнее значение и вычислять дельту или сбрасывать внутренний счетчик на 0.0конец каждой эпохи.)
  • он определенно теряет точность при больших тренировках и в конечном итоге становится бесполезным. (Возможно, для вас это не проблема.)
  • он может потерять некоторые результаты из-за многопоточной перезаписи значений. (Возможно, это не практическая проблема для вас, в зависимости от того, почему вы консультируетесь со стоимостью убытка.)