9.4 Rekurentiniai neuroniniai tinklai

9.3 skyrelis aprašėme Markovo modelius ir nn-gramas kalbos modeliavimui, kur teksto vieneto xtx_t sąlyginė tikimybė laiko žingsniu tt priklauso tik nuo n−1n-1 ankstesnių teksto vienetų. Jei norime įtraukti galimą teksto vienetų, ankstesnių nei laiko žingsnis t−(n−1)t-(n-1), poveikį xtx_t, turime didinti nn. Tačiau modelio parametrų skaičius taip pat didėtų eksponentiškai, nes žodyno aibei V\mathcal{V} turėtume saugoti ∣V∣n|\mathcal{V}|^n skaičių. Todėl užuot modeliavus P(xt∣xt−1,…,xt−n+1)P(x_t \mid x_{t-1}, \ldots, x_{t-n+1}), pageidautina naudoti latentinio kintamojo modelį,

P(xt∣xt−1,…,x1)≈P(xt∣ht−1),P(x_t \mid x_{t-1}, \ldots, x_1) \approx P(x_t \mid h_{t-1}),

kur ht−1h_{t-1} yra paslėptoji būsena, saugojanti sekos informaciją iki laiko žingsnio t−1t-1. Apskritai paslėptąją būseną bet kuriuo laiko žingsniu tt galima apskaičiuoti pagal ir dabartinę įvestį xtx_{t}, ir ankstesnę paslėptąją būseną ht−1h_{t-1}:

ht=f(xt,ht−1).(9.4.1)h_t = f(x_{t}, h_{t-1}). \tag{9.4.1}

Pakankamai galingai funkcijai ff (9.4.1) latentinio kintamojo modelis nėra aproksimacija. Juk hth_t gali tiesiog saugoti visus iki šiol stebėtus duomenis. Tačiau tai gali padaryti brangius ir skaičiavimus, ir saugojimą.

Prisiminkite, kad paslėptuosius sluoksnius su paslėptaisiais vienetais aptarėme 5 skyrelis. Verta pažymėti, kad paslėptieji sluoksniai ir paslėptosios būsenos reiškia dvi labai skirtingas sąvokas. Paslėptieji sluoksniai, kaip paaiškinta, yra sluoksniai, paslėpti nuo žvilgsnio kelyje nuo įvesties iki išvesties. Paslėptosios būsenos techniškai kalbant yra įvestys tam, ką darome duotame žingsnyje, ir jas galima apskaičiuoti tik žiūrint į ankstesnių laiko žingsnių duomenis.

Rekurentiniai neuroniniai tinklai (RNN) yra neuroniniai tinklai su paslėptosiomis būsenomis. Prieš pristatydami RNN modelį, pirmiausia grįžkime prie MLP modelio, pristatyto 5.1 skyrelis.

from d2l import mxnet as d2l
from mxnet import np, npx
npx.set_np()
from d2l import torch as d2l
import torch
from d2l import tensorflow as d2l
import tensorflow as tf
from d2l import jax as d2l
import jax
from jax import numpy as jnp

9.4.1 Neuroniniai tinklai be paslėptųjų būsenų

Pažvelkime į MLP su vienu paslėptuoju sluoksniu. Tegul paslėptojo sluoksnio aktyvacijos funkcija yra ϕ\phi. Turint pavyzdžių minirinkinį X∈Rn×d\mathbf{X} \in \mathbb{R}^{n \times d} su rinkinio dydžiu nn ir dd įvesčių, paslėptojo sluoksnio išvestis H∈Rn×h\mathbf{H} \in \mathbb{R}^{n \times h} apskaičiuojama taip:

H=ϕ(XWxh+bh).(9.4.2)\mathbf{H} = \phi(\mathbf{X} \mathbf{W}_{\textrm{xh}} + \mathbf{b}_\textrm{h}). \tag{9.4.2}

(9.4.2) paslėptajam sluoksniui turime svorių parametrą Wxh∈Rd×h\mathbf{W}_{\textrm{xh}} \in \mathbb{R}^{d \times h}, poslinkio parametrą bh∈R1×h\mathbf{b}_\textrm{h} \in \mathbb{R}^{1 \times h} ir paslėptųjų vienetų skaičių hh. Taip pasiruošę, sumuodami taikome transliavimą (žr. 2.1.4 skyrelis). Toliau paslėptojo sluoksnio išvestis H\mathbf{H} naudojama kaip išvesties sluoksnio įvestis, kuri pateikiama taip:

O=HWhq+bq,\mathbf{O} = \mathbf{H} \mathbf{W}_{\textrm{hq}} + \mathbf{b}_\textrm{q},

kur O∈Rn×q\mathbf{O} \in \mathbb{R}^{n \times q} yra išvesties kintamasis, Whq∈Rh×q\mathbf{W}_{\textrm{hq}} \in \mathbb{R}^{h \times q} yra svorių parametras, o bq∈R1×q\mathbf{b}_\textrm{q} \in \mathbb{R}^{1 \times q} yra išvesties sluoksnio poslinkio parametras. Jei tai klasifikavimo uždavinys, galime naudoti softmax(O)\mathrm{softmax}(\mathbf{O}) išvesties kategorijų tikimybių skirstiniui apskaičiuoti.

Tai visiškai analogiška anksčiau 9.1 skyrelis išspręstam regresijos uždaviniui, todėl detalių praleidžiame. Pakanka pasakyti, kad galime atsitiktinai rinktis požymių ir žymenų poras ir išmokti savo tinklo parametrus per automatinį diferencijavimą ir stochastinį gradientinį nusileidimą.

9.4.2 Rekurentiniai neuroniniai tinklai su paslėptosiomis būsenomis

Reikalai visiškai skiriasi, kai turime paslėptąsias būsenas. Pažvelkime į struktūrą šiek tiek išsamiau.

Tarkime, kad turime įvesčių minirinkinį Xt∈Rn×d\mathbf{X}_t \in \mathbb{R}^{n \times d} laiko žingsniu tt. Kitaip tariant, nn sekų pavyzdžių minirinkiniui kiekviena Xt\mathbf{X}_t eilutė atitinka vieną pavyzdį laiko žingsniu tt iš sekos. Toliau pažymėkime Ht∈Rn×h\mathbf{H}_t \in \mathbb{R}^{n \times h} laiko žingsnio tt paslėptojo sluoksnio išvestį. Skirtingai nei su MLP, čia išsaugome ankstesnio laiko žingsnio paslėptojo sluoksnio išvestį Ht−1\mathbf{H}_{t-1} ir įvedame naują svorių parametrą Whh∈Rh×h\mathbf{W}_{\textrm{hh}} \in \mathbb{R}^{h \times h}, aprašantį, kaip naudoti ankstesnio laiko žingsnio paslėptojo sluoksnio išvestį dabartiniame laiko žingsnyje. Konkrečiai, dabartinio laiko žingsnio paslėptojo sluoksnio išvesties skaičiavimą lemia dabartinio laiko žingsnio įvestis kartu su ankstesnio laiko žingsnio paslėptojo sluoksnio išvestimi:

Ht=ϕ(XtWxh+Ht−1Whh+bh).(9.4.3)\mathbf{H}_t = \phi(\mathbf{X}_t \mathbf{W}_{\textrm{xh}} + \mathbf{H}_{t-1} \mathbf{W}_{\textrm{hh}} + \mathbf{b}_\textrm{h}). \tag{9.4.3}

Palyginti su (9.4.2), (9.4.3) prideda dar vieną narį Ht−1Whh\mathbf{H}_{t-1} \mathbf{W}_{\textrm{hh}} ir taip realizuoja (9.4.1). Iš gretimų laiko žingsnių paslėptojo sluoksnio išvesčių Ht\mathbf{H}_t ir Ht−1\mathbf{H}_{t-1} ryšio žinome, kad šie kintamieji užfiksavo ir išlaikė sekos istorinę informaciją iki jų dabartinio laiko žingsnio, lygiai kaip neuroninio tinklo dabartinio laiko žingsnio būsena ar atmintis. Todėl tokia paslėptojo sluoksnio išvestis vadinama paslėptąja būsena. Kadangi paslėptoji būsena dabartiniame laiko žingsnyje naudoja tą patį ankstesnio laiko žingsnio apibrėžimą, (9.4.3) skaičiavimas yra rekurentinis. Todėl, kaip sakėme, neuroniniai tinklai su paslėptosiomis būsenomis, pagrįstais rekurentiniu skaičiavimu, vadinami rekurentiniais neuroniniais tinklais. Sluoksniai, kurie RNN atlieka (9.4.3) skaičiavimą, vadinami rekurentiniais sluoksniais.

Yra daug skirtingų RNN konstravimo būdų. Tie, kurių paslėptoji būsena apibrėžiama (9.4.3), yra labai įprasti. Laiko žingsniui tt išvesties sluoksnio išvestis yra panaši į skaičiavimą MLP:

Ot=HtWhq+bq.\mathbf{O}_t = \mathbf{H}_t \mathbf{W}_{\textrm{hq}} + \mathbf{b}_\textrm{q}.

RNN parametrai apima paslėptojo sluoksnio svorius Wxh∈Rd×h,Whh∈Rh×h\mathbf{W}_{\textrm{xh}} \in \mathbb{R}^{d \times h}, \mathbf{W}_{\textrm{hh}} \in \mathbb{R}^{h \times h} ir poslinkį bh∈R1×h\mathbf{b}_\textrm{h} \in \mathbb{R}^{1 \times h}, kartu su išvesties sluoksnio svoriais Whq∈Rh×q\mathbf{W}_{\textrm{hq}} \in \mathbb{R}^{h \times q} ir poslinkiu bq∈R1×q\mathbf{b}_\textrm{q} \in \mathbb{R}^{1 \times q}. Verta paminėti, kad net skirtingais laiko žingsniais RNN visada naudoja šiuos modelio parametrus. Todėl RNN parametrizavimo kaina nedidėja didėjant laiko žingsnių skaičiui.

9.4.1 pav. iliustruoja RNN skaičiavimo logiką trijuose gretimuose laiko žingsniuose. Bet kuriuo laiko žingsniu tt paslėptosios būsenos skaičiavimą galima traktuoti taip: (i) sujungti dabartinio laiko žingsnio tt įvestį Xt\mathbf{X}_t ir ankstesnio laiko žingsnio t−1t-1 paslėptąją būseną Ht−1\mathbf{H}_{t-1}; (ii) sujungimo rezultatą paduoti į pilnai sujungtą sluoksnį su aktyvacijos funkcija ϕ\phi. Tokio pilnai sujungto sluoksnio išvestis yra dabartinio laiko žingsnio tt paslėptoji būsena Ht\mathbf{H}_t. Šiuo atveju modelio parametrai yra Wxh\mathbf{W}_{\textrm{xh}} ir Whh\mathbf{W}_{\textrm{hh}} sujungimas bei poslinkis bh\mathbf{b}_\textrm{h}, visi iš (9.4.3). Dabartinio laiko žingsnio tt paslėptoji būsena Ht\mathbf{H}_t dalyvaus skaičiuojant kito laiko žingsnio t+1t+1 paslėptąją būseną Ht+1\mathbf{H}_{t+1}. Be to, Ht\mathbf{H}_t taip pat bus paduota į pilnai sujungtą išvesties sluoksnį, kad būtų apskaičiuota dabartinio laiko žingsnio tt išvestis Ot\mathbf{O}_t.

RNN su paslėptąja būsena.

9.4.1 pav. RNN su paslėptąja būsena.

Ką tik paminėjome, kad paslėptosios būsenos skaičiavimas XtWxh+Ht−1Whh\mathbf{X}_t \mathbf{W}_{\textrm{xh}} + \mathbf{H}_{t-1} \mathbf{W}_{\textrm{hh}} yra ekvivalentus Xt\mathbf{X}_t ir Ht−1\mathbf{H}_{t-1} sujungimo ir Wxh\mathbf{W}_{\textrm{xh}} bei Whh\mathbf{W}_{\textrm{hh}} sujungimo matricų daugybai. Nors tai galima įrodyti matematiškai, toliau tiesiog naudojame paprastą kodo fragmentą demonstracijai. Pirmiausia apibrėžiame matricas X, W_xh, H ir W_hh, kurių formos atitinkamai yra (3, 1), (1, 4), (3, 4) ir (4, 4). Padauginę X iš W_xh, o H iš W_hh, ir tada sudėję šias dvi sandaugas, gauname formos (3, 4) matricą.

X, W_xh = d2l.randn(3, 1), d2l.randn(1, 4)
H, W_hh = d2l.randn(3, 4), d2l.randn(4, 4)
d2l.matmul(X, W_xh) + d2l.matmul(H, W_hh)
X, W_xh = d2l.normal((3, 1)), d2l.normal((1, 4))
H, W_hh = d2l.normal((3, 4)), d2l.normal((4, 4))
d2l.matmul(X, W_xh) + d2l.matmul(H, W_hh)
X, W_xh = jax.random.normal(d2l.get_key(), (3, 1)), jax.random.normal(
                                                        d2l.get_key(), (1, 4))
H, W_hh = jax.random.normal(d2l.get_key(), (3, 4)), jax.random.normal(
                                                        d2l.get_key(), (4, 4))
d2l.matmul(X, W_xh) + d2l.matmul(H, W_hh)

Dabar sujungiame matricas X ir H išilgai stulpelių (ašis 1), o matricas W_xh ir W_hh – išilgai eilučių (ašis 0). Šie du sujungimai duoda atitinkamai formos (3, 5) ir (5, 4) matricas. Padauginę šias dvi sujungtas matricas, gauname tą pačią formos (3, 4) išvesties matricą kaip aukščiau.

d2l.matmul(d2l.concat((X, H), 1), d2l.concat((W_xh, W_hh), 0))

9.4.3 RNN pagrįsti simbolių lygio kalbos modeliai

Prisiminkite, kad kalbos modeliavimui 9.3 skyrelis siekiame prognozuoti kitą teksto vienetą pagal dabartinius ir ankstesnius teksto vienetus; todėl originalią seką pastumiame vienu teksto vienetu kaip tikslus (žymenis). (Bengio ir kt., 2003) pirmieji pasiūlė naudoti neuroninį tinklą kalbos modeliavimui. Toliau iliustruojame, kaip RNN galima naudoti kalbos modeliui sukurti. Tegul minirinkinio dydis yra vienas, o teksto seka – „machine“. Kad supaprastintume apmokymą kituose skyreliuose, tekstą skaidome į simbolius, o ne į žodžius, ir nagrinėjame simbolių lygio kalbos modelį. 9.4.2 pav. parodo, kaip prognozuoti kitą simbolį pagal dabartinį ir ankstesnius simbolius per RNN simbolių lygio kalbos modeliavimui.

Simbolių lygio kalbos modelis, pagrįstas RNN. Įvesties ir tikslinė sekos yra atitinkamai „machin“ ir „achine“.

9.4.2 pav. Simbolių lygio kalbos modelis, pagrįstas RNN. Įvesties ir tikslinė sekos yra atitinkamai „machin“ ir „achine“.

Apmokymo proceso metu kiekvienam laiko žingsniui atliekame softmax operaciją su išvesties sluoksnio išvestimi, o tada naudojame kryžminės entropijos nuostolį, kad apskaičiuotume paklaidą tarp modelio išvesties ir tikslo. Dėl rekurentinio paslėptosios būsenos skaičiavimo paslėptajame sluoksnyje 3 laiko žingsnio išvestį O3\mathbf{O}_3 9.4.2 pav. lemia teksto seka „m“, „a“ ir „c“. Kadangi kitas sekos simbolis mokymo duomenyse yra „h“, 3 laiko žingsnio nuostolis priklausys nuo kito simbolio tikimybių skirstinio, sugeneruoto pagal požymių seką „m“, „a“, „c“, ir šio laiko žingsnio tikslo „h“.

Praktikoje kiekvienas teksto vienetas pavaizduojamas dd dimensijų vektoriumi, o naudojame rinkinio dydį n>1n>1. Todėl įvestis Xt\mathbf X_t laiko žingsniu tt bus n×dn\times d matrica, identiška tam, ką aptarėme 9.4.2 skyrelis.

Kituose skyreliuose įgyvendinsime RNN simbolių lygio kalbos modeliams.

9.4.4 Santrauka

Neuroninis tinklas, naudojantis rekurentinį skaičiavimą paslėptosioms būsenoms, vadinamas rekurentiniu neuroniniu tinklu (RNN). RNN paslėptoji būsena gali užfiksuoti sekos istorinę informaciją iki dabartinio laiko žingsnio. Naudojant rekurentinį skaičiavimą, RNN modelio parametrų skaičius nedidėja didėjant laiko žingsnių skaičiui. Taikymų požiūriu RNN galima naudoti simbolių lygio kalbos modeliams kurti.

9.4.5 Pratimai

  1. Jei naudojame RNN kitam teksto sekos simboliui prognozuoti, kokia yra reikalinga bet kurios išvesties dimensija?
  2. Kodėl RNN gali išreikšti teksto vieneto sąlyginę tikimybę tam tikru laiko žingsniu pagal visus ankstesnius teksto sekos teksto vienetus?
  3. Kas nutinka gradientui, jei atgaline kryptimi sklidate per ilgą seką?
  4. Kokios yra kai kurios šiame skyrelyje aprašyto kalbos modelio problemos?

Diskusijos

Diskusijos

Diskusijos

Diskusijos