Даруни модел
Чаро ба даруни модел нигарем?
Pipeline то вақте қулай аст, ки тамғаи тайёр басанда бошад. Барои қоидаҳои шахсии эътимод, таҳлили хато ё ҷустуҷӯи маъноӣ фаҳмидани натиҷаи ададии шабака лозим аст. Logit, эҳтимолият ва вектори token-ро фарқ кунед: ин намояндагиҳо вазифаҳои гуногун доранд.
Дар лоиҳаи воқеӣ AutoTokenizer.from_pretrained(name) ва AutoModelForSequenceClassification.from_pretrained(name) ҷуфти мувофиқро мегиранд. model(**enc) майдонҳои tokenizer-ро ҳамчун аргументҳои номдор медиҳад. Ин ҷо объектҳои маҳаллӣ ва ададҳои маълумро бе боргирии вазнҳо истифода мекунем.
Мисолҳоро бо тартиб иҷро кунед. Сохтани модел аз конфигуратсия вазнҳои омӯхташударо намегирад: намуна шакли додаҳоро нишон медиҳад, на сифати пешгӯиро.
1. Натиҷаи гурӯҳбандӣ
Logit баҳои хоми синф аст; он метавонад манфӣ ё аз як калон бошад. SequenceClassifierOutput баҳоро дар майдони logits нигоҳ медорад. Меҳвари аввал матнҳо ва охирин синфҳост. Номҳо алоҳида дар config.id2label ҳастанд.
import torch
from transformers import BertConfig, BertModel, PretrainedConfig
from transformers.modeling_outputs import SequenceClassifierOutput
outputs = SequenceClassifierOutput(logits=torch.tensor([[1.0, 3.0], [0.0, 0.0]]))
config = PretrainedConfig(id2label={0: 'NEGATIVE', 1: 'POSITIVE'})
print(list(outputs.logits.shape))
print(config.id2label[1])
Натиҷа:
[2, 2]
POSITIVE
Шакли [2, 2] ду матн ва ду синфро ифода мекунад. Рақами 1 танҳо аз рӯйи конфигуратсия POSITIVE аст. Ба тартиби «манфӣ ҳамеша аввал» такя кардан мумкин нест.
2. Эҳтимолиятҳо аз рӯйи сатр
Softmax баҳоро ба ададҳои мусбати ҷамъашон тақрибан як табдил медиҳад. Logit нисбат ба ҳамсояҳо ҳар қадар калон бошад, эҳтимолият баландтар аст. dim=-1 меҳвари охирин, яъне синфҳои ҳар матнро интихоб мекунад.
probs = torch.softmax(outputs.logits, dim=-1)
print([[round(p, 3) for p in row] for row in probs.tolist()])
print(probs.sum(dim=-1).tolist())
Натиҷа:
[[0.119, 0.881], [0.5, 0.5]]
[0.9999999403953552, 1.0]
Сатри аввал синфи дуюмро афзал медонад, дуюм онҳоро фарқ намекунад. Ҷамъи 0.99999994 ба ҷойи расо 1 хатои муқаррарии float32 аст. Logit ва эҳтимолияти калонтарин як синфро нишон медиҳанд, аммо logit-и хом эътимод нест.
3. Натиҷаи модели асосӣ
Head қабати иловагӣ барои ҷавоби вазифаи мушаххас аст. AutoModel модели асосиро бе head-и гурӯҳбандӣ мегирад. last_hidden_state барои ҳар мавқеъ як вектор дорад, на барои тамоми матн якто.
eval() рафтори ҳолати омӯзишӣ, масалан dropout-ро хомӯш мекунад. torch.no_grad() сабти gradient-ро қатъ мекунад; ин амали дигар ва барои пешгӯӣ муфид аст.
model = BertModel(BertConfig(vocab_size=10, hidden_size=8, num_hidden_layers=1, num_attention_heads=2, intermediate_size=16)).eval()
enc = {'input_ids': torch.tensor([[2, 5, 3, 0]]), 'attention_mask': torch.tensor([[1, 1, 1, 0]])}
with torch.no_grad():
h = model(**enc).last_hidden_state
print(list(h.shape))
print(enc['attention_mask'].sum(dim=1).tolist())
Натиҷа:
[1, 4, 8]
[3]
Шакли [1, 4, 8] як матн, чор мавқеъ ва ҳашт адад дар векторро ифода мекунад. Се мавқеъ ҳақиқӣ аст. Векторҳои пуркунанда ҳатто бо ниқоби дуруст ҳатман сифр нестанд.
4. Ниқоб ҳангоми миёнагирӣ
Pooling чанд векторро ба якто табдил медиҳад. Роҳи сода миёнаи мавқеъҳои ҳақиқӣ аст. Як координатаро бинем: қимати сеюм ба пуркунанда тааллуқ дорад ва набояд ба миёна таъсир расонад.
values = torch.tensor([4.0, 8.0, 90.0])
mask = torch.tensor([1, 1, 0])
real = values[mask.bool()]
print(real.tolist())
print(real.mean().item())
Натиҷа:
[4.0, 8.0]
6.0
Миёна 6 аст, на 34. Барои векторҳои пурра принсип ҳамон аст: пуркунандаҳоро хориҷ ва ҷамъро ба шумораи мавқеъҳои дохилшуда тақсим кунед. Token-ҳои махсус метавонанд бимонанд, агар ба омӯзиш мувофиқ бошад. Ниқоби холӣ қоидаи алоҳида мехоҳад.
5. Самт ва монандии маъноӣ
Embedding намояндагии ададии матн аст. Ҷустуҷӯ аксар вақт самти векторҳоро бо монандии косинусӣ муқоиса мекунад. Дароз кардан самтро дигар намекунад: дарозии 7 ба ҷойи 1 ба мувофиқат халал намерасонад.
a = torch.tensor([0.0, 1.0])
b = torch.tensor([0.0, 7.0])
c = torch.tensor([1.0, 0.0])
print(torch.nn.functional.cosine_similarity(a, b, dim=0).item())
print(torch.nn.functional.cosine_similarity(a, c, dim=0).item())
Натиҷа:
1.0
0.0
Як ҳамсамтӣ, сифр амудӣ ва минус як муқобилсамтиро нишон медиҳад. Монандии маъноӣ модели барои чунин намояндагӣ омӯхташударо мехоҳад. Миёнагирии BERT-и тасодуфӣ онро ба низоми хуби ҷустуҷӯ табдил намедиҳад.
Дар дохил чӣ мегузарад?
Рақамҳо ба вектор табдил меёбанд, қабатҳои attention контексти мавқеъҳоро омехта мекунанд ва head баҳои синфҳоро ҳисоб мекунад. Softmax тақсимот месозад. Ҷустуҷӯ векторҳои дохилӣ ва pooling-и ба омӯзиш мувофиқро мегирад. Ба ҳуҷҷат бахш ё тавсифи ҷустуҷӯӣ додан мумкин аст: ҳар намояндагӣ фоидаи худро дорад.
Хатоҳои маъмул
softmax(logits, dim=0)матнҳои ҷудоро мепайвандад. Барои синфҳои ҳар матн меҳвари охиринро гиред.outputs.logitsдарBertModel-и одӣAttributeErrorмедиҳад. Head-и мувофиқ ёlast_hidden_stateлозим аст.h.mean(dim=1)padding-ро дохил карда, бо тағйири баста намояндагиро дигар мекунад. Ниқоб ва шумораи мавқеъҳои ҳақиқиро ба ҳисоб гиред.- Танҳо
torch.no_grad()dropout-и ҳолати омӯзиширо хомӯш намекунад. Барои пешгӯӣeval()-ро низ даъват кунед. vectors @ queryаз дарозии векторҳо вобаста аст. Барои самт cosine similarity ё векторҳои меъёриро истифода кунед.
Ёдномаи кӯтоҳ
| Объект | Шакл ё маъно |
|---|---|
logits |
(N, C): матнҳо ва синфҳо |
softmax(..., dim=-1) |
тақсимот аз рӯйи синфҳо |
config.id2label |
рақам → ном |
last_hidden_state |
(N, L, H): матнҳо, мавқеъҳо, координатаҳо |
attention_mask |
мавқеъҳои иштироккунанда |
| cosine similarity | муқоисаи самтҳо |