Gensim Doc2Vec - Почему infer_vector () использует альфа? - PullRequest
0 голосов
/ 07 мая 2018

Я пытаюсь сопоставить предложения с вектором, чтобы сделать предложения сопоставимыми друг с другом.Чтобы протестировать модель Doc2Vec от gensim, я скачал набор данных группы новостей sklearn и обучил его модели.

Чтобы сравнить два предложения, я использую model.infer_vector (), и мне интересно, почему два вызова, использующие одно и то же предложение, дают мне разные векторы:

model = Doc2Vec(vector_size=100, window=8, min_count=5, workers=6)
model.build_vocab(documents)

epochs=10
for epoch in range(epochs):
    print("Training epoch %d" % (epoch+1))
    model.train(documents,  total_examples=len(documents), epochs=epochs)

    v1 = model.infer_vector("I feel good")
    v2 = model.infer_vector("I feel good")
    print(np.linalg.norm(v1-v2)) 

Вывод:

Тренировочная эпоха 1

0.41606528

Тренировочная эпоха 2

0.43440753

Тренировочная эпоха 3

0.3203116

Тренировочная эпоха 4

0,3039317

Тренировочная эпоха 5

0.68224543

Тренировочная эпоха 6

0.5862567

Тренировочная эпоха 7

0,5424634

Тренировочная эпоха 8

0.7618142

Тренировочная эпоха 9

0.8170159

Эпоха обучения 10

0.6028216

Если я установлю alpha и min_alpha = 0, я получу согласованные векторы для «я чувствую себя хорошо» и «я чувствую себя хорошо», но модель дает мнеодин и тот же вектор в каждой эпохе, поэтому он, кажется, ничего не изучает:

Тренировочная эпоха 1

0,043668125

ПоездЭпоха 2

0,043668125

Эпоха обучения 3

0,043668125

Эпоха обучения 4

0,043668125

Эпоха обучения5

0,043668125

тренировочная эпоха 6

0,043668125

тренировочная эпоха 7

0,043668125

тренировочная эпоха 8

0,043668125

Учебная эпоха 9

0,043668125

Учебная эпоха 10

0,043668125

Итак, мои вопросыявляются:

  1. Почему у меня даже есть возможность указать скорость обучения для вывода?Я ожидаю, что модель изменяется только во время обучения, а не во время вывода.

  2. Если я задаю альфа = 0 для вывода, почему расстояние между этими двумя векторами не меняется в разные эпохи??

1 Ответ

0 голосов
/ 07 мая 2018

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

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

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

Помимо этого, в вашем коде есть ряд проблем, которые могут помешать желаемым результатам:

  • Вызывая train() epochs раз в цикле, а затем предоставляя значение больше 1 для epochs, вы фактически выполняете epochs * epochs всего тренировочных проходов

  • далее, оставляя неуказанными alpha и min_alpha, каждый вызов train() будет понижать эффективную альфу с ее высокого значения до его низкого значения при каждом вызове - шаблон пилообразной передачи, который не подходит для этот вид стохастической оптимизации градиентного спуска. (В ваших журналах должно быть предупреждение об этой ошибке.)

Редко нужно звонить train() несколько раз в цикле. Просто назовите его один раз, с правильным значением epochs, и он сделает правильную вещь: столько проходов с плавно затухающей скоростью обучения alpha.

Отдельно при звонке infer_vector():

  • для него требуется список токенов, как и свойство words обучающих примеров, которые были элементами в documents - , а не в строке. (Предоставляя строку, она выглядит как список символов, поэтому она будет выводить вектор документа для документа ['I', ' ', 'f', 'e', 'e', 'l', ' ', 'g', 'o', 'o', 'd'] , а не ['I', 'feel', 'good'].)

  • эти токены должны быть предварительно обработаны так же, как и учебные документы - например, если они там были в нижнем регистре, они должны быть в нижнем регистре до перехода к infer_vector()

  • аргумент по умолчанию passes=5 очень мал, особенно для коротких текстов - многие сообщают о лучших результатах со значением в десятках или сотнях

  • аргумент по умолчанию alpha=0.1 несколько больше по сравнению с обучением по умолчанию 0.025; использование значения тренировки (особенно с большим количеством passes) часто дает лучшие результаты

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

Однако, если модель была достаточно обучена, и вывод был скорректирован, как указано выше, для лучших результатов, векторы для одного и того же текста должны быть очень, очень близки. А поскольку это рандомизированный алгоритм с некоторым внутренним «джиттером» между прогонами, лучше сделать ваши последующие оценки и использовать толерантность к таким небольшим отклонениям. (И если вместо этого вы видите большие отклонения, исправьте другие проблемы с моделью / выводом, обычно с помощью дополнительных данных или других настроек параметров.)

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

...