Вопрос или проблема
Я пытаюсь обучить модель spaCy с целью вычисления семантического сходства, но не получаю результатов, которых ожидал.
Я создал два текстовых файла, которые содержат множество предложений с новым термином “PROJ123456”. Например, “PROJ123456 в курсе дел.”
Я добавил каждый файл в DocBin
и сохранил их на диск как train.spacy и dev.spacy.
Затем я запускаю:
python -m spacy train config.cfg --output ./output --paths.train ./train.spacy --paths.dev ./dev.spacy
Файл config.cfg содержит:
[paths]
train = null
dev = null
vectors = null
init_tok2vec = null
[system]
gpu_allocator = null
seed = 0
[nlp]
lang = "en"
pipeline = ["tok2vec","parser"]
batch_size = 1000
disabled = []
before_creation = null
after_creation = null
after_pipeline_creation = null
tokenizer = {"@tokenizers":"spacy.Tokenizer.v1"}
[components]
[components.parser]
factory = "parser"
learn_tokens = false
min_action_freq = 30
moves = null
scorer = {"@scorers":"spacy.parser_scorer.v1"}
update_with_oracle_cut_size = 100
[components.parser.model]
@architectures = "spacy.TransitionBasedParser.v2"
state_type = "parser"
extra_state_tokens = false
hidden_width = 128
maxout_pieces = 3
use_upper = true
nO = null
[components.parser.model.tok2vec]
@architectures = "spacy.Tok2VecListener.v1"
width = ${components.tok2vec.model.encode.width}
upstream = "*"
[components.tok2vec]
factory = "tok2vec"
[components.tok2vec.model]
@architectures = "spacy.Tok2Vec.v2"
[components.tok2vec.model.embed]
@architectures = "spacy.MultiHashEmbed.v2"
width = ${components.tok2vec.model.encode.width}
attrs = ["ORTH","SHAPE"]
rows = [5000,2500]
include_static_vectors = true
[components.tok2vec.model.encode]
@architectures = "spacy.MaxoutWindowEncoder.v2"
width = 256
depth = 8
window_size = 1
maxout_pieces = 3
[corpora]
[corpora.dev]
@readers = "spacy.Corpus.v1"
path = ${paths.dev}
max_length = 0
gold_preproc = false
limit = 0
augmenter = null
[corpora.train]
@readers = "spacy.Corpus.v1"
path = ${paths.train}
max_length = 0
gold_preproc = false
limit = 0
augmenter = null
[training]
dev_corpus = "corpora.dev"
train_corpus = "corpora.train"
seed = ${system.seed}
gpu_allocator = ${system.gpu_allocator}
dropout = 0.1
accumulate_gradient = 1
patience = 1600
max_epochs = 0
max_steps = 20000
eval_frequency = 200
frozen_components = []
annotating_components = []
before_to_disk = null
[training.batcher]
@batchers = "spacy.batch_by_words.v1"
discard_oversize = false
tolerance = 0.2
get_length = null
[training.batcher.size]
@schedules = "compounding.v1"
start = 100
stop = 1000
compound = 1.001
t = 0.0
[training.logger]
@loggers = "spacy.ConsoleLogger.v1"
progress_bar = false
[training.optimizer]
@optimizers = "Adam.v1"
beta1 = 0.9
beta2 = 0.999
L2_is_weight_decay = true
L2 = 0.01
grad_clip = 1.0
use_averages = false
eps = 0.00000001
learn_rate = 0.001
[training.score_weights]
dep_uas = 0.5
dep_las = 0.5
dep_las_per_type = null
sents_p = null
sents_r = null
sents_f = 0.0
[pretraining]
[initialize]
vectors = "en_core_web_lg"
init_tok2vec = ${paths.init_tok2vec}
vocab_data = null
lookups = null
before_init = null
after_init = null
[initialize.components]
[initialize.tokenizer]
Я получаю новую модель в output/model-last
.
Затем я запускаю следующий файл:
import spacy
nlp = spacy.load("./output/model-last")
print(nlp('PROJ123456').vector)
Я ожидаю увидеть вектор с ненулевыми значениями, но вместо этого я вижу вектор из 300 нулевых значений. Я принимаю это как знак того, что “PROJ123456” не было добавлено в словарь. Но я не понимаю, почему.
После векторизации вашего пользовательского текста, вам нужно сделать одно из двух в spaCy:
- загрузить эти бинарные векторы в nlp.vocab с помощью чего-то вроде nlp.vocab.load_rep_vectors .
- Или просто заменить файл vec.bin в “data/vocab/vec.bin”.
Подробная информация здесь: https://stackoverflow.com/questions/43524301/update-spacy-vocabulary .
Если у вас есть векторы слов, свойство .vectors
использует их для вычисления значений. Обучение модели не изменяет векторы слов. Похоже, вы просто повторно используете векторы слов из большой английской модели, которая не будет содержать ваш специальный термин, поэтому решение заключается в том, чтобы вам обучить свои собственные векторы слов и добавить их в модель.
Ответ или решение
Обучение модели spaCy для семантического сходства
Обучение модели для вычисления семантического сходства в библиотеке spaCy может показаться достаточно сложной задачей, особенно если результаты не оправдывают ожидания. В данной статье мы подробно рассмотрим, как правильно обучить модель для работы с собственными терминами и почему вы получаете вектор из 300 нулевых значений.
1. Загрузка необходимых данных
Вы упомянули, что создали два текстовых файла с предложениями, содержащими новый термин "PROJ123456". Эти файлы были использованы для создания объекта DocBin
, который затем был сохранён на диске в форматах train.spacy
и dev.spacy
. Это верный шаг — коллекция данных необходима для обучения модели, однако необходимо убедиться, что в обучающей выборке достаточно предложений для системы, чтобы она могла усвоить новый термин.
2. Конфигурация файла config.cfg
Ваша конфигурация в config.cfg
, по-видимому, не совсем подходит для достижения поставленной вами цели. Рассмотрим несколько ключевых аспектов:
-
Отсутствие векторов: Вы являетесь важным элементом модели, отвечающим за семантическое представление слов. Ваша модель не будет учитывать "PROJ123456", если его нет в словаре векторов. В разделе
[initialize]
вы написали, чтоvectors
равен "en_core_web_lg". Это предобученные векторы языка, которые не содержат вашего нового термина. -
Создание собственных векторов: Для правильного обучения попробуйте использовать метод обучения собственных векторов на основе ваших текстов. Это можно сделать с помощью системы представления векторов (например, с использованием библиотеки
gensim
) перед обучением spaCy. Вы можете создать векторы для ваших слов и затем загрузить их в словарь spaCy.
3. Обучение модели
После того как вы настройте ваши данные и конфигурацию, вы должны перезапустить команду для обучения:
python -m spacy train config.cfg --output ./output --paths.train ./train.spacy --paths.dev ./dev.spacy
Убедитесь, что в процессе обучения у вас есть достаточное количество примеров для каждого термина, если вы хотите, чтобы ваша модель могла корректно их интерпретировать.
4. Загружайте векторы
Как было упомянуто в ваших источниках, после обучения вашей модели вам необходимо убедиться, что векторы загружены в nlp.vocab
. Выполните одну из следующих задач:
-
Загрузите бинарные векторы в
nlp.vocab
с помощью команды:nlp.vocab.load_rep_vectors("path_to_your_vector_file.bin")
-
Или замените файл
vec.bin
в папке "data/vocab/vec.bin" на свой.
Это справит ситуацию с тем, что ваш термин "PROJ123456" не будет представлен как вектор.
5. Проверка модели
После обучения и загрузки векторов, попробуйте снова проверить векторы вашего термина:
import spacy
nlp = spacy.load("./output/model-last")
print(nlp('PROJ123456').vector)
Заключение
Обучение модели spaCy для вычисления семантического сходства требует комплексного подхода к подготовке данных, исследованиям, конфигурации и, в частности, к созданию и загрузке собственных векторов. Учитывая вышеописанные рекомендации, вы сможете получить вектор, способный отражать смысл вашего специального термина, и добиться точности в вычислении семантического сходства.
Если у вас остались вопросы, не стесняйтесь спрашивать, чтобы повысить результативность вашей работы с spaCy.