Есть ли способ сохранить и загрузить словарь модели Gensim Doc2Vec - PullRequest
0 голосов
/ 22 мая 2019

редактировать

Корпус поезда - это информационный фрейм Spark, который я построил перед этим шагом. Я загружаю его из формата паркета и создаю класс «Feed», который дает Gensim lib итератор в корпусе поезда:

class Feed():
    def __init__(self, train_data):
        self.train_data = train_data

    def __iter__(self):
        for row in self.train_data.rdd.toLocalIterator():
            yield \
                gensim.models.doc2vec.TaggedDocument(\
                words=[kw.lower() for kw in row["keywords"]] + list(row["tokens_filtered"]),\
                tags=[row["id"]])


sdf = spark.read.parquet(save_dirname)
train_corpus = Feed(sdf)

конец редактирования

Я хочу обучить модель Gensim Doc2Vec для ~ 9 миллионов новостных текстовых документов. Вот мое определение модели:

model = gensim.models.doc2vec.Doc2Vec(
        workers=8,
        vector_size=300,
        min_count=50,
        epochs=10)

Первый шаг - это получение словарного запаса:

model.build_vocab(train_corpus)

Это заканчивается через 90 минут. Вот информация о регистрации в конце этого процесса:

INFO:gensim.models.doc2vec:collected 4202859 word types and 8950263 unique tags from a corpus of 8950339 examples and 1565845381 words
INFO:gensim.models.word2vec:Loading a fresh vocabulary
INFO:gensim.models.word2vec:min_count=50 retains 325027 unique words (7% of original 4202859, drops 3877832)
INFO:gensim.models.word2vec:min_count=50 leaves 1546772183 word corpus (98% of original 1565845381, drops 19073198)
INFO:gensim.models.word2vec:deleting the raw counts dictionary of 4202859 items
INFO:gensim.models.word2vec:sample=0.001 downsamples 9 most-common words
INFO:gensim.models.word2vec:downsampling leaves estimated 1536820314 word corpus (99.4% of prior 1546772183)
INFO:gensim.models.base_any2vec:estimated required memory for 325027 words and 300 dimensions: 13472946500 bytes

Затем я тренирую модель с классом итераторов в корпусе поезда:

model.train(train_corpus, total_examples=nb_rows, epochs=model.epochs)

Последние журналы тренировок:

INFO:gensim.models.base_any2vec:EPOCH 1 - PROGRESS: at 99.99% examples, 201921 words/s, in_qsize 16, out_qsize 0
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 7 more threads
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 6 more threads
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 5 more threads
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 4 more threads

Но он никогда не заканчивает оставшиеся темы. Это не первый раз, когда я сталкиваюсь с этой проблемой, даже с гораздо меньшим корпусом поезда. Обычно я перезапускаю весь процесс (настройка словарного запаса и обучение модели), и он продолжается.

К настоящему времени, чтобы сэкономить время, я не хочу снова вычислять словарный запас, вставляя на место ранее рассчитанный успешно, и только пытаюсь снова обучить модель. Есть ли способ сохранить вокабальную часть только модели, а затем загрузить ее для обучения модели непосредственно в корпусе поезда?

1 Ответ

0 голосов
/ 23 мая 2019

Что касается причины зависания, похоже, что вы обычно делаете правильные вещи, но что-то может не получиться с вашим train_corpus, конструкцию которого вы не показали.

Дважды проверьте его реализацию и, возможно, отредактируйте свой вопрос, чтобы показать более подробную информацию о его типе / инициализации. Просмотрите журналы, чтобы увидеть, есть ли доказательства того, что какие-либо потоки попали в ошибки, которые оставили их в состоянии, когда они не отчитываются, как требуется.

Вы можете .save() различных частей модели Doc2Vec, таких как model.wv.save(wv_path) - но нет простого способа восстановить модель из этих частей. (Это возможно, но требует тщательного внимания к требуемому состоянию объекта при просмотре источника и подвержено ошибкам.)

Но, что более важно, вы можете .save() полную модель Doc2Vec в любое время - и это, вероятно, лучший подход для ваших нужд. То есть вы можете .save() это после build_vocab() или после звонка на .train() и т. Д.

Если на самом деле ваш текущий зависший находится в каком-то блокноте, где вы можете прервать зависшее действие и выполнить новый код в новой ячейке, вы, вероятно, можете просто сохранить модель оттуда, отладить train_corpus, а затем повторно загрузить & переобучаться - при условии, что размер корпуса / словарный запас соответствуют тому, что было изучено в build_vocab().

Однако , такой частично обученный .save(), в конце концов, будет зависеть от почти полного обучения, которое уже произошло. Таким образом, конечные результаты будут отражать не только ваши параметры конфигурации, но и кучу лишних специальных тренировок.

Если вы хотите «очистить» длительные эффекты этой частичной тренировки после перезагрузки сохраненной Doc2Vec модели, я считаю, что следующее должно сделать это:

model.trainables.reset_weights(model.hs, model.negative, model.wv, model.docvecs)
...