Можно ли добавлять другие слои (attention, менять структуру, могут ли быть разные головы, …)
Добавить пример реализациия Two-Tower DSSM на PyTorch
Модификации DSSM (Multi-head DSSM?) и доп ссылки его применения (WB, LAMODA, Yandex Market, Yandex Dzen, …)
Интуицию
BoW
Embedding
DSSM
Цель обучения состоит в том, чтобы увеличить вероятность того, что модель предскажет документ, на который пользователь кликнет, исходя из запроса. То есть, если пользователь кликнул на документ, этот документ считается релевантным для данного запроса, и модель должна обучиться предсказывать такие результаты.
Входной слой: 30000 нейронов
Это соответствует размеру хешированного вектора признаков после обработки текста N-граммами.
Первый скрытый слой: 300 нейронов
Второй скрытый слой: 300 нейронов
Выходной слой: 128 нейронов
Это финальное семантическое представление запроса или документа
текстовые данные обрабатываются через bag of words с применением n-грамм (обычно от 1 до 3) и после применяется хеширование
В оригинальной статье используется 3 полносвязных слоя с нелинейными функциями активациями tanh
CODE EXAMPLE
# loss func
- L = -log P(d+|q) # -torch.log(prob)
- P(d+|q) = exp(γ R(q,d+)) / Σ exp(γ R(q,di)) # prob
- q - вектор запроса # query_vec
- d+ - вектор релевантного документа # pos_doc_vec
- di - векторы всех документов в наборе (включая релевантный) # all_cosines
- R(q,d) - косинусное сходство между векторами # pos_cosine
- γ - коэффициент масштабирования (обычно 10) # gamma
import torch
import torch.nn.functional as F
def loss_function(query_vec, pos_doc_vec, neg_doc_vecs, gamma=10):
# Вычисляем косинусное сходство между запросом и позитивным документом
pos_cosine = F.cosine_similarity(query_vec, pos_doc_vec)
# Вычисляем косинусное сходство между запросом и каждым негативным документом
neg_cosines = [F.cosine_similarity(query_vec, neg_doc_vec) for neg_doc_vec in neg_doc_vecs]
neg_cosines = torch.stack(neg_cosines)
all_cosines = torch.cat([pos_cosine.unsqueeze(0)] + neg_cosines)
# Применяем экспоненту с масштабированием
exp_pos = torch.exp(gamma * pos_cosine)
exp_all = torch.sum(torch.exp(gamma * all_cosines))
# Вычисляем вероятность позитивного документа
prob = exp_pos / exp_all
# Вычисляем отрицательный логарифм вероятности (функция потерь)
loss = -torch.log(prob) #
return loss
Башня фильма строит эмбеддинг на основе данных о фильме: это заголовок, описание, жанр, страна, актёры и т. д. Эта часть сети достаточно сильно похожа на поисковую. Однако для зрителя мы хотим использовать его историю. Чтобы это сделать, мы агрегируем эмбеддинги фильмов из истории с затуханием по времени с момента события. Затем поверх суммарного эмбеддинга применяем несколько слоёв сети и в итоге получаем эмбеддинг размера 400.
DSSM — это нейросеть из двух башен. Каждая башня строит свой эмбеддинг, затем между эмбеддингами считается косинусное расстояние, это число — выход сети. То есть сеть учится оценивать близость объектов в левой и правой башне. Подобные нейросети используются, например, в , чтобы находить релевантные запросу документы. Для задачи поиска в одну из башен подаётся запрос, в другую — документ. Для нашей сети роль запроса играет пользователь, а в качестве документов выступают фильмы.