项目地址
git@github.com:graykode/nlp-tutorial.git
NNLM
首先看数据是个啥
sentences = ["i like dog", "i love coffee", "i hate milk"]
目的, 用 i like
预测 dog
, 用i love
预测 coffe
其实就是语言模型(下式为n-gram)
$ P ^ ( w t ∣ w 1 t − 1 ) ≈ P ^ ( w t ∣ w t − n + 1 t − 1 ) \hat{P}\left(w_{t} \mid w_{1}^{t-1}\right) \approx \hat{P}\left(w_{t} \mid w_{t-n+1}^{t-1}\right) P^(wt∣w1t−1)≈P^(wt∣wt−n+1t−1)$
首先是Embedding
self.C = nn.Embedding(n_class, m)
demo中一共有7个词, 其实是一个7x2的线性层
进Embedding前:
X.shape
Out[13]: torch.Size([3, 2])
3个batch, 2个step(根据前两个词预测后一个词是什么, 相当与2-gram)
进Embedding后:
X.shape
Out[15]: torch.Size([3, 2, 2])
分布式表示. 不然如果用OHE 就是[3, 2, 7]
了.
X = X.view(-1, n_step * m)
X.shape
Out[16]: torch.Size([3, 4])
对2个词做了拼接, 方便喂给线性层
self.H(X).shape
Out[17]: torch.Size([3, 2])
出隐层
tanh = torch.tanh(self.d + self.H(X)) # [batch_size, n_hidden]
self.H = nn.Linear(n_step * m, n_hidden, bias=False)
self.d = nn.Parameter(torch.ones(n_hidden))
self.U = nn.Linear(n_hidden, n_class, bias=False)
self.W = nn.Linear(n_step * m, n_class, bias=False)
self.b = nn.Parameter(torch.ones(n_class))
tanh = torch.tanh(self.d + self.H(X)) # [batch_size, n_hidden]
output = self.b + self.W(X) + self.U(tanh) # [batch_size, n_class]
需要注意的是, 如果用了CrossEntropyLoss
损失函数, 不需要手动加softmax