NLP de la Traducere Scratch cu o secvență la secvență rețea și atenție - Tutoriale PyTorch 1

Acesta este al treilea și ultimul tutorial despre realizarea „NLP From Scratch”, unde ne scriem propriile clase și funcții pentru a preprocesa datele pentru a realiza sarcinile noastre de modelare NLP. Sperăm că, după finalizarea acestui tutorial, veți continua să aflați cum torchtext poate gestiona o mare parte din această preprocesare pentru dvs. în cele trei tutoriale imediat următoare.

În acest proiect vom preda o rețea neuronală pentru a traduce din franceză în engleză.

… La diferite grade de succes.

Acest lucru este posibil prin ideea simplă, dar puternică, a rețelei secvență în secvență, în care două rețele neuronale recurente funcționează împreună pentru a transforma o secvență în alta. O rețea de codificare condensează o secvență de intrare într-un vector, iar o rețea de decodare desfășoară acel vector într-o nouă secvență.

scratch

Pentru a îmbunătăți acest model, vom folosi un mecanism de atenție, care permite decodorului să învețe să se concentreze pe un anumit interval al secvenței de intrare.

Lectură recomandată:

Presupun că ați instalat cel puțin PyTorch, cunoașteți Python și înțelegeți tensorii:

  • https://pytorch.org/ Pentru instrucțiuni de instalare
  • Învățare profundă cu PyTorch: un Blitz de 60 de minute pentru a începe cu PyTorch în general
  • Învățarea PyTorch cu exemple pentru o imagine de ansamblu largă și profundă
  • PyTorch pentru foștii utilizatori Torch dacă sunteți un fost utilizator Lua Torch

De asemenea, ar fi util să știm despre rețelele Secvență în secvență și cum funcționează:

Veți găsi, de asemenea, tutoriale anterioare despre NLP From Scratch: Clasificarea numelor cu un RNN la nivel de caracter și NLP From Scratch: Generarea de nume cu un RNN la nivel de caracter util, deoarece aceste concepte sunt foarte asemănătoare cu modelele Encoder și respectiv Decoder.

Și pentru mai multe, citiți lucrările care au introdus aceste subiecte:

Cerințe

Se încarcă fișiere de date

Datele pentru acest proiect sunt un set de mii de perechi de traduceri din engleză în franceză.

Această întrebare din Open Data Stack Exchange m-a indicat spre site-ul de traducere deschis https://tatoeba.org/ care are descărcări disponibile la https://tatoeba.org/eng/downloads - și mai bine, cineva a făcut munca suplimentară de divizare perechi de limbi în fișiere text individuale aici: https://www.manythings.org/anki/

Perechile din engleză în franceză sunt prea mari pentru a fi incluse în repo, așa că descărcați pe data/eng-fra.txt înainte de a continua. Fișierul este o listă separată de tabele de perechi de traduceri:

Descărcați datele de aici și extrageți-le în directorul curent.

Similar cu codificarea caracterelor folosită în tutorialele RNN la nivel de caractere, vom reprezenta fiecare cuvânt într-o limbă ca un vector cu un singur fierbinte sau vector gigant de zerouri, cu excepția unuia singur (la indexul cuvântului). Comparativ cu zecile de caractere care ar putea exista într-o limbă, există multe alte cuvinte, deci vectorul de codificare este mult mai mare. Cu toate acestea, vom înșela puțin și vom tăia datele pentru a folosi doar câteva mii de cuvinte pe limbă.

Vom avea nevoie de un index unic pe cuvânt pentru a-l folosi ca intrări și ținte ale rețelelor mai târziu. Pentru a urmări toate acestea, vom folosi o clasă de ajutor numită Lang care are dicționare cuvânt → index (word2index) și index → ​​word (index2word), precum și un număr al fiecărui cuvânt word2count de utilizat pentru a înlocui ulterior cuvintele rare.

Fișierele sunt toate în Unicode, pentru a simplifica, vom transforma caracterele Unicode în ASCII, vom face totul cu litere mici și vom tăia cele mai multe punctuații.

Pentru a citi fișierul de date, vom împărți fișierul în linii, apoi le vom împărți în perechi. Fișierele sunt toate engleză → Altă limbă, așa că dacă dorim să traducem din altă limbă → engleză, am adăugat steagul invers pentru a inversa perechile.

Deoarece există o mulțime de propoziții de exemplu și dorim să instruim ceva rapid, vom reduce setul de date doar la propoziții relativ scurte și simple. Aici lungimea maximă este de 10 cuvinte (care include punctuația de încheiere) și trecem la propoziții care se traduc în forma „Eu sunt” sau „El este” etc. (contabilizarea apostrofelor înlocuite anterior).

Procesul complet de pregătire a datelor este:

  • Citiți fișierul text și împărțiți-l în linii, împărțiți liniile în perechi
  • Normalizați textul, filtrați după lungime și conținut
  • Faceți liste de cuvinte din propoziții în perechi

Modelele Seq2Seq

O rețea neuronală recurentă sau RNN este o rețea care funcționează pe o secvență și își folosește propria ieșire ca intrare pentru pașii următori.

O rețea de secvență la secvență sau rețea seq2seq sau rețea de decodare a codificatorului este un model format din două RNN-uri numite codificator și decodor. Codificatorul citește o secvență de intrare și scoate un singur vector, iar decodorul citește acel vector pentru a produce o secvență de ieșire.

Spre deosebire de predicția secvenței cu un singur RNN, unde fiecare intrare corespunde unei ieșiri, modelul seq2seq ne eliberează de lungimea și ordinea secvenței, ceea ce îl face ideal pentru traducerea între două limbi.

Luați în considerare propoziția „Je ne suis pas le chat noir” → „Eu nu sunt pisica neagră”. Majoritatea cuvintelor din propoziția de intrare au o traducere directă în propoziția de ieșire, dar sunt în ordine ușor diferite, de ex. „Chat noir” și „pisică neagră”. Datorită construcției „ne/pas”, mai există încă un cuvânt în propoziția de intrare. Ar fi dificil să se producă o traducere corectă direct din secvența cuvintelor introduse.