Kako funkcionira povratno razmnožavanje i kako pomoću Pythona možete graditi neuronsku mrežu

Neuronske mreže mogu biti zastrašujuće, posebno za ljude koji su novi u strojnom učenju. Međutim, ovaj vodič će razložiti kako točno funkcionira neuronska mreža i do kraja ćete imati radnu fleksibilnu neuronsku mrežu. Započnimo!

Razumijevanje procesa

S približno 100 milijardi neurona, ljudski mozak obrađuje podatke brzinom od 268 mph! U osnovi, neuronska mreža je skup neurona povezanih sinapsama .

Ova je kolekcija organizirana u tri glavna sloja: ulazni kasnije, skriveni sloj i izlazni sloj.

Možete imati mnogo skrivenih slojeva, što je mjesto gdje pojam dubokog učenja ulazi u igru. U umjetnoj neuronskoj mreži postoji nekoliko ulaza, koji se nazivaju značajkama , a koji proizvode barem jedan izlaz - koji se naziva oznaka .

Na gornjem crtežu krugovi predstavljaju neurone, dok linije predstavljaju sinapse.

Uloga sinapse je da uzima i umnožava ulaze i težine .

O težinama možete razmišljati kao o “snazi” veze između neurona. Ponderi prvenstveno definiraju izlaz neuronske mreže. Međutim, vrlo su fleksibilni. Nakon toga se primjenjuje funkcija aktiviranja za vraćanje izlaza.

Evo kratkog pregleda kako funkcionira jednostavna povratna neuronska mreža:

  1. Uzmi ulaze kao matricu (2D niz brojeva)
  2. Pomnožite ulaze sa skupom pondera (to se radi množenjem matrice, aka uzimajući 'točkasti proizvod')
  3. Primijenite funkciju aktiviranja
  4. Vrati izlaz
  5. Pogreška se izračunava uzimajući razliku između željenog rezultata iz modela i predviđenog rezultata. Ovo je postupak koji se naziva gradijentno spuštanje i koji možemo koristiti za izmjenu težina.
  6. Ponderi se zatim prilagođavaju, prema pogrešci pronađenoj u koraku 5.
  7. Za treniranje se ovaj postupak ponavlja više od 1000 puta. Što se više podataka obučava, to će naši rezultati biti točniji.

U svojoj su srži neuronske mreže jednostavne.

Oni samo izvode umnožavanje matrice s ulazom i težinama i primjenjuju funkciju aktiviranja.

Kada se težine prilagode pomoću funkcije gradijenta gubitka, mreža se prilagođava promjenama kako bi proizvela preciznije rezultate.

Naša će neuronska mreža modelirati jedan skriveni sloj s tri ulaza i jednim izlazom. U mreži ćemo predviđati rezultat našeg ispita na temelju podataka o tome koliko smo sati učili i koliko sati spavali dan ranije. Rezultat je 'test rezultat'.

Evo naših primjera podataka o onome na čemu ćemo trenirati našu neuronsku mrežu:

Kao što ste mogli primijetiti, ?u ovom slučaju predstavlja ono što želimo da naša neuronska mreža predvidi. U ovom slučaju predviđamo testnu ocjenu nekoga tko je učio četiri sata i spavao osam sati na temelju prethodnih rezultata.

Prosljeđivanje

Počnimo kodirati ovog lošeg dječaka! Otvorite novu datoteku python. Morat ćete uvesti numpyjer će nam pomoći u određenim izračunima.

Prvo, uvezimo svoje podatke kao numpy nizove pomoću np.array. Također ćemo htjeti normalizirati naše jedinice jer su naši unosi u satima, ali naš je rezultat test rezultat od 0-100. Stoga svoje podatke moramo prilagoditi dijeljenjem s maksimalnom vrijednošću za svaku varijablu.

Dalje, definirajmo python classi napišimo initfunkciju u kojoj ćemo odrediti naše parametre kao što su ulazni, skriveni i izlazni slojevi.

Vrijeme je za naš prvi izračun. Imajte na umu da naše sinapse izvode točkice ili matrično množenje ulaznih podataka i težine. Imajte na umu da se ponderi generiraju nasumično i između 0 i 1.

Izračuni iza naše mreže

U skupu podataka, naši ulazni podaci X, predstavljaju matricu 3x2. Naši izlazni podaci y, je matrica 3x1. Svaki element u matrici Xtreba pomnožiti s odgovarajućom težinom, a zatim dodati zajedno sa svim ostalim rezultatima za svaki neuron u skrivenom sloju. Evo kako bi prvi element ulaznih podataka (2 sata učenja i 9 sati spavanja) izračunao izlaz u mreži:

Ova slika razlaže ono što naša neuronska mreža zapravo čini da bi proizvela izlaz. Prvo se proizvodi slučajno generiranih utega (.2, .6, .1, .8, .3, .7) na svakoj sinapsi i pripadajući ulazi zbrajaju da bi se dobili kao prve vrijednosti skrivenog sloja. Te su sume manjim fontom jer nisu konačne vrijednosti za skriveni sloj.

Da bismo dobili konačnu vrijednost za skriveni sloj, moramo primijeniti funkciju aktiviranja.

Uloga aktivacijske funkcije je uvođenje nelinearnosti. Prednost toga je što se izlaz mapira iz raspona 0 i 1, što olakšava promjenu pondera u budućnosti.

Postoji mnogo funkcija aktivacije za mnoge različite slučajeve uporabe. U ovom ćemo se primjeru držati jedne od popularnijih - sigmoidne funkcije.

Sada za izračun vrijednosti izlaznog sloja trebamo ponovno koristiti množenje matrice, s drugim skupom slučajnih ponderiranja.

Na kraju, da bismo normalizirali izlaz, samo ponovno primjenjujemo funkciju aktiviranja.

I, eto ti! Teoretski, s tim ponderima, vanjska će se neuronska mreža izračunati .85kao rezultat testa! Međutim, naša meta je bila .92. Naš rezultat nije bio loš, jednostavno nije najbolji koji može biti. Upravo smo imali malo sreće kad sam za ovaj primjer odabrao slučajne utege.

Kako treniramo svoj model za učenje? Pa, saznat ćemo vrlo brzo. Za sada, nastavimo s kodiranjem naše mreže.

Ako ste i dalje zbunjeni, toplo preporučujem da pogledate ovaj informativni video koji na istom primjeru objašnjava strukturu neuronske mreže.

Provođenje proračuna

Sada, generirajmo svoje utege nasumično koristeći np.random.randn(). Zapamtite, trebat će nam dva kompleta utega. Jedan za prelazak iz ulaznog u skriveni sloj, a drugi za prelazak iz skrivenog u izlazni sloj.

Jednom kada postavimo sve varijable, spremni smo napisati našu forwardfunkciju širenja. Proslijedimo svoj ulaz, Xi u ovom primjeru varijablu možemo koristiti zza simulaciju aktivnosti između ulaznog i izlaznog sloja.

Kao što je objašnjeno, moramo uzeti točkasti umnožak ulaza i težina, primijeniti funkciju aktiviranja, uzeti još jedan točkasti proizvod skrivenog sloja i drugog skupa težina i na kraju primijeniti konačnu funkciju aktivacije da bismo dobili naš izlaz:

Na kraju, moramo definirati našu sigmoidnu funkciju:

I, eto ga! (Neobučena) neuronska mreža sposobna proizvesti izlaz.

Kao što ste možda primijetili, moramo osposobiti našu mrežu za izračunavanje preciznijih rezultata.

Povratno razmnožavanje - „učenje“ naše mreže

Budući da imamo slučajni skup pondera, moramo ih izmijeniti kako bi naši ulazi bili jednaki odgovarajućim izlazima iz našeg skupa podataka. To se postiže metodom koja se naziva povratno razmnožavanje.

Povratno razmnožavanje djeluje tako da se pomoću funkcije gubitka izračuna koliko je mreža udaljena od ciljanog izlaza.

Pogreška izračuna

Jedan od načina predstavljanja funkcije gubitka je pomoću funkcije srednje vrijednosti kvadrata gubitka :

U ovoj je funkciji onaš predviđeni izlaz i ystvarni rezultat. Sad kad imamo funkciju gubitka, cilj nam je približiti je što bliže 0. To znači da trebamo imati gotovo nikakav gubitak. Dok treniramo svoju mrežu, sve što radimo je minimaliziranje gubitaka.

Da bismo shvatili u kojem ćemo smjeru mijenjati utege, moramo pronaći brzinu promjene našeg gubitka s obzirom na naše težine. Drugim riječima, trebamo upotrijebiti izvod funkcije gubitka da bismo razumjeli kako utezi utječu na ulaz.

U ovom ćemo slučaju koristiti djelomičnu izvedenicu koja će nam omogućiti da uzmemo u obzir drugu varijablu.

Ova metoda je poznata kao gradijentni spust . Znajući na koji način promijeniti našu težinu, naši rezultati mogu biti samo precizniji.

Evo kako ćemo izračunati inkrementalnu promjenu naših težina:

  1. Pronađite granicu pogreške izlaznog sloja (o) uzimajući razliku predviđenog izlaza i stvarnog izlaza (y)
  2. Primijenite izvedenicu naše funkcije aktiviranja sigmoida na pogrešku izlaznog sloja. Taj rezultat nazivamo delta izlaznim zbrojem .
  3. Koristite delta izlazni zbroj pogreške izlaznog sloja da biste shvatili koliko je naš z² (skriveni) sloj pridonio izlaznoj pogrešci izvođenjem točkanog proizvoda s našom drugom matricom težine. To možemo nazvati pogreškom z².
  4. Izračunajte zbroj delta izlaza za z² sloj primjenom izvedenice naše sigmoidne funkcije aktiviranja (baš kao korak 2).
  5. Prilagodite težine za prvi sloj izvođenjem točkanog umnoška ulaznog sloja sa skrivenom () delta izlaznom svotom . Za drugu težinu izvedite umnožak skrivenog (z²) sloja i izlaznu (o) delta izlaznu sumu .

Izračun zbroja delta izlaza, a zatim primjena izvoda sigmoidne funkcije vrlo su važni za povratno razmnožavanje. Derivat sigmoida, poznat i kao sigmoidni prosti broj , dat će nam brzinu promjene ili nagib aktivacijske funkcije na izlaznom zbroju.

Nastavimo kodirati našu Neural_Networkklasu dodavanjem funkcije sigmoidPrime (derivat sigmoid):

Zatim ćemo htjeti stvoriti našu backwardfunkciju širenja koja radi sve navedeno u četiri gornja koraka:

Sada možemo definirati svoj izlaz pokretanjem širenja prema naprijed i pokrenuti funkciju unatrag tako što ćemo je pozvati u trainfunkciji:

Da bismo pokrenuli mrežu, sve što moramo učiniti je pokrenuti trainfunkciju. Naravno, željet ćemo to učiniti više puta, ili možda tisuće puta. Dakle, poslužit ćemo se forpetljom.

Evo punih 60 linija nevjerojatnosti:

Eto ti! Punopravna neuronska mreža koja može učiti na ulazima i izlazima.

Iako smo o svojim ulazima razmišljali kao o satima učenja i spavanja, a kao izlazne rezultate, slobodno ih promijenite u bilo što što želite i promatrajte kako se mreža prilagođava!

Napokon, sve što mreža vidi su brojevi. Izračuni koje smo napravili, koliko god izgledali složeni, svi su imali veliku ulogu u našem modelu učenja.

Ako želite predvidjeti izlaz na temelju naših uvježbanih podataka, poput predviđanja rezultata testa ako ste učili četiri sata i spavali osam, ovdje pogledajte cijeli tutorial.

Demo i izvor

Reference

Steven Miller

Welch laboratoriji

Kabir šah

Ovaj je priručnik izvorno objavljen na Enlightu, web mjestu na kojem se održavaju razni vodiči i projekti za učenje putem gradnje! Pogledajte još projekata poput ovih :)