12.7 Adagrad
Pradėkime nagrinėdami mokymosi uždavinius su požymiais, kurie pasitaiko retai.
12.7.1 Reti požymiai ir mokymosi greičiai
Įsivaizduokite, kad apmokome kalbos modelį. Kad pasiektume gerą tikslumą, paprastai norime mažinti mokymosi greitį tęsiant apmokymą, dažniausiai arba lėtesne sparta. Dabar panagrinėkime modelį, apmokomą su retais požymiais, t. y. požymiais, kurie pasitaiko tik retai. Tai įprasta natūraliajai kalbai, pavyzdžiui, daug mažiau tikėtina, kad pamatysime žodį pradinių sąlygų tikrinimas nei mokymasis. Tačiau tai taip pat įprasta kitose srityse, tokiose kaip skaičiuojamoji reklama ir personalizuotas kolaboratyvusis filtravimas. Juk yra daug dalykų, kurie domina tik nedidelį skaičių žmonių.
Su retais požymiais susiję parametrai gauna prasmingus atnaujinimus tik tada, kai šie požymiai pasitaiko. Esant mažėjančiam mokymosi greičiui, galime atsidurti situacijoje, kai dažnų požymių parametrai gana greitai konverguoja į savo optimalias reikšmes, o retų požymių atveju mums dar trūksta pakankamai dažnų stebėjimų, kad būtų galima nustatyti jų optimalias reikšmes. Kitaip tariant, mokymosi greitis dažniems požymiams mažėja per lėtai arba retiems – per greitai.
Galimas šios problemos taisymo būdas būtų skaičiuoti, kiek kartų matome tam tikrą požymį, ir naudoti tai kaip laikrodį mokymosi greičiams koreguoti. Tai yra, užuot pasirinkę formos mokymosi greitį, galėtume naudoti . Čia skaičiuoja požymio nenulinių reikšmių skaičių, kurį stebėjome iki momento . Tai iš tikrųjų gana lengva įgyvendinti be reikšmingų pridėtinių sąnaudų. Tačiau tai nepasiteisina, kai neturime tikro retumo, o tik duomenis, kuriuose gradientai dažnai labai maži ir tik retai dideli. Juk neaišku, kur brėžti ribą tarp to, kas laikoma stebėtu požymiu, o kas ne.
(Duchi ir kt., 2011) Adagrad tai sprendžia pakeisdamas gana grubų skaitiklį anksčiau stebėtų gradientų kvadratų agregatu. Visų pirma mokymosi greičiui koreguoti jis naudoja . Tai turi du privalumus: pirma, nebereikia nuspręsti, kada gradientas yra pakankamai didelis. Antra, jis automatiškai keičia mastelį pagal gradientų dydį. Koordinatės, kurios įprastai atitinka didelius gradientus, gerokai sumažinamos, o kitos su mažais gradientais sulaukia daug švelnesnio elgesio. Praktikoje tai veda prie labai veiksmingos skaičiuojamosios reklamos ir panašių uždavinių optimizavimo procedūros. Tačiau tai paslepia kai kuriuos papildomus Adagrad privalumus, kuriuos geriausia suprasti pradinių sąlygų tikrinimo kontekste.
12.7.2 Pradinių sąlygų tikrinimas
Iškilieji optimizavimo uždaviniai tinka algoritmų savybėms analizuoti. Juk daugumai neiškiliųjų uždavinių sunku išvesti prasmingas teorines garantijas, tačiau intuicija ir įžvalgos dažnai išlieka. Panagrinėkime uždavinį minimizuoti .
Kaip matėme 12.6 skyrelis, šį uždavinį galima perrašyti per jo tikrinį skaidinį ir gauti daug paprastesnį uždavinį, kuriame kiekvieną koordinatę galima spręsti atskirai:
Čia naudojome , taigi ir . Modifikuoto uždavinio minimizuotojas yra , o minimali reikšmė . Tai daug lengviau apskaičiuoti, nes yra įstrižaininė matrica, kurioje yra tikrinės reikšmės.
Jei truputį sutrikdytume, tikėtume, kad minimizuotojas pasikeis tik nežymiai. Deja, taip nėra. Nors nežymūs pokyčiai lemia tokius pat nežymius pokyčius, to negalima pasakyti apie (ir atitinkamai ) minimizuotoją. Kai tikrinės reikšmės didelės, matysime tik mažus ir minimumo pokyčius. Ir atvirkščiai, esant mažoms , pokyčiai gali būti dramatiški. Didžiausios ir mažiausios tikrinės reikšmės santykis vadinamas optimizavimo uždavinio sąlygotumo skaičiumi.
Jei sąlygotumo skaičius didelis, optimizavimo uždavinį sunku tiksliai išspręsti. Turime pasirūpinti, kad teisingai gautume didelį reikšmių dinaminį diapazoną. Mūsų analizė veda į akivaizdų, nors ir kiek naivų klausimą: ar negalėtume tiesiog „ištaisyti“ problemos iškreipdami erdvę taip, kad visos tikrinės reikšmės būtų ? Teoriškai tai gana lengva: reikia tik tikrinių reikšmių ir vektorių, kad uždavinį perskaičiuotume iš į uždavinį su . Naujoje koordinačių sistemoje galima supaprastinti iki . Deja, tai gana nepraktiškas pasiūlymas. Tikrinių reikšmių ir vektorių skaičiavimas apskritai yra daug brangesnis nei paties uždavinio sprendimas.
Nors tikslus tikrinių reikšmių skaičiavimas gali būti brangus, jų spėjimas ir apskaičiavimas bent apytiksliai gali būti daug geriau nei visiškai nieko nedaryti. Visų pirma galėtume naudoti įstrižainės elementus ir atitinkamai pakeisti mastelį. Tai daug pigiau nei tikrinių reikšmių skaičiavimas.
Šiuo atveju turime ir konkrečiai visiems . Daugeliu atvejų tai gerokai supaprastina sąlygotumo skaičių. Pavyzdžiui, anksčiau aptartais atvejais tai visiškai pašalintų nagrinėjamą problemą, nes uždavinys yra lygiagretus ašims.
Deja, susiduriame su dar viena problema: giliajame mokymesi paprastai net neturime prieigos prie tikslo funkcijos antrosios išvestinės: kai , antrajai išvestinei net minirinkinyje apskaičiuoti gali prireikti atminties ir darbo, todėl praktiškai tai neįmanoma. Išradinga Adagrad idėja yra naudoti šios sunkiai pasiekiamos Hesės matricos įstrižainės pakaitalą, kurį palyginti pigu apskaičiuoti ir kuris yra veiksmingas – pačio gradiento dydį.
Kad suprastume, kodėl tai veikia, pažvelkime į . Turime, kad
kur yra minimizuotojas. Taigi gradiento dydis priklauso ir nuo , ir nuo atstumo iki optimumo. Jei nesikeistų, to užtektų. Juk tokiu atveju gradiento dydžio pakanka. Kadangi AdaGrad yra stochastinio gradientinio nusileidimo algoritmas, matysime nenulinės dispersijos gradientus net optimume. Todėl galime saugiai naudoti gradientų dispersiją kaip pigų Hesės matricos mastelio pakaitalą. Išsami analizė peržengia šio skyrelio ribas (tai užimtų kelis puslapius). Išsamiau skaitytojus nukreipiame į (Duchi ir kt., 2011).
12.7.3 Algoritmas
Formalizuokime aukščiau pateiktą diskusiją. Kintamąjį naudojame praeities gradientų dispersijai kaupti taip.
Čia operacijos taikomos kiekvienai koordinatei atskirai. Tai yra, turi elementus . Panašiai turi elementus , o turi elementus . Kaip ir anksčiau, yra mokymosi greitis, o yra adityvinė konstanta, užtikrinanti, kad nedalytume iš . Galiausiai inicializuojame .
Kaip ir momento metodo atveju, turime sekti pagalbinį kintamąjį, šiuo atveju, kad kiekvienai koordinatei būtų galima turėti atskirą mokymosi greitį. Tai reikšmingai nepadidina Adagrad kainos, palyginti su SGD, nes pagrindinės sąnaudos paprastai yra skaičiuoti ir jo išvestinę.
Atkreipkite dėmesį, kad kaupiant gradientų kvadratus reiškia, kad auga iš esmės tiesiškai (praktikoje šiek tiek lėčiau nei tiesiškai, nes gradientai pradžioje mažėja). Tai lemia mokymosi greitį, nors ir koreguojamą kiekvienai koordinatei atskirai. Iškiliesiems uždaviniams tai visiškai tinka. Tačiau giliajame mokymesi galbūt norėtume mokymosi greitį mažinti gerokai lėčiau. Tai paskatino sukurti nemažai Adagrad variantų, kuriuos aptarsime vėlesniuose skyreliuose. Kol kas pažiūrėkime, kaip jis elgiasi kvadratiniame iškiliajame uždavinyje. Naudojame tą patį uždavinį kaip anksčiau:
Adagrad įgyvendinsime naudodami tą patį mokymosi greitį kaip anksčiau, t. y. . Kaip matome, nepriklausomo kintamojo iteracinė trajektorija yra glotnesnė. Tačiau dėl kaupiamojo poveikio mokymosi greitis nuolat mažėja, todėl nepriklausomas kintamasis vėlesniuose iteracijų etapuose juda nebe taip daug.
%matplotlib inline
from d2l import mxnet as d2l
import math
from mxnet import np, npx
npx.set_np()
%matplotlib inline
from d2l import torch as d2l
import math
import torch
%matplotlib inline
from d2l import tensorflow as d2l
import math
import tensorflow as tf
def adagrad_2d(x1, x2, s1, s2):
eps = 1e-6
g1, g2 = 0.2 * x1, 4 * x2
s1 += g1 ** 2
s2 += g2 ** 2
x1 -= eta / math.sqrt(s1 + eps) * g1
x2 -= eta / math.sqrt(s2 + eps) * g2
return x1, x2, s1, s2
def f_2d(x1, x2):
return 0.1 * x1 ** 2 + 2 * x2 ** 2
eta = 0.4
d2l.show_trace_2d(f_2d, d2l.train_2d(adagrad_2d))
Padidinus mokymosi greitį iki , matome daug geresnį elgesį. Tai jau rodo, kad mokymosi greičio mažėjimas gali būti gana agresyvus net be triukšmo atveju, todėl turime užtikrinti, kad parametrai tinkamai konverguotų.
eta = 2
d2l.show_trace_2d(f_2d, d2l.train_2d(adagrad_2d))
12.7.4 Įgyvendinimas nuo nulio
Kaip ir momentų metodas, Adagrad turi išlaikyti būsenos kintamąjį tokios pat formos kaip parametrai.
def init_adagrad_states(feature_dim):
s_w = d2l.zeros((feature_dim, 1))
s_b = d2l.zeros(1)
return (s_w, s_b)
def adagrad(params, states, hyperparams):
eps = 1e-6
for p, s in zip(params, states):
s[:] += np.square(p.grad)
p[:] -= hyperparams['lr'] * p.grad / np.sqrt(s + eps)
def init_adagrad_states(feature_dim):
s_w = d2l.zeros((feature_dim, 1))
s_b = d2l.zeros(1)
return (s_w, s_b)
def adagrad(params, states, hyperparams):
eps = 1e-6
for p, s in zip(params, states):
with torch.no_grad():
s[:] += torch.square(p.grad)
p[:] -= hyperparams['lr'] * p.grad / torch.sqrt(s + eps)
p.grad.data.zero_()
def init_adagrad_states(feature_dim):
s_w = tf.Variable(d2l.zeros((feature_dim, 1)))
s_b = tf.Variable(d2l.zeros(1))
return (s_w, s_b)
def adagrad(params, grads, states, hyperparams):
eps = 1e-6
for p, s, g in zip(params, states, grads):
s[:].assign(s + tf.math.square(g))
p[:].assign(p - hyperparams['lr'] * g / tf.math.sqrt(s + eps))
Palyginti su eksperimentu 12.5 skyrelis, modeliui apmokyti naudojame didesnį mokymosi greitį.
data_iter, feature_dim = d2l.get_data_ch11(batch_size=10)
d2l.train_ch11(adagrad, init_adagrad_states(feature_dim),
{'lr': 0.1}, data_iter, feature_dim);
12.7.5 Glaustas įgyvendinimas
Naudodami algoritmo adagrad egzempliorių Trainer, galime iškviesti Adagrad algoritmą Gluon.
d2l.train_concise_ch11('adagrad', {'learning_rate': 0.1}, data_iter)
trainer = torch.optim.Adagrad
d2l.train_concise_ch11(trainer, {'lr': 0.1}, data_iter)
trainer = tf.keras.optimizers.Adagrad
d2l.train_concise_ch11(trainer, {'learning_rate' : 0.1}, data_iter)
12.7.6 Santrauka
- Adagrad dinamiškai mažina mokymosi greitį kiekvienai koordinatei atskirai.
- Jis naudoja gradiento dydį kaip priemonę koreguoti, kaip greitai pasiekiama pažanga: koordinatės su dideliais gradientais kompensuojamos mažesniu mokymosi greičiu.
- Tikslios antrosios išvestinės skaičiavimas giliojo mokymosi uždaviniuose paprastai neįmanomas dėl atminties ir skaičiavimo apribojimų. Gradientas gali būti naudingas pakaitalas.
- Jei optimizavimo uždavinys turi gana netolygią struktūrą, Adagrad gali padėti sušvelninti iškraipymą.
- Adagrad ypač veiksmingas retiems požymiams, kai retai pasitaikantiems nariams mokymosi greitį reikia mažinti lėčiau.
- Giliojo mokymosi uždaviniuose Adagrad kartais gali būti pernelyg agresyvus mažindamas mokymosi greitį. Strategijas tam sušvelninti aptarsime 12.10 skyrelis kontekste.
12.7.7 Pratimai
- Įrodykite, kad ortogonaliajai matricai ir vektoriui galioja: . Kodėl tai reiškia, kad sutrikdymų dydis nepasikeičia po ortogonaliojo kintamųjų keitimo?
- Išbandykite Adagrad ir taip pat tikslo funkcijai, pasuktai 45 laipsniais, t. y. . Ar jis elgiasi kitaip?
- Įrodykite Geršgorino apskritimų teoremą, kuri teigia, kad matricos tikrinės reikšmės tenkina bent vienam pasirinkimui.
- Ką Geršgorino teorema mums sako apie įstrižaininiu būdu pradinių sąlygų tikrinimo atžvilgiu pakoreguotos matricos tikrines reikšmes?
- Išbandykite Adagrad tinkamam giliajam tinklui, pavyzdžiui, 7.6 skyrelis taikomam Fashion-MNIST.
- Kaip reikėtų modifikuoti Adagrad, kad mokymosi greičio mažėjimas būtų ne toks agresyvus?
