Hoşgeldin Misafir

Doğal Dil Çıkarımı: Dikkati Kullanma Modeli

Mustafa73

20 Eyl 2023
423 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
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
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.