Выбор функции потерь для lstm, обученного на векторах word2vec, когда целью является вектор с такими же размерами - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть lstm, который я использую в качестве генератора последовательности, обученного на векторах word2vec.Предыдущая реализация производила распределение вероятностей для всех различных меток.Был один ярлык для каждого слова в словаре.Эта реализация использовала CrossEntropyLoss от Pytorch.Теперь я хочу изменить это так, чтобы lstm вывел вектор, который имеет те же размеры, что и векторы, используемые для обучения.Таким образом, я мог бы использовать евклидову меру расстояния, чтобы сопоставить остроумие с соседними векторами в словаре.Проблема в том, что для этого мне нужно использовать другую функцию потерь, потому что CrossEntropyLoss подходит для классификаторов, а не для проблем регрессии.

Я попытался изменить формат целевого вектора, но функция CrossEntropyLoss факела требует целочисленного ввода, и у меня есть слово vector.Посмотрев на несколько вариантов, кажется, что Cosine Embedded Loss может быть хорошей идеей, но я не понимаю, как это работает и какой ввод требует.

Я уже изменил свой полностью подключенный слой, чтобы выводить векторы того же размера, что и вложения Word, используемые для обучения:

nn.Linear(in_features=self.cfg.lstm.lstm_num_hidden,out_features=self.cfg.lstm.embedding_dim,bias=True)

Буду очень признателен за любые советы и примеры.

1 Ответ

2 голосов
/ 25 сентября 2019

Как указано в документации CosineEmbeddingLoss :

Создает критерий, который измеряет потери с учетом двух входных тензоров и метки Tensor со значениями 1 или -1.

В вашем сценарии вы всегда должны указывать 1 в качестве метки Tensor.

batch_size, seq_len, w2v_dim = 32, 100, 200
x1 = torch.randn(batch_size, seq_len, w2v_dim)
x2 = torch.randn(batch_size, seq_len, w2v_dim)
y = torch.ones(batch_size, seq_len)
loss_fn = torch.nn.CosineEmbeddingLoss(reduction='none')
loss = loss_fn(x1.view(-1, w2v_dim), 
               x2.view(-1, w2v_dim),  
               y.view(-1))
loss = loss.view(batch_size, seq_len)

Здесь я предполагаю, что x1 - это вложение слова, x2 - это выход LSTM.с последующим некоторым преобразованием.

Почему я всегда должен указывать 1 в качестве метки Tensor?

Сначала вы должны увидеть функцию потерь.

enter image description here

В вашем сценарии, чем выше сходство косинусов, тем меньше должны быть потери.Другими словами, вы хотите максимизировать косинусное сходство.Таким образом, вам нужно указать 1 в качестве метки.

С другой стороны, если вы хотите минимизировать косинусное сходство, вам нужно указать -1 в качестве метки.

...