Есть несколько способов, с которыми вы можете иметь дело. Я не думаю, что могу привести ссылку на то, что работает лучше.
Не обучаемый вариант :
- Случайный вектор как вложение
- Вы можете использовать все нулевые векторы для OOV.
- Вы можете иметь в виду весь вектор внедрения, чтобы избежать риска быть в стороне от фактического распределения.
- Также вложения обычно идут с «unk» векторами, изученными во время обучения, которым вы можете воспользоваться.
Вариант обучения :
Вы можете объявить отдельный вектор встраивания для OOV и сделать его обучаемым, сохраняя другие встраивания фиксированными. Возможно, вам придется переписать прямой метод встраивания поиска для этого. Вы можете объявить новый обучаемый Variable
и в прямом проходе использовать этот вектор как вложение для OOV вместо поиска.
Обращаясь к комментариям ОП:
Я не уверен, какой из трех не обучаемых методов может работать лучше, и я не уверен, есть ли какая-то работа по этому поводу. Но метод 4) должен работать лучше.
Для обучаемой опции вы можете создать новый слой для встраивания, как показано ниже.
class Embeddings_new(torch.nn.Module):
def __init__(self, dim, vocab):
super().__init__()
self.embedding = torch.nn.Embedding(vocab, dim)
self.embedding.weight.requires_grad = False
# vector for oov
self.oov = torch.nn.Parameter(data=torch.rand(1,dim))
self.oov_index = -1
self.dim = dim
def forward(self, arr):
N = arr.shape[0]
mask = (arr==self.oov_index).long()
mask_ = mask.unsqueeze(dim=1).float()
embed =(1-mask_)*self.embedding((1-mask)*arr) + mask_*(self.oov.expand((N,self.dim)))
return embed
Использование:
model = Embeddings_new(10,20000)
out = model.forward(torch.tensor([-1,-1, 100, 1, 0]))
# dummy loss
loss = torch.sum(a**2)
loss.backward()