Word2vec Gensim имеет потерю 0 из эпохи 1?
Я использую модуль 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
Ответы
Основная проблема вашего кода заключается в том, что вы не использовали Word2Vec
параметр инициализации, необходимый для включения отслеживания потерь:compute_loss=True
(См. Раздел «Параметры» в https://radimrehurek.com/gensim/models/word2vec.html#gensim.models.word2vec.Word2Vec )
Даже с этим исправлением отчет о потерях все еще содержит ошибки (на момент gensim-3.8.3
написания этой статьи в августе 2020 года):
- это не общее за эпоху или среднее значение для каждого примера, как можно было бы ожидать. (Так что, если вам это нужно, в качестве обходного пути ваш обратный вызов должен запоминать последнее значение и вычислять дельту или сбрасывать внутренний счетчик на
0.0
конец каждой эпохи.) - он определенно теряет точность при больших тренировках и в конечном итоге становится бесполезным. (Возможно, для вас это не проблема.)
- он может потерять некоторые результаты из-за многопоточной перезаписи значений. (Возможно, это не практическая проблема для вас, в зависимости от того, почему вы консультируетесь со стоимостью убытка.)