Как получить детерминированные результаты поездов в Doc2Vec?

Я использую Doc2Vec для анализа некоторого абзаца и хочу получить детерминированное векторное представление данных поезда. Судя по официальной документации, мне кажется, что мне нужно установить параметры "seed" и «worker», а также переменную среды PYTHONHASHSEED в Python 3. Поэтому я написал сценарий следующим образом.

import os
from gensim.models.doc2vec import TaggedDocument
from gensim.models import Doc2Vec


def main():
    # Check whether the environment variable has been set successfully
    print(os.environ.get('PYTHONHASHSEED'))

    docs = [TaggedDocument(['Apple', 'round', 'apple', 'red', 'Apple', 'juicy', 'apple', 'sweet'], ['A']),
            TaggedDocument(['I', 'have', 'a', 'little', 'frog', 'His', 'name', 'is', 'Tiny', 'Tim'], ['B']),
            TaggedDocument(['On', 'top', 'of', 'spaghetti', 'all', 'covered', 'with', 'cheese'], ['C'])]

    # Loop 3 times to check whether consistent results are produced within each run
    for i in range(3):
        model = Doc2Vec(min_count=1, seed=12345, workers=1)
        model.build_vocab(docs)
        model.train(docs, total_examples=model.corpus_count, epochs=model.epochs)
        print(model.docvecs['B'])


if __name__ == '__main__':
    os.environ['PYTHONHASHSEED'] = '12345'
    main()

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

Я использую Python 3.6.5.


person jiao    schedule 12.06.2019    source источник


Ответы (2)


Я считаю, что устанавливать PYTHONHASHSEED внутри вашего кода слишком поздно: его нужно установить в среде ОС, прежде чем интерпретатор Python вообще запустится. Когда Python запускается, он проверяет это, чтобы решить, будут ли все словари во время этого выполнения использовать указанное начальное число рандомизации. (Это не проверяется позже, при каждом последующем создании словаря.)

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

В Q11 и Q12 FAQ по проекту gensim есть немного больше обсуждения этих проблем:

https://github.com/RaRe-Technologies/gensim/wiki/recipes-&-faq#q11-ive-trained-my-word2vecdoc2vecetc-model-repeatedly-using-the-exact-same-text-corpus-but-the-vector-are-different-each-time-is-there-a-bug-or-have-i-made-a-error-2vec-training-non-terminism

person gojomo    schedule 12.06.2019
comment
Привет, я был бы рад, если бы я мог задать другой связанный с этим вопрос (пожалуйста, дайте мне знать, если я должен создать новый пост). Как и то, что вы сказали, разница в результатах тренировки может быть довольно небольшой от прогона к запуску. Однако, скажем, если я использовал документ D для обучения и получил его векторное представление D_v из model.docvecs; D_v2 = model.infer_vector(D) сильно отличается от D_v. Я думал, что D_v и D_v2 должны быть похожи. Я неправильно понимаю или что-то упустил? - person jiao; 22.07.2019
comment
Да, они должны быть очень похожими - в частности, если вы запрашиваете обученные векторы из модели через model.most_similar(positive=[D_v2,]), tag для того же текста в обучении должен быть лучшим результатом (или в нескольких лучших). Если это не, возможно, во время обучения или вывода могут возникнуть другие проблемы. Включите ведение журнала на уровне INFO для обучения и просмотрите журналы, чтобы убедиться, что обрабатывается ожидаемое количество текстов, тегов документов, слов и т. Д. Убедитесь, что вы используете недавний gensim со всеми недавними исправлениями вывода. Убедитесь, что вы передаете список токенов для вывода, и подумайте о повышении epochs. - person gojomo; 22.07.2019
comment
Тег для того же текста не появился, но после обновления gensim до более новой версии проблема, похоже, решена. Моя предыдущая версия gensim была 3.4.0 (которая кажется последней версией, доступной на conda), и я переустановил 3.7.1 с помощью pip (более поздняя версия выдает предупреждение о том, что расширение C не загружено в среде Anaconda). Большое спасибо за подробное объяснение! - person jiao; 23.07.2019

Я думаю, вам следует использовать следующий код, чтобы исправить PYTHONHASHSEED

import os
import sys
hashseed = os.getenv('PYTHONHASHSEED')
if not hashseed:
    os.environ['PYTHONHASHSEED'] = '0'
    os.execv(sys.executable, [sys.executable] + sys.argv)
person Violet R. Allison    schedule 24.06.2021