Ошибка Pickle при сохранении модели doc2vec, AttributeError - PullRequest
0 голосов
/ 24 октября 2019

Мне не удалось использовать обратные вызовы для сохранения модели в соответствии с [официальными документами]: https://radimrehurek.com/gensim/models/callbacks.html

AttributeError: Невозможно выбрать локальный объект 'train_model..shf'

    from random import shuffle
    from gensim.models.callbacks import CallbackAny2Vec
    from gensim.test.utils import get_tmpfile

    class shf(CallbackAny2Vec):
        def __init__(self, x, path_prefix):
            self.epoch = 0
            self.x = x
            self.path_prefix = path_prefix
        def on_epoch_begin(self, model):
            shuffle(self.x)

        def on_epoch_end(self, model):
            print("epoch:%s"%self.epoch)
            if self.epoch % 10 == 0:
                output_path = get_tmpfile('{}_epoch{}.model'.format(self.path_prefix, self.epoch))
                model.save(output_path)
            self.epoch += 1
    model_dm = gensim.models.Doc2Vec(min_count=1, window=10, size=size, sample=1e-3, negative=5, workers=3)
    model_dm.build_vocab(x_train + x_test)

    fun = shf(x_train, "\models")
    model_dm.train(x_train, total_examples=model_dm.corpus_count, epochs=100, callbacks=[fun])

1 Ответ

0 голосов
/ 24 октября 2019

Вы должны включить дословно полный стек ошибок, который вы видите в своем вопросе, чтобы помочь ответчикам точно определить, какие шаги / строки кода вызывают ошибку.

Кроме того, сохранение моделей с обратными вызовами создает ряд проблем, особенно когда вы определили класс чисто локально (как в вашем классе shf), который может быть недоступен при повторной загрузке модели. ,Существует некоторое обсуждение проблемы и обходных путей в открытой gensim проблеме , и библиотека может по своему выбору отключить сохранение обратных вызовов в будущем (например, указывается только обратный вызов иэффект, на время одного звонка train()).

Между тем, эта ошибка, которую вы получаете, может быть чем-то новым в Python 3.x - проблема заключается в сохранении, а не в загрузке. И, если вы определили свой класс обратного вызова в другом модуле, который можно было импортировать по имени перед сохранением (чтобы он также мог быть импортирован по имени перед повторной загрузкой), это может решить вашу проблему.

Несколько других замечаний о вашей настройке:

  • Перестановки перед каждой тренировочной эпохой обычно перебивают с незначительной выгодой, особенно с большими наборами данных или большим количеством эпох. (Если в вашем исходном источнике данных есть примеры схожей категории или словаря, объединенные вместе, тогда может быть полезен только один начальный случайный случай.)

  • Если вы сделали build_vocab() с большим числомдокументов, отличных от вашего последующего звонка на train(), тогда model_dm.corpus_count не будет правильным номером total_examples. (Это общее кеширование из build_vocab(), а не количество примеров обучения.) В результате, управление скоростью обучения и зарегистрированные показатели прогресса будут немного отличаться. Кроме того, модель будет инициализирована, чтобы знать о словах, которые могут встречаться только в не обучающих документах. Части модели, связанные с такими словами, останутся необученными - потому что нет никаких примеров их использования, приведенных во время train() - что, вероятно, приведет к худшим результатам модели, чем просто полное их игнорирование.

  • Если вы звоните train() с epochs=100, вы также можете указать epochs=100 при создании модели, чтобы модель запомнила это значение как своеколичество циклов по умолчанию (например, при последующем вызове infer_vector()).

...