Gensim의 word2vec은 epoch 1에서 0의 손실이 있습니까?

Aug 21 2020

Gensim 라이브러리의 Word2vec 모듈을 사용하여 단어 임베딩을 훈련하고 있으며 데이터 세트는 10 만 개의 고유 한 단어가 포함 된 400k 문장입니다 (영어가 아님)

이 코드를 사용하여 손실을 모니터링하고 계산합니다.

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의 이전 버전 중 일부가 손실 함수를 계산하는 데 문제가있는 것처럼 보였지만 거의 1 년 전의 것이며 지금 바로 수정해야 할 것 같습니까?

이 질문의 답변에 제공된 코드도 시도했지만 여전히 손실은 0입니다.

훈련 중에 손실이 감소하지 않습니다 (Word2Vec, Gensim).

EDIT1 : 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.32020 년 8 월 현재).

  • 예상 할 수있는 에포크 당 총계 또는 예제 당 평균이 아닙니다. (따라서 해결 방법으로 콜백이 마지막 값을 기억하고 델타를 계산하거나 내부 카운터를 0.0각 세대의 끝으로 재설정해야합니다 .)
  • 더 큰 훈련 실행에서는 확실히 정밀도가 떨어지고 결국 쓸모 없게됩니다. (이것은 문제가되지 않을 수 있습니다.)
  • 다중 스레드 값 덮어 쓰기로 인해 일부 집계가 손실 될 수 있습니다. (손실 가치를 문의하는 이유에 따라 실제 문제가 아닐 수 있습니다.)