Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

SNLI-textual-entailment

Progetto realizzato in collaborazione con Shahed Akter per il corso di Applicazioni Informatiche dell'Intelligenza Artificiale alla Sapienza nell'a.a. 2024/2025. Si tratta di un task di textual entailment sullo Stanford Natural Language Inference dataset.

Il Dataset

La target variable ‘gold_label’ assume 4 valori diversi: ‘entailment’, ‘contradiction’, ‘neutral’ e ‘-’. Quando non è ‘-’ ci sono due casi possibili: se le label da 2 a 5 sono assenti, ha lo stesso valore della label 1; altrimenti rappresenta la scelta della maggioranza degli annotatori (label da 1 a 5). Se il voto degli annotatori non è conclusivo, ‘gold_label’ è ‘-’. Notiamo che nella maggior parte dei casi le label da 2 a 5 sono assenti (oltre 510.000 sample sugli oltre 550.000 presenti nel training set); pertanto abbiamo deciso di eliminare le colonne rappresentanti le annotazioni Inoltre abbiamo eliminato le colonne contenenti il parse e il binary parse delle frasi perché abbiamo deciso di lavorare solo con la rappresentazione sequenziale delle frasi e non con con la struttura sintattica. Quindi abbiamo tenuto solo ‘gold_label’, ‘sentence1’ e ‘sentence2’. Abbiamo eliminato i sample contenenti un trattino come etichetta, dopo aver verificato che rappresentavano solo una percentuale trascurabile dei sample totali; abbiamo anche eliminato i pochi sample (6) in cui l’ipotesi (‘sentence2’) era completamente assente. I dati erano già suddivisi in tre file diversi per il training, il validation e il test set. Abbiamo verificato che sia la distribuzione delle etichette che la lunghezza media della premessa e dell’ipotesi sono simili in tutti e tre.

L’embedding

Abbiamo scelto di usare i vettori preaddestrati di GloVe per l’embedding; abbiamo provato a utilizzare sia i vettori di dimensione 100 che quelli di dimensione 300 e abbiamo notato un significativo miglioramento della performance con quelli di dimensione maggiore. Per utilizzarli abbiamo costruito un vocabolario tokenizzando le parole presenti nel corpus utilizzando semplicemente le espressioni regolari; abbiamo preferito questo metodo a tokenizzazioni più sofisticate perché l’uso delle espressioni regolari è computazionalmente più efficiente e la performance del modello non ne ha risentito, dal momento che le frasi non presentano caratteri speciali e la poca punteggiatura presente non è rilevante per il task.

Dataset e Dataloader

All’interno della classe del dataset, nella funzione getitem, tokenizziamo la premessa e l’ipotesi e, tramite una funzione di supporto definita appositamente, restituiamo un vettore contenente gli indici associati nel vocabolario costruito precedentemente. Abbiamo scelto di impostare la batch size a 512 perché ci è sembrato il miglior compromesso tra performance e velocità dell’addestramento.

Modello base

Il nostro modello base è una semplice rete neurale costituita da un layer di embedding, in cui abbiamo reso addestrabile la matrice degli embedding; l’embedding delle due frasi avviene separatamente, e su ciascun output applichiamo il mean pooling. I due tensori risultanti da questa operazione vengono concatenati lungo l’asse dell’embedding_dim, e infine applichiamo un layer lineare finale, che insieme alla funzione di loss scelta, Cross Entropy Loss, può essere visto come una regressione logistica multiclasse. Come ottimizzatore abbiamo scelto Adam. Per velocizzare l’addestramento del modello abbiamo deciso di utilizzare la mixed precision a 16 bit; abbiamo anche implementato l’early stopping basato sulla validation accuracy. Nonostante la sua semplicità, il modello raggiunge dei discreti risultati; infatti, l’accuracy sul test set si attesta intorno al 66%. Dal momento che le etichette sono molto ben bilanciate f1, precision e recall sono molto vicine al valore dell’accuracy.

BiLSTM

La soluzione migliorativa che abbiamo pensato si basa su un LSTM bidirezionale. Innanzitutto c’è, come nel caso precedente, un layer di embedding con la matrice di embedding addestrabile. L’embedding avviene separatamente per premessa e ipotesi nella funzione di supporto encode; abbiamo aggiunto anche un layer di dropout per un maggiore effetto regolarizzante sul modello. Ciascuna frase è poi data in input a un LSTM bidirezionale con hidden_dim pari a 256 e con 2 layer (questi sono gli iperparametri selezionati tramite grid search). Dal risultato estraiamo gli hidden state dell’ultimo layer, sia forward che reverse, e li concateniamo; a questo concateniamo poi anche la media e il massimo dell’output calcolati lungo dim=1 (la lunghezza delle sequenze). In questo caso utilizziamo il pooling per aggiungere più informazioni che identifichino ciascuna frase; in questo modo otteniamo una rappresentazione più sofisticata. In forward applichiamo encode a premessa e ipotesi; calcoliamo poi le interazioni tra le due, in particolare il valore assoluto della differenza e il prodotto di Hadamard (punto per punto) delle due rappresentazioni. La nostra idea si basa infatti sulla similarità tra le due frasi, e questo è un modo abbastanza semplice di implementarla nel nostro modello. Abbiamo provato a utilizzare invece la similarità del coseno, ma la performance era peggiore; probabilmente usare sia la differenza che il prodotto tra le due rappresentazioni permette di cogliere più aspetti della similarità (o dissimilarità) tra le frasi. Infine abbiamo concatenato le rappresentazioni delle due frasi e le due interazioni, e le abbiamo date in input a una sequenza composta da un layer lineare, ReLU, un layer di dropout e un layer lineare finale. La funzione di loss che abbiamo utilizzato è anche in questo caso Cross Entropy Loss, mentre come ottimizzatore abbiamo usato AdamW, in particolare nella sua variante AMSGrad, che applicando il weight decay direttamente nell’aggiornamento dei parametri e non alla loss come Adam (regolarizzazione L2) ha ridotto di molto la velocità con cui il modello va in overfitting. L’accuracy del modello è abbastanza alta, così come lo sono precision, recall e f1. Guardando però il classification report notiamo che la performance è diversa sulle tre classi; la maggior parte degli errori viene fatta per la classe ‘neutral’; sia precision che recall sono infatti di diversi punti più basse rispetto a ‘contradiction’ e ‘entailment’. A parte alcuni casi in cui l’ambiguità delle frasi rende il lavoro difficile anche per un essere umano, guardando i sample che il modello classifica male sembra che spesso si tratti di casi in cui la premessa e l’ipotesi presentano molte delle stesse parole. Questo potrebbe significare che ci siamo concentrati troppo sulla similarità tra le frasi e che bisognerebbe trovare un modo migliore per catturare meglio le differenze tra premessa e ipotesi, o forse che servirebbe un modo migliore per rappresentare le frasi.

Possibili miglioramenti

Per migliorare la performance del modello senza stravolgerne l’architettura secondo noi si può lavorare su due fronti. Il primo è quello della rappresentazione delle frasi, che potrebbe essere resa più sofisticata per esempio aggiungendo delle informazioni sulla struttura sintattica della frase; l’analisi degli errori mostra che il punto debole del modello è più probabilmente l’aspetto semantico, ma l’aggiunta di questo genere di informazione potrebbe comunque contribuire a migliorarne le prestazioni. L’altro fronte riguarda proprio l’aspetto semantico: si potrebbe cercare un modo migliore per catturare la similarità ma soprattutto la differenza tra le frasi. Inoltre, dall’analisi degli errori emerge che spesso il modello sbaglia a classificare sample in cui la premessa e l’ipotesi sono uguali a meno di una o due parole che però cambiano di molto il significato delle frasi e quindi la relazione tra le due; potrebbe quindi essere utile implementare un meccanismo che non tenga conto solo della similarità tra le intere frasi, ma anche delle singole parole, magari quelle più rilevanti.

About

Textual entailment sul dataset SNLI con BiLSTM.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages