Doğal Dil Çıkarımı (NLI), bir öncül ve bir hipotez arasındaki mantıksal ilişkiyi belirlemek için kullanılan bir görevdir. Öncül, bir veri ya da önerme sunarken, hipotez, bu önerme ile ilgili çıkarımı belirtir. Dikkat mekanizmaları, bu iki metin dizisi arasındaki ilişkileri anlamak ve hizalamak için kullanılır.
Dikkat Mekanizması ile Hizalama
Dikkat mekanizması, bir metin dizisindeki belirteçleri (kelimeleri) diğer dizideki belirteçlerle hizalar. Bu, makine çevirisinde kaynak ve hedef cümleler arasındaki belirteç hizalamalarına benzer. Örneğin, "benim uykuya ihtiyacım var" öncülünü ve "ben yorgunum" hipotezini ele alalım. "Ben" belirteçleri ve "uyku" ile "yorgun" belirteçleri anlamsal olarak hizalanır.
Dikkat Mekanizmasını Kodlama
Karşılaştırma Adımı
Dikkat mekanizması ile hizalanan belirteçler, bir MLP (çok katmanlı algılayıcı) kullanılarak karşılaştırılır.
Biriktirme Adımı
Son adımda, karşılaştırma vektörleri toplanarak nihai çıkarımı yapmak için bir MLP'ye beslenir.
Modelin Birleştirilmesi
Dikkat etme, karşılaştırma ve biriktirme adımlarını birleştirerek modeli tanımlarız.
Modelin Eğitimi ve Değerlendirilmesi
SNLI veri kümesinde modeli eğitmek ve değerlendirmek için aşağıdaki adımlar izlenir.
Modeli Kullanma
Eğitilmiş modeli kullanarak, bir öncül ve hipotez arasındaki mantıksal ilişkiyi tahmin edebiliriz.
Kodlar, belirteç hizalama, karşılaştırma ve biriktirme adımlarını içerir ve modelin eğitimi ve değerlendirilmesi için gerekli tüm bileşenleri sağlar.
Dikkat Mekanizması ile Hizalama
Dikkat mekanizması, bir metin dizisindeki belirteçleri (kelimeleri) diğer dizideki belirteçlerle hizalar. Bu, makine çevirisinde kaynak ve hedef cümleler arasındaki belirteç hizalamalarına benzer. Örneğin, "benim uykuya ihtiyacım var" öncülünü ve "ben yorgunum" hipotezini ele alalım. "Ben" belirteçleri ve "uyku" ile "yorgun" belirteçleri anlamsal olarak hizalanır.
Dikkat Mekanizmasını Kodlama
Python:
import torch
from torch import nn
from torch.nn import functional as F
def mlp(num_inputs, num_hiddens, flatten):
net = [nn.Dropout(0.2), nn.Linear(num_inputs, num_hiddens), nn.ReLU()]
if flatten:
net.append(nn.Flatten(start_dim=1))
net.extend([nn.Dropout(0.2), nn.Linear(num_hiddens, num_hiddens), nn.ReLU()])
if flatten:
net.append(nn.Flatten(start_dim=1))
return nn.Sequential(*net)
class Attend(nn.Module):
def __init__(self, num_inputs, num_hiddens):
super(Attend, self).__init__()
self.f = mlp(num_inputs, num_hiddens, flatten=False)
def forward(self, A, B):
f_A = self.f(A)
f_B = self.f(B)
e = torch.bmm(f_A, f_B.permute(0, 2, 1))
beta = torch.bmm(F.softmax(e, dim=-1), B)
alpha = torch.bmm(F.softmax(e.permute(0, 2, 1), dim=-1), A)
return beta, alpha
Karşılaştırma Adımı
Dikkat mekanizması ile hizalanan belirteçler, bir MLP (çok katmanlı algılayıcı) kullanılarak karşılaştırılır.
Python:
class Compare(nn.Module):
def __init__(self, num_inputs, num_hiddens):
super(Compare, self).__init__()
self.g = mlp(num_inputs, num_hiddens, flatten=False)
def forward(self, A, B, beta, alpha):
V_A = self.g(torch.cat([A, beta], dim=2))
V_B = self.g(torch.cat([B, alpha], dim=2))
return V_A, V_B
Biriktirme Adımı
Son adımda, karşılaştırma vektörleri toplanarak nihai çıkarımı yapmak için bir MLP'ye beslenir.
Python:
class Aggregate(nn.Module):
def __init__(self, num_inputs, num_hiddens, num_outputs):
super(Aggregate, self).__init__()
self.h = mlp(num_inputs, num_hiddens, flatten=True)
self.linear = nn.Linear(num_hiddens, num_outputs)
def forward(self, V_A, V_B):
V_A = V_A.sum(dim=1)
V_B = V_B.sum(dim=1)
Y_hat = self.linear(self.h(torch.cat([V_A, V_B], dim=1)))
return Y_hat
Modelin Birleştirilmesi
Dikkat etme, karşılaştırma ve biriktirme adımlarını birleştirerek modeli tanımlarız.
Python:
class DecomposableAttention(nn.Module):
def __init__(self, vocab, embed_size, num_hiddens, num_inputs_attend, num_inputs_compare, num_inputs_agg):
super(DecomposableAttention, self).__init__()
self.embedding = nn.Embedding(len(vocab), embed_size)
self.attend = Attend(num_inputs_attend, num_hiddens)
self.compare = Compare(num_inputs_compare, num_hiddens)
self.aggregate = Aggregate(num_inputs_agg, num_hiddens, num_outputs=3)
def forward(self, X):
premises, hypotheses = X
A = self.embedding(premises)
B = self.embedding(hypotheses)
beta, alpha = self.attend(A, B)
V_A, V_B = self.compare(A, B, beta, alpha)
Y_hat = self.aggregate(V_A, V_B)
return Y_hat
Modelin Eğitimi ve Değerlendirilmesi
SNLI veri kümesinde modeli eğitmek ve değerlendirmek için aşağıdaki adımlar izlenir.
Python:
from d2l import torch as d2l
batch_size, num_steps = 256, 50
train_iter, test_iter, vocab = d2l.load_data_snli(batch_size, num_steps)
embed_size, num_hiddens, devices = 100, 200, d2l.try_all_gpus()
net = DecomposableAttention(vocab, embed_size, num_hiddens, 100, 200, 400)
glove_embedding = d2l.TokenEmbedding('glove.6b.100d')
embeds = glove_embedding[vocab.idx_to_token]
net.embedding.weight.data.copy_(embeds)
lr, num_epochs = 0.001, 4
trainer = torch.optim.Adam(net.parameters(), lr=lr)
loss = nn.CrossEntropyLoss(reduction="none")
d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, devices)
Modeli Kullanma
Eğitilmiş modeli kullanarak, bir öncül ve hipotez arasındaki mantıksal ilişkiyi tahmin edebiliriz.
Python:
def predict_snli(net, vocab, premise, hypothesis):
net.eval()
premise = torch.tensor(vocab[premise], device=d2l.try_gpu())
hypothesis = torch.tensor(vocab[hypothesis], device=d2l.try_gpu())
label = torch.argmax(net([premise.reshape((1, -1)), hypothesis.reshape((1, -1))]), dim=1)
return 'entailment' if label == 0 else 'contradiction' if label == 1 else 'neutral'
predict_snli(net, vocab, ['he', 'is', 'good', '.'], ['he', 'is', 'bad', '.'])
Kodlar, belirteç hizalama, karşılaştırma ve biriktirme adımlarını içerir ve modelin eğitimi ve değerlendirilmesi için gerekli tüm bileşenleri sağlar.


