În urmă cu 60 de ani, calculatoarele erau ceva ce putea fi folosit doar după multă pregătire și cu foarte multă atenție, altfel tot efortul tău era irosit. Astăzi, toată lumea are în buzunar un calculator mult mai puternic, care poate fi folosit cu ușurință de oricine.
În mod similar, în urmă cu cincisprezece ani, a lucra cu text liber (cum ar fi articolele de știri, postările de pe bloguri, comentariile de pe rețelele de socializare, articolele juridice și așa mai departe) și a extrage informații din acesta erau sarcini foarte dificile, care necesitau multă muncă manuală pentru a adnota date și un anumit volum de cunoștințe de lingvistică și matematică pentru a scrie algoritmii de la zero. Dar progresele recente în domeniul deep learning și al procesării limbajului natural (NLP) au făcut toate acestea mult mai ușoare, permițând crearea unor proof of concepts în câteva ore sau cel mult câteva zile și la un nivel calitativ superior.
NLP este folosit zilnic de aproape toată lumea. Siri, Google Assistant și alte chatboturi îl folosesc pentru a înțelege ce vrem să facem atunci când vorbim cu telefoanele noastre. Google Search se bazează foarte mult pe modele NLP pentru a ne oferi rezultate mai bune la căutările noastre. Companiile aplică analiza sentimentelor la postările din social media pentru a înțelege ce părere au clienții despre noile lor produse și cum sunt percepute rebranduirile. Cererile de asistență de la clienți pot fi clasificate mai rapid cu ajutorul unor modele de NLP, astfel încât să se petreacă mai puțin timp pentru a trimite problema la persoana potrivită și mai mult timp pentru a rezolva problema utilizatorului. Jurnaliștii pot extrage din documente ce persoane, locații și organizații sunt menționate în acestea, pentru a permite o căutare mai facilă în ele. Acestea sunt doar câteva exemple de utilizare a NLP.
Unul dintre marile progrese în NLP a venit în 2018, când Jacob Devlin et al. au publicat un articol intitulat "BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding", în care au prezentat un nou model de învățare automată bazat pe Transformers, care poate fi antrenat pe zeci de gigabytes de date, într-un mod generic, și ulterior poate fi ajustat pentru aproape orice tip de sarcină.
BERT a fost adoptat rapid: în 2019 era deja utilizat pentru Google Search, iar în următorii 2-3 ani, cercetătorii au continuat să aplice BERT în tot mai multe domenii, obținând rezultate mult mai bune decât înainte.
Au existat multe îmbunătățiri ale BERT în anii următori, de la DistillBERT, care a redus dimensiunea modelului și l-a făcut mai rapid, la RoBERTa, care a crescut acuratețea modelului, la CamemBERT, care este pentru limba franceză, și așa mai departe.
Modelele de tip BERT pot fi utilizate pentru aproape toate sarcinile NLP: pot clasifica texte, extrage entități, răspunde la întrebări despre documente și pot spune dacă un text implică logic un alt text.
BERT și alte modele similare sunt antrenate într-un mod nesupravegheat, ceea ce înseamnă că nu au nevoie de date adnotate. Din acest motiv, poate fi antrenat pe cantități mult mai mari de date, care pot fi obținute prin crawling sau din cărți. Alte modele NLP au nevoie de învățare supravegheată, deci ar avea nevoie de date adnotate de oameni cu categoria corespunzătoare pentru clasificarea textului sau de entitățile care le conțin pentru recunoașterea entităților numite.
Pentru a se antrena în mod nesupravegheat, BERT a avut două obiective. Primul, numit masked language modelling (MLM), este generat prin luarea unei propoziții ("Lui George îi place plăcinta cu mere"), mascarea unui cuvânt ("Lui George îi [MASK] plăcinta cu mere") și apoi BERT trebuia să prezică care este cuvântul mascat în acest caz (place). De obicei, aproximativ 15% din cuvinte au fost mascate în corpul de antrenament. Celălalt obiectiv este next sentence prediction, în care se iau două propoziții din setul de date, uneori consecutive, alteori la întâmplare, și BERT trebuie să prezică dacă acestea sunt consecutive sau nu.
Setul de date utilizat de BERT în 2018 a fost format din 3,3 miliarde de cuvinte luate de pe Wikipedia și din Toronto Book Corpus. Modele ulterioare au fost antrenate pe un număr și mai mare de cuvinte, cum ar fi RoBERTa, antrenat pe 33 de miliarde de tokenuri (aproximativ 160 Gb de text).
Aceste modele sunt, de obicei, antrenate de companii precum Google, Facebook, OpenAI, Microsoft sau Baidu și apoi sunt publicate sub o licență permisivă, și oricine poate să le folosească în mod gratuit. Această antrenare inițială este costisitoare, necesitând câteva zile pe clustere cu sute de GPU. Dar ulterior, oricine poate ajusta un model BERT pe un singur GPU, pentru a îndeplini sarcinile care îl interesează.
Aceste modele sunt atât de puternice deoarece ajung să conțină cunoștințe despre tot ceea ce se află în setul de date de antrenare. Deoarece sunt foarte multe date de antrenare, câteva zeci de gigabytes de articole, mesaje de pe forumuri, bloguri, știri, cărți și alte texte extrase de pe internet, ele ajung să conțină cunoștințe despre tot ceea ce se scrie pe internet, ceea ce astăzi include cam orice. Din acest motiv, nu mai aveți nevoie de zeci de mii de exemple pentru a învăța un clasificator de texte bun, ci puteți obține rezultate bune chiar și cu doar câteva sute de exemple. Acest lucru reduce nevoia de colectare manuală a datelor, făcând mai ușoară și mai ieftină obținerea datelor pentru rezolvarea unei probleme cu ajutorul învățării automate.
Pregătirea pe astfel de seturi de date are, de asemenea, unele probleme: aceste modele au adesea prejudecăți (bias) și pot face predicții sexiste, rasiste sau cu alte tipuri de probleme.
Una dintre cele mai populare biblioteci pentru a lucra cu aceste modele avansate de tip Transformer se numește (emoticonul Hugging Face). Cum se poate utiliza pentru a antrena un clasificator de texte pentru a distinge între 10 clase? Mai întâi importăm toate bibliotecile necesare, încărcăm setul de date cu care vom lucra (în acest caz Yahoo Answers, unde va trebui să clasificăm întrebările în una dintre cele 10 categorii) și să inițializăm un model bert-base-cased
preantrenat, care este furnizat de către Google.
from datasets import load_dataset
from transformers import AutoTokenizer
from transformers import
AutoModelForSequenceClassification
from transformers import TrainingArguments,
Trainer
import numpy as np
from datasets import load_metric
dataset = load_dataset("yahoo_answers_topics")
tokenizer = AutoTokenizer
.from_pretrained("bert-base-cased")
model = AutoModelForSequenceClassification
.from_pretrained("bert-base-cased", num_labels=10)
Apoi, trebuie să preprocesăm textul: unim titlul întrebării și conținutul întrebării într-un singur șir de caractere și transformăm fiecare șir în token-uri (formatul acceptat de BERT). Apoi, împărțim setul de date în două: un set de date pentru antrenarea modelului, care conține 1000 de întrebări, și unul pentru evaluarea modelului, care conține alte 1000 de întrebări.
def tokenize_function(examples):
return tokenizer(examples["text"],
padding="max_length", truncation=True)
joined_dataset = dataset.map(
lambda example: {'text': example['question_title']
+ ' ' + example['question_content']})
tokenized_datasets = joined_dataset.map(
tokenize_function, batched=True)
.rename_column('topic', labels')
small_train_dataset = tokenized_datasets["train"]
.shuffle(seed=42).select(range(1000))
small_eval_dataset = tokenized_datasets["test"]
.shuffle(seed=42).select(range(1000))
Ultimul pas este să definim metrica pentru care dorim să optimizăm, în acest caz acuratețea, și apoi putem începe antrenamentul folosind clasa Trainer furnizată de HuggingFace.
metric = load_metric("accuracy")
def compute_metrics(eval_pred):
logits, labels = eval_pred
predictions = np.argmax(logits, axis=-1)
return metric.compute(predictions=predictions,
references=labels)
training_args = TrainingArguments(output_dir="test_trainer", evaluation_strategy="epoch",
num_train_epochs=5)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=small_train_dataset,
eval_dataset=small_eval_dataset,
compute_metrics=compute_metrics)
trainer.train()
Rularea acestui cod pe un GPU ne va oferi un model care atinge o acuratețe de 64% folosind doar 1000 de întrebări, din cele 1,4 milioane de întrebări din setul de date. În schimb, un model LogisticRegression scikit-learn are nevoie de cel puțin 100000 de întrebări pentru a atinge o precizie similară.
BERT poate fi utilizat pentru a clasifica documente fără a-i da vreun exemplu, pur și simplu prin valorificarea informațiilor semantice din cuvintele folosite pentru categorii.
În învățarea automată tradițională, numele categoriilor nu contează, deoarece acestea sunt codificate numeric, astfel încât, indiferent dacă este "politics", "A@!$DV" sau 100, modelul vede că aceasta este categoria numărul 2. Dar cu BERT, este posibil să se utilizeze orice informație semantică prezentă în categoria (dacă există). Pentru ca acest lucru să funcționeze, categoriile trebuie să aibă o anumită semantică (astfel, "Politica" va funcționa mai bine decât "A@!$$").
Cel mai frecvent mod de rezolvare a acestei probleme este reformularea problemei de clasificare a textului ca o problemă de deducere în limbaj natural (NLI). Aceste probleme NLI întreabă dacă există o relație de "implicare", "contradicție" sau "neutralitate" între două propoziții. Dacă stabilim că prima propoziție este documentul pentru care dorim să facem o predicție, iar cea de-a doua propoziție este "Acest document este despre ${TOPIC}", atunci putem cere modelului să ne spună care este relația dintre cele două "propoziții": dacă prima propoziție o implică pe cea de-a doua, documentul este probabil despre acel subiect, altfel nu. Facem acest lucru pentru toate subiectele de interes și îl alegem pe cel care are cea mai mare probabilitate.
Codul de încărcare a setului de date este similar cu cel de dinainte:
from transformers import pipeline
from datasets import load_dataset
from tqdm import trange
from sklearn.metrics import accuracy_score
dataset = load_dataset("yahoo_answers_topics")
joined_dataset = dataset.map(
lambda example: {'text': example['question_title'] + '' + example['question_content']})
Încărcarea modelului este un pic diferită și trebuie să dăm nume rezonabile adnotărilor, deoarece în setul de date acestea sunt doar numere:
zero_shot_classifier = pipeline(
'zero-shot-classification',
model="facebook/bart-large-mnli", device=0)
class_names = {0: "Society & Culture",
1: "Science & Mathematics",
4: "Computers & Internet",
7: "Entertainment & Music",
9: "Politics & Government",
2: "Health",
8: "Family & Relationships",
3: "Education & Reference",
6: "Business & Finance",
5: "Sports"}
Apoi, aplicăm pipeline-ul zero shot la cele 100 de întrebări din setul nostru de date și calculăm scorul de acuratețe prin compararea rezultatelor prezise cu rezultatele adevărate:
true_label = []
predicted_label = []
predictions = zero_shot_classifier(
joined_dataset['train'][:100]['text'],
list(class_names.values()),
hypothesis_template="This text is about {}.")
for idx in trange(100):
top_label = predictions[idx]['labels'][0]
true_label.append(class_names[dataset['train'][idx]
['topic']])
predicted_label.append(top_label)
print(accuracy_score(true_label, predicted_label))
În mod surprinzător, obținem o acuratețe de 52%, fără a face nicio antrenare. Pentru ceva care poate fi reutilizat foarte ușor, acesta este un rezultat foarte bun. Puteți folosi acest pipeline pentru a crea un proof of concept pentru a evalua dacă clasificarea textului poate funcționa pentru problema dvs., înainte de a petrece ore cu adnotarea datelor.
În aceast articol am văzut cum putem profita de modele Transformer mari preantrenate pentru a obține rezultate bune fie fără nicio antrenare, fie cu mult mai puține date adnotate decât este necesar pentru algoritmi mai vechi de învățare automată.
Dar datele adnotate dau în continuare cele mai bune rezultate, așa că data viitoare vom analiza modalități de a obține mai multe date adnotate mai rapid, folosind weakly supervised learning.