ჩვენს წინა მაგალითში, ჩვენ ვიმუშავეთ მაღალგანზომილებიანი ჩანთა-სიტყვების ვექტორებზე vocab_size სიგრძით, და ჩვენ აშკარად ვაკონვერტირებდით დაბალი განზომილებიანი პოზიციური წარმოდგენის ვექტორებიდან იშვიათ one-hot წარმოდგენაში. ეს one-hot წარმოდგენა არ არის მეხსიერების ეფექტური, გარდა ამისა, თითოეული სიტყვა განიხილება ერთმანეთისგან დამოუკიდებლად, ანუ one-hot დაშიფრული ვექტორები არ გამოხატავს რაიმე სემანტიკურ მსგავსებას სიტყვებს შორის.
ამ განყოფილებაში ჩვენ გავაგრძელებთ News AG მონაცემთა ბაზის შესწავლას. დასაწყისისთვის, მოდით ჩატვირთოთ მონაცემები და მივიღოთ გარკვეული განმარტებები წინა ნოუთბუქიდან.
იტვირთება…გამოტანა
Loading dataset...
d:\WORK\ai-for-beginners\5-NLP\14-Embeddings\data\train.csv: 29.5MB [00:01, 18.8MB/s]
d:\WORK\ai-for-beginners\5-NLP\14-Embeddings\data\test.csv: 1.86MB [00:00, 11.2MB/s]
Building vocab...
Vocab size = 95812
რა არის ჩანერგვა?
ჩანერგვის იდეა არის სიტყვების წარმოდგენა ქვედა განზომილებიანი მკვრივი ვექტორებით, რომლებიც გარკვეულწილად ასახავს სიტყვის სემანტიკურ მნიშვნელობას. ჩვენ მოგვიანებით განვიხილავთ, თუ როგორ უნდა ავაშენოთ შინაარსიანი სიტყვების ემბედინგი, მაგრამ ახლა მოდით, უბრალოდ ვიფიქროთ ემბედინგიზე, როგორც სიტყვის ვექტორის განზომილების შემცირების გზაზე.
ასე რომ, ჩაშენებული ფენა მიიღებს სიტყვას, როგორც შეყვანის სახით და წარმოქმნის მითითებულ embedding_size-ის გამომავალ ვექტორს. გარკვეული გაგებით, ის ძალიან ჰგავს Linear ფენას, მაგრამ იმის ნაცვლად, რომ აიღოს one-hot კოდირებული ვექტორი, მას შეეძლება სიტყვის რიცხვის მიღება შეყვანის სახით.
ჩვენს ქსელში პირველ ფენად ჩაშენების ფენის გამოყენებით, ჩვენ შეგვიძლია გადავიტანოთ ჩანთა-of-words ჩაშენების ტომარაზე მოდელზე, სადაც ჯერ ჩვენს ტექსტში თითოეულ სიტყვას გადავიყვანთ შესაბამის ემბედინგიდ და შემდეგ გამოვთვალოთ აგრეგატული ფუნქცია ყველა ამ ემბედინგიზე, როგორიცაა sum, CODE_____ ან CODE_____ ან.

ჩვენი კლასიფიკატორის ნერვული ქსელი დაიწყება ჩაშენებული ფენით, შემდეგ აგრეგაციის ფენით და მის თავზე ხაზოვანი კლასიფიკატორით:
იტვირთება…საქმე ცვლადი თანმიმდევრობის ზომასთან
ამ არქიტექტურის შედეგად, ჩვენს ქსელში მინი პარტიები უნდა შეიქმნას გარკვეული გზით. წინა ერთეულში, სიტყვების ჩანთაში გამოყენებისას, ყველა BoW ტენსორს მინი პარტიაში ჰქონდა თანაბარი ზომა vocab_size, მიუხედავად ჩვენი ტექსტის თანმიმდევრობის რეალური სიგრძისა. მას შემდეგ რაც გადავალთ სიტყვების ემბედინგიზე, ჩვენ მივიღებთ სიტყვების ცვლადი რაოდენობას თითოეულ ტექსტურ ნიმუშში და ამ ნიმუშების მინი პატჩებში გაერთიანებისას ჩვენ უნდა გამოვიყენოთ გარკვეული შიგთავსი.
ეს შეიძლება გაკეთდეს მონაცემთა წყაროსთვის collate_fn ფუნქციის მიწოდების იგივე ტექნიკის გამოყენებით:
იტვირთება…ტრენინგის ჩაშენების კლასიფიკატორი
ახლა, როდესაც ჩვენ განვსაზღვრეთ შესაბამისი მონაცემთა ჩამტვირთავი, ჩვენ შეგვიძლია მოვამზადოთ მოდელი წინა განყოფილებაში განსაზღვრული სასწავლო ფუნქციის გამოყენებით:
იტვირთება…გამოტანა
3200: acc=0.6415625
6400: acc=0.6865625
9600: acc=0.7103125
12800: acc=0.726953125
16000: acc=0.739375
19200: acc=0.75046875
22400: acc=0.7572321428571429
(0.889799795315499, 0.7623160588611644)შენიშვნა: ჩვენ ვვარჯიშობთ მხოლოდ 25 ათასი ჩანაწერისთვის (ერთ სრულ ეპოქაზე ნაკლები) დროის გულისთვის, მაგრამ შეგიძლიათ განაგრძოთ ვარჯიში, დაწეროთ ფუნქცია რამდენიმე ეპოქის ვარჯიშისთვის და ექსპერიმენტი სწავლის სიჩქარის პარამეტრზე უფრო მაღალი სიზუსტის მისაღწევად. თქვენ უნდა შეძლოთ დაახლოებით 90% სიზუსტეზე წასვლა.
EmbeddingBag Layer და ცვლადი სიგრძის თანმიმდევრობის წარმოდგენა
წინა არქიტექტურაში, ჩვენ გვჭირდებოდა ყველა თანმიმდევრობის ერთნაირი სიგრძის დაყენება, რათა მინიპატჩში მოვთავსდეთ. ეს არ არის ყველაზე ეფექტური გზა ცვლადი სიგრძის თანმიმდევრობების წარმოსაჩენად - სხვა მეთოდი იქნება ოფსეტური ვექტორის გამოყენება, რომელიც შეიცავდა ერთ დიდ ვექტორში შენახული ყველა თანმიმდევრობის ოფსეტებს.

შენიშვნა: ზემოთ მოცემულ სურათზე ჩვენ ვაჩვენებთ სიმბოლოების თანმიმდევრობას, მაგრამ ჩვენს მაგალითში ვმუშაობთ სიტყვების თანმიმდევრობით. თუმცა, მიმდევრობების ოფსეტური ვექტორით წარმოდგენის ზოგადი პრინციპი იგივე რჩება.
ოფსეტური წარმომადგენლობით სამუშაოდ, ჩვენ ვიყენებთ Embedding Bag ფენას. ის მსგავსია Embedding-ის, მაგრამ შეყვანის სახით იღებს შინაარსის ვექტორს და ოფსეტური ვექტორს და ასევე მოიცავს საშუალო შრეს, რომელიც შეიძლება იყოს mean, sum ან max.
აქ არის შეცვლილი ქსელი, რომელიც იყენებს EmbeddingBag-ს:
იტვირთება…მონაცემთა ნაკრების მოსამზადებლად ტრენინგისთვის, ჩვენ უნდა მივაწოდოთ კონვერტაციის ფუნქცია, რომელიც მოამზადებს ოფსეტური ვექტორს:
იტვირთება…გაითვალისწინეთ, რომ ყველა წინა მაგალითისგან განსხვავებით, ჩვენი ქსელი ახლა იღებს ორ პარამეტრს: მონაცემთა ვექტორს და ოფსეტურ ვექტორს, რომლებიც სხვადასხვა ზომისაა. ანალოგიურად, ჩვენი მონაცემთა ჩამტვირთავი ასევე გვაწვდის 3 მნიშვნელობას 2-ის ნაცვლად: ორივე ტექსტი და ოფსეტური ვექტორები მოცემულია როგორც ფუნქციები. ამიტომ, ჩვენ უნდა ოდნავ მოვარგოთ ჩვენი სავარჯიშო ფუნქცია, რომ ვიზრუნოთ ამაზე:
იტვირთება…გამოტანა
3200: acc=0.6153125
6400: acc=0.6615625
9600: acc=0.6932291666666667
12800: acc=0.715078125
16000: acc=0.7270625
19200: acc=0.7382291666666667
22400: acc=0.7486160714285715
(22.771553103007037, 0.7551983365323096)სემანტიკური ემბედინგები: Word2Vec
ჩვენს წინა მაგალითში, მოდელის ჩანერგვის ფენამ ისწავლა სიტყვების ვექტორული წარმოდგენის დახატვა, თუმცა ამ წარმოდგენას არ ჰქონდა დიდი სემანტიკური მნიშვნელობა. კარგი იქნებოდა ვისწავლოთ ისეთი ვექტორული წარმოდგენა, რომ მსგავსი სიტყვები ან სინონიმები შეესაბამებოდეს ვექტორებს, რომლებიც ახლოს არიან ერთმანეთთან გარკვეული ვექტორული მანძილით (მაგ. ევკლიდიური მანძილით).
ამისათვის ჩვენ წინასწარ უნდა მოვამზადოთ ჩვენი ჩაშენების მოდელი ტექსტის დიდ კოლექციაზე კონკრეტული გზით. სემანტიკური ჩაშენების მომზადების ერთ-ერთ პირველ გზას ჰქვია Word2Vec. იგი დაფუძნებულია ორ მთავარ არქიტექტურაზე, რომლებიც გამოიყენება სიტყვების განაწილებული წარმოდგენის შესაქმნელად:
- სიტყვების უწყვეტი ტომარა (CBoW): ამ არქიტექტურაში ჩვენ ვწვრთნით მოდელს სიტყვის პროგნოზირებისთვის მიმდებარე კონტექსტიდან. $(W_{-2},W_{-1},W_0,W_1,W_2)$ ნგრამის გათვალისწინებით, მოდელის მიზანია $W_0$-ის პროგნოზირება $(W_{-2},W_{-1},W_1,W_2)$-დან.
- უწყვეტი skip-gram არის CBoW-ის საპირისპირო. მოდელი იყენებს კონტექსტური სიტყვების მიმდებარე ფანჯარას მიმდინარე სიტყვის პროგნოზირებისთვის.
CBoW უფრო სწრაფია, ხოლო skip-gram უფრო ნელი, მაგრამ უკეთესად ასრულებს იშვიათი სიტყვების წარმოდგენას.

Google News მონაცემთა ბაზაში წინასწარ მომზადებული word2vec ჩაშენების ექსპერიმენტებისთვის, შეგვიძლია გამოვიყენოთ gensim ბიბლიოთეკა. ქვემოთ ვპოულობთ სიტყვებს, რომლებიც ყველაზე მეტად ჰგავს "ნერვულს"
შენიშვნა: როდესაც პირველად ქმნით სიტყვების ვექტორებს, მათ ჩამოტვირთვას შეიძლება გარკვეული დრო დასჭირდეს!
იტვირთება…იტვირთება…გამოტანა
neuronal -> 0.7804799675941467
neurons -> 0.7326500415802002
neural_circuits -> 0.7252851724624634
neuron -> 0.7174385190010071
cortical -> 0.6941086649894714
brain_circuitry -> 0.6923246383666992
synaptic -> 0.6699118614196777
neural_circuitry -> 0.6638563275337219
neurochemical -> 0.6555314064025879
neuronal_activity -> 0.6531826257705688
ჩვენ ასევე შეგვიძლია გამოვთვალოთ ვექტორული ემბედინგები სიტყვიდან, რომლებიც გამოყენებული იქნება ტრენინგის კლასიფიკაციის მოდელში (სიცხადისთვის ვაჩვენებთ მხოლოდ ვექტორის პირველ 20 კომპონენტს):
იტვირთება…გამოტანა
array([ 0.01226807, 0.06225586, 0.10693359, 0.05810547, 0.23828125,
0.03686523, 0.05151367, -0.20703125, 0.01989746, 0.10058594,
-0.03759766, -0.1015625 , -0.15820312, -0.08105469, -0.0390625 ,
-0.05053711, 0.16015625, 0.2578125 , 0.10058594, -0.25976562],
dtype=float32)სემანტიკური ჩაშენების შესახებ კარგი რამ არის ის, რომ შეგიძლიათ ვექტორული კოდირების მანიპულირება სემანტიკის შესაცვლელად. მაგალითად, შეგვიძლია მოვითხოვოთ ვიპოვოთ სიტყვა, რომლის ვექტორული წარმოდგენა რაც შეიძლება ახლოს იქნება სიტყვებთან king და woman და რაც შეიძლება შორს სიტყვიდან man:
იტვირთება…გამოტანა
('queen', 0.7118192911148071)ორივე CBoW და Skip-Grams არის „პროგნოზირებადი“ ემბედინგები, რადგან ისინი ითვალისწინებენ მხოლოდ ადგილობრივ კონტექსტს. Word2Vec არ იყენებს გლობალურ კონტექსტს.
FastText, ეფუძნება Word2Vec-ს, თითოეული სიტყვისთვის ვექტორული წარმოდგენების და თითოეულ სიტყვაში ნაპოვნი სიმბოლოების n-გრამების შესწავლით. შემდეგ წარმომადგენლობების მნიშვნელობები საშუალოდ ერთ ვექტორად ხდება ყოველი ვარჯიშის საფეხურზე. მიუხედავად იმისა, რომ ეს უამრავ დამატებით გამოთვლას მატებს წინასწარ ტრენინგს, ის აძლევს სიტყვის ემბედინგის ქვესიტყვის ინფორმაციის დაშიფვრის საშუალებას.
კიდევ ერთი მეთოდი, GloVe, იყენებს თანამოხვედრის მატრიცის იდეას, იყენებს ნერვულ მეთოდებს თანამოხვედრის მატრიცის უფრო გამოხატულ და არაწრფივ სიტყვის ვექტორებად დასაშლელად.
თქვენ შეგიძლიათ ითამაშოთ მაგალითზე ემბედინგების შეცვლით FastText-ზე და GloVe-ზე, რადგან gensim მხარს უჭერს სიტყვების ჩაშენების რამდენიმე სხვადასხვა მოდელს.
წინასწარ გაწვრთნილი ემბედინგების გამოყენება PyTorch-ში
ჩვენ შეგვიძლია შევცვალოთ ზემოთ მოყვანილი მაგალითი, რათა წინასწარ შევავსოთ მატრიცა ჩვენს ჩაშენების ფენაში სემანტიკური ემბედინგებით, როგორიცაა Word2Vec. უნდა გავითვალისწინოთ, რომ წინასწარ მომზადებული ჩაშენების ლექსიკა და ჩვენი ტექსტის კორპუსი სავარაუდოდ არ ემთხვევა, ამიტომ გამოტოვებული სიტყვების წონებს შემთხვევითი მნიშვნელობებით მოვაწყობთ:
იტვირთება…გამოტანა
Embedding size: 300
Populating matrix, this will take some time...Done, found 41080 words, 54732 words missing
ახლა მოდით ვავარჯიშოთ ჩვენი მოდელი. გაითვალისწინეთ, რომ მოდელის მომზადებისთვის საჭირო დრო გაცილებით დიდია, ვიდრე წინა მაგალითში, ჩაშენებული ფენის უფრო დიდი ზომის და, შესაბამისად, პარამეტრების გაცილებით მეტი რაოდენობის გამო. ასევე, ამის გამო შეიძლება დაგვჭირდეს ჩვენი მოდელის სწავლება უფრო მეტ მაგალითზე, თუ გვინდა, რომ თავიდან ავიცილოთ ზედმეტი მორგება.
იტვირთება…გამოტანა
3200: acc=0.6359375
6400: acc=0.68109375
9600: acc=0.7067708333333333
12800: acc=0.723671875
16000: acc=0.73625
19200: acc=0.7463541666666667
22400: acc=0.7560714285714286
(214.1013875559821, 0.7626759436980166)ჩვენს შემთხვევაში, ჩვენ ვერ ვხედავთ სიზუსტის დიდ ზრდას, რაც, სავარაუდოდ, საკმაოდ განსხვავებული ლექსიკაა. სხვადასხვა ლექსიკის პრობლემის დასაძლევად შეგვიძლია გამოვიყენოთ ერთ-ერთი შემდეგი გამოსავალი:
- ხელახლა ავარჯიშეთ word2vec მოდელი ჩვენს ლექსიკაზე
- ჩატვირთეთ ჩვენი მონაცემთა ნაკრები წინასწარ მომზადებული word2vec მოდელის ლექსიკით. მონაცემთა ნაკრების ჩასატვირთად გამოყენებული ლექსიკა შეიძლება დაზუსტდეს ჩატვირთვის დროს.
ეს უკანასკნელი მიდგომა უფრო მარტივი ჩანს, განსაკუთრებით იმიტომ, რომ PyTorch torchtext ჩარჩო შეიცავს ჩაშენებულ მხარდაჭერას ჩაშენებისთვის. ჩვენ შეგვიძლია, მაგალითად, გამოვიყენოთ GloVe-ზე დაფუძნებული ლექსიკა შემდეგი გზით:
იტვირთება…გამოტანა
100%|█████████▉| 399999/400000 [00:15<00:00, 25411.14it/s]
დატვირთულ ლექსიკას აქვს შემდეგი ძირითადი ოპერაციები:
vocab.stoiლექსიკონი საშუალებას გვაძლევს გადავიყვანოთ სიტყვა მის ლექსიკონის ინდექსშიvocab.itosაკეთებს საპირისპიროს - აქცევს რიცხვს სიტყვადvocab.vectorsარის ჩაშენებული ვექტორების მასივი, ასე რომ, სიტყვის ჩადგმის მისაღებადsუნდა გამოვიყენოთvocab.vectors[vocab.stoi[s]]
აქ მოცემულია ჩაშენებით მანიპულირების მაგალითი განტოლების კეთილი კაცი+ქალი = დედოფალი განტოლების დემონსტრირებისთვის (მოიწია კოეფიციენტის ოდნავ შესწორება, რომ ის იმუშაოს):
იტვირთება…გამოტანა
'queen'იმისათვის, რომ მოვამზადოთ კლასიფიკატორი ამ ემბედინგების გამოყენებით, ჩვენ ჯერ უნდა დავაშიფროთ ჩვენი მონაცემთა ბაზა GloVe ლექსიკის გამოყენებით:
იტვირთება…როგორც ზემოთ ვნახეთ, ყველა ვექტორული ემბედინგი ინახება vocab.vectors მატრიცაში. ეს ძალიან მარტივს ხდის ამ წონის ჩატვირთვას ჩაშენებული ფენის წონაში მარტივი კოპირების გამოყენებით:
იტვირთება…ახლა მოდით ვავარჯიშოთ ჩვენი მოდელი და ვნახოთ, მივიღებთ თუ არა უკეთეს შედეგებს:
იტვირთება…გამოტანა
3200: acc=0.6271875
6400: acc=0.68078125
9600: acc=0.7030208333333333
12800: acc=0.71984375
16000: acc=0.7346875
19200: acc=0.7455729166666667
22400: acc=0.7529464285714286
(35.53972978646833, 0.7575175943698017)ერთ-ერთი მიზეზი, რის გამოც ჩვენ ვერ ვხედავთ სიზუსტის მნიშვნელოვან ზრდას, არის ის ფაქტი, რომ ჩვენი მონაცემთა ნაკრებიდან ზოგიერთი სიტყვა აკლია წინასწარ მომზადებულ GloVe ლექსიკაში და, შესაბამისად, ისინი არსებითად იგნორირებულია. ამ ფაქტის დასაძლევად, ჩვენ შეგვიძლია მოვამზადოთ საკუთარი ემბედინგები ჩვენს მონაცემთა ბაზაში.
კონტექსტური ემბედინგები
ტრადიციული წინასწარ გაწვრთნილი ჩაშენების წარმოდგენის ერთ-ერთი მთავარი შეზღუდვა, როგორიცაა Word2Vec, არის სიტყვის გაგების გაუგებრობის პრობლემა. მიუხედავად იმისა, რომ წინასწარ გაწვრთნილ ჩაშენებებს შეუძლიათ სიტყვების ზოგიერთი მნიშვნელობის აღქმა კონტექსტში, სიტყვის ყველა შესაძლო მნიშვნელობა დაშიფრულია იმავე ჩასმაში. ამან შეიძლება გამოიწვიოს პრობლემები ქვედა დინების მოდელებში, რადგან ბევრ სიტყვას, როგორიცაა სიტყვა „თამაში“ განსხვავებული მნიშვნელობა აქვს იმისდა მიხედვით, თუ რა კონტექსტში გამოიყენება.
მაგალითად, სიტყვა "თამაში" ამ ორ განსხვავებულ წინადადებაში საკმაოდ განსხვავებული მნიშვნელობა აქვს:
- თეატრში სპექტაკლზე წავედი.
- ჯონს სურს თამაში მეგობრებთან ერთად.
ზემოთ მომზადებული ემბედინგები წარმოადგენს სიტყვა „თამაშის“ ორივე მნიშვნელობას იმავე ემბედინგიში. ამ შეზღუდვის დასაძლევად, ჩვენ უნდა ავაშენოთ ემბედინგები ენის მოდელზე საფუძველზე, რომელიც გაწვრთნილია ტექსტის დიდ კორპუსზე და იცის როგორ შეიძლება სიტყვების გაერთიანება სხვადასხვა კონტექსტში. კონტექსტური ემბედინგების განხილვა არ არის ამ სახელმძღვანელოსთვის, მაგრამ ჩვენ მათ დავუბრუნდებით, როდესაც ვისაუბრებთ ენის მოდელებზე მომდევნო თავში.