Söz yerləşdirmə və dil modelləşdirmə | AI-yə doğru

Deterministik word2vec / doc2vec / abzas vektorları necə əldə edilir

Tamam, Word Yerləşdirmə aralığımıza xoş gəlmisiniz. Bu yazı seriyanın ilk hekayəsidir. Bəlkə də bu hekayə ən azı bir dəfə Word2Vec və ya Doc2Vec / Paragraph vektorlarını öyrətmiş və ya sınamış olan inkişaf etmiş və ya yuxarıdakılar üçün uyğundur. Ancaq narahat olmayın, aşağıdakı məlumatlarda məqalələrdən istifadə edərək kodun tətbiqi ilə yanaşı məlumatları, tələbləri və bilikləri təqdim edəcəyəm.

Sizi yorucu dərsləri oxumağınızı və imtina etməyinizi xahiş edən digər linklərə yönəltməmək üçün əlimdən gələni edəcəyəm (inanın, onlayn dərsliklərin qurbanı mənəm :)). Söz yerləşdiricilərini kodlaşdırma səviyyəsindən başa düşmək üçün mənimlə işləməyinizi istərdim ki, söz yerləşdirməyimizi və dil modelimizi necə dizayn edib tətbiq edəcəyimizi bilək.

Söz vektorlarını özünüz öyrətmək imkanınız varsa, eyni məşq məlumatlarını daxil etsəniz də, hər məşq üçün model və vektor təmsilçiliyinin fərqli olduğunu görə bilərsiniz. Bu, təlim dövründə tətbiq olunan təsadüfilikdən irəli gəlir. Kod özü üçün danışa bilər. Təsadüfiliyin haradan gəldiyini və bunu necə hərtərəfli aradan qaldıracağınızı görək. Kodu göstərmək üçün DL4j-nin abzas vektorlarının tətbiqindən istifadə edəcəyəm. Digər paketə baxmaq istəyirsinizsə, eyni tətbiqetmə metoduna sahib olan gensims doc2vec-ə gedin.

Təsadüfiliyin haradan gəldiyi

Model çəkilərinin başlanğıcı və vektor təqdimatı

Təlimdən əvvəl bir modelin və vektorun göstərilməsinin ağırlıqlarının təsadüfi başlanğıc edildiyini və təsadüfi başlanğıc dəyəri ilə idarə olunduğunu bilirik. Beləliklə, başlanğıc dəyərini 0 olaraq təyin etsək, hər dəfə eyni başlanğıc əldə edirik. Toxumun yerləşdiyi yer budur. Burada syn0 model ağırlığıdır və Nd4j.rand tərəfindən işə salınır

// Nd4j, Nd4j.getRandom () əvvəl toxum konfiqurasiyasını alır. SetSeed (configuration.getSeed ());
// Nd4j, syn0 üçün təsadüfi bir matris başlatır syn0 = Nd4j.rand (yeni int [] {vocab.numWords (), vectorLength}, rng) .si (0,5) .divi (vectorLength);

PV-DBOW alqoritmi

Təlimin təkrarlanması zamanı Paraqraf Vektorlarını öyrətmək üçün PV-DBOW alqoritmindən (təfərrüatları aşağıdakı yazılarda izah edəcəyəm) istifadə etdikdə, mətn pəncərəsindən sözlər çəkiləri hesablamaq və yeniləmək üçün təsadüfi alt nümunələrə qoyulur. Ancaq bu təsadüf həqiqətən təsadüfi deyil. Kodu nəzərdən keçirək.

// növbəti təsadüfi mövzu identifikatoru ilə başlanılan AtomicLong, this.nextRandom = new AtomicLong (this.threadId);

Və nextRandom istifadə olunur

trainSequence (ardıcıllıq, nextRandom, alfa);

QatarSequence-də harada olacaq

nextRandom.set (nextRandom.get () * 25214903917L + 11);

Təlim addımlarına nəzər salsaq, nextRandom-un eyni şəkildə, yəni eyni riyaziyyat əməliyyatını həyata keçirərək (bu və bunun səbəbini bilmək üçün) yaradıldığını görərik ki, 0, 1, 2, 3 , .... Beləliklə, artıq təsadüfi deyil.

Paralel tokenizasiya

Paralel işarələr üçün istifadə olunur, çünki mürəkkəb mətn prosesi çox vaxt apara bilər. Paralel nişan vermə qabiliyyətini artıra bilər, eyni zamanda təlimlər arasındakı uyğunluğa zəmanət verilmir. Tokenayzer tərəfindən işlənmiş ardıcıllıqlar təsadüfi qaydada öyrədiləcək iplərə verilə bilər. Koddan da göründüyü kimi, allowParallelBuilder-i false olaraq təyin etsək, məlumat daxil etmə qaydası qorunub saxlanmasına baxmayaraq, tokenizasiya edən icraedici başa çatana qədər gözləyir.

if (! allowParallelBuilder) {Deneyin {runnable.awaitDone (); } tutmaq (InterruptException e) {Thread.currentThread (). Interrupt (); yeni bir RuntimeException (e) atın; }}

Təlim ediləcək hər bir mövzu üçün ardıcıllıqlar təmin edən növbə

Bu LinkedBlockingQueue, təlim mətninin təkrarçısından ardıcıllığı çağırır və bu ardıcıllığı hər mövzuya təqdim edir. Hər bir iplik, məşq əsnasında istənilən anda təsadüfi bir şəkildə gələ bildiyindən, hər bir iplik təlim üçün fərqli ardıcıllıqla ola bilər. Bu məlumat təminatçının tətbiqinə nəzər salaq.

// Mövzular üçün məlumat təmin etmək üçün bir sekvenser başladın val sequencer = new AsyncSequencer (this.iterator, this.stopWords);
// Hər bir mövzu eyni ardıcıllığa işarə edir // işçi istifadə etmək istədiyimiz mövzuların sayıdır (int x = 0; x
// Sequencer bir LinkedBlockingQueue tamponunu başlatır // və ölçüsü [limitLower, limitUpper] xüsusi final LinkedBlockingQueue arasında saxlayır > bufer; limitLower = işçi * batchSize; limitUpper = işçilər * batchSize * 2;
// Mövzular buffer.poll (3L, TimeUnit.SECONDS) vasitəsilə növbədən məlumat alır;

Beləliklə, işçi sayını 1-ə təyin etsək, tək bir mövzuda icra ediləcək və hər təlimlə eyni məlumatların verilməsi qaydasına sahib olacaqdır. Ancaq nəzərə alın ki, tək bir iplik təhsili olduqca yavaşlatacaq.

Xülasə et

Xülasə olaraq, təsadüfiliyi tamamilə istisna etmək üçün aşağıdakılar edilməlidir: 1. Başlanğıc dəyərini 0 olaraq təyin edin; 2. allowParallelTokenization-ı false olaraq təyin edin. 3. İşçilərin (mövzuların) sayını 1 olaraq təyin edin. Sonra eyni məlumatları daxil etsək, eyni söz vektoru və abzas vektoru nəticələrini əldə edirik.

Nəhayət, təlim üçün kodumuz belədir:

ParagraphVectors vec = yeni ParagraphVectors.Builder () .minWordFrequency (1) .labels (labelsArray) .layerSize (100) .stopWords (new ArrayList) ()) .windowSize (5) .qayırmaq (iter) .allowParallelTokenization (false) .worker (1) .saat (0) .tokenizerFactory (t) .build (); vec.fit ();

İstəsən

Xahiş edirəm söz yerləşdirmə və dil modeli ilə bağlı növbəti hekayələri izləyin, festivalı sizin üçün hazırladım.

istinad

[1] Deeplearning4j, ND4J, DataVec və daha çox - GPU + + Spark ilə Java / Scala üçün Dərin Öyrənmə və Xətti Cəbr - Skymind-dən http://deeplearning4j.org https://github.com/deeplearning4j/deeplearning4j
[2] Java ™ Platforması, Standard Edition 8 API spesifikasiyası https://docs.oracle.com/javase/8/docs/api/
[3] https://giphy.com/
[4] https://images.google.com/