Kako podesiti pametne telefone i računare. Informativni portal
  • Dom
  • Windows 7, XP
  • Primjer neuronske mreže u Python kodu. Učenje neuronskih mreža u četiri koraka

Primjer neuronske mreže u Python kodu. Učenje neuronskih mreža u četiri koraka

  • Programiranje
    • Prevod

    O čemu je članak?

    Lično, najbolje učim s malim radnim kodom s kojim se mogu igrati. U ovom tutorijalu naučit ćemo algoritam povratnog širenja koristeći malu neuronsku mrežu implementiranu u Python kao primjer.

    Daj mi kod!

    X = np.array([ ,,, ]) y = np.array([]).T syn0 = 2*np.random.random((3,4)) - 1 syn1 = 2*np.random.random ((4,1)) - 1 za j u x opsegu (60000): l1 = 1/(1+np.exp(-(np.dot(X,syn0)))) l2 = 1/(1+np. exp(-(np.dot(l1,syn1)))) l2_delta = (y - l2)*(l2*(1-l2)) l1_delta = l2_delta.dot(syn1.T) * (l1 * (1-l1) )) syn1 += l1.T.dot(l2_delta) syn0 += X.T.dot(l1_delta)

    Previše komprimovano? Hajde da ga podelimo na jednostavnije delove.

    Dio 1: Mala igračka neuronska mreža

    Neuronska mreža obučena kroz propagaciju unazad pokušava da koristi ulazne podatke za predviđanje izlaznih podataka.

    Recimo da trebamo predvidjeti kako će izlazna kolona izgledati na osnovu ulaznih podataka. Ovaj problem bi se mogao riješiti izračunavanjem statističke korespondencije između njih. I vidjeli bismo da je lijeva kolona 100% u korelaciji sa izlazom.

    Propagacija unazad, u svom najjednostavnijem slučaju, izračunava slične statistike za kreiranje modela. Pokusajmo.

    Neuronska mreža u dva sloja

    import numpy kao np # Sigmoid def nonlin(x,deriv=False): if(deriv==True): vrati f(x)*(1-f(x)) return 1/(1+np.exp(-x) )) # ulazni skup podataka X = np.array([ , , , ]) # izlazni podaci y = np.array([]).T # čini slučajne brojeve konkretnijim np.random.seed(1) # inicijalizira težine na slučajni način sa srednjom 0 syn0 = 2*np.random.random((3,1)) - 1 za iter u xrange(10000): # širenje naprijed l0 = X l1 = nonlin(np.dot(l0,syn0) )) # Koliko smo pogriješili? l1_error = y - l1 # pomnožite ovo sa nagibom sigmoida # na osnovu vrijednosti u l1 l1_delta = l1_error * nonlin(l1,True) # !!! # ažuriranje težine syn0 += np.dot(l0.T,l1_delta) # !!! print "Izlaz nakon treninga:" print l1

    Rezultat nakon treninga: [[ 0,00966449] [ 0,00786506] [ 0,99358898] [ 0,99211957]]

    Varijable i njihovi opisi.






    "*" - množenje po elementima - dva vektora iste veličine množe odgovarajuće vrijednosti, a izlaz je vektor iste veličine
    "-" – oduzimanje vektora po elementima
    x.dot(y) – ako su x i y vektori, onda će izlaz biti skalarni proizvod. Ako su to matrice, onda je rezultat množenje matrice. Ako je matrica samo jedna od njih, to je množenje vektora i matrice.

    • uporedi l1 nakon prve i nakon posljednje iteracije
    • pogledajte nelinsku funkciju.
    • pogledajte kako se mijenja l1_error
    • 36. red parse - glavni tajni sastojci se skupljaju ovdje (označeno!!!)
    • 39. red raščlanjivanja - cijela mreža se priprema upravo za ovu operaciju (označeno!!!)

    Hajde da raščlanimo kod red po red

    import numpy kao np

    Uvozi numpy, biblioteku linearne algebre. Naša jedina zavisnost.

    Def nonlin(x,deriv=False):

    Naša nelinearnost. Ova posebna funkcija stvara “sigmoid”. Usklađuje bilo koji broj sa vrijednošću od 0 do 1 i pretvara brojeve u vjerovatnoće, a također ima nekoliko drugih svojstava korisnih za obuku neuronskih mreža.

    If(deriv==Tačno):

    Ova funkcija također može proizvesti derivat sigmoida (deriv=True). Ovo je jedan od njenih korisna svojstva. Ako je izlaz funkcije izlazna varijabla, onda će derivat biti out * (1-out). Efektivno.

    X = np.array([ , …

    Inicijalizacija niza ulaznih podataka kao numpy matrice. Svaka linija je primjer treninga. Kolone su ulazni čvorovi. Na kraju imamo 3 ulazna čvora u mreži i 4 primjera obuke.

    Y = np.niz([]).T

    Inicijalizira izlazne podatke. ".T" – prijenosna funkcija. Nakon prevođenja, y matrica ima 4 reda sa jednom kolonom. Kao i kod ulaznih podataka, svaki red je primjer treninga, a svaka kolona (jedna u našem slučaju) je izlazni čvor. Ispostavilo se da mreža ima 3 ulaza i 1 izlaz.

    Np.random.seed(1)

    Time slučajna distribucija biće isti svaki put. To će nam omogućiti da lakše nadgledamo mrežu nakon što unesemo promjene u kod.

    Syn0 = 2*np.random.random((3,1)) – 1

    Mrežna matrica težine. syn0 znači "sinapsa nula". Pošto imamo samo dva sloja, ulaz i izlaz, potrebna nam je jedna matrica težine koja će ih povezati. Njegova dimenzija je (3, 1), pošto imamo 3 ulaza i 1 izlaz. Drugim riječima, l0 ima veličinu 3, a l1 ima veličinu 1. Pošto povezujemo sve čvorove u l0 sa svim čvorovima u l1, potrebna nam je matrica dimenzija (3, 1).

    Imajte na umu da se inicijalizira nasumično i da je srednja vrijednost nula. Iza ovoga stoji prilično složena teorija. Za sada ćemo ovo shvatiti samo kao preporuku. Također imajte na umu da je naša neuronska mreža upravo ova matrica. Imamo "slojeve" l0 i l1, ali to su privremene vrijednosti zasnovane na skupu podataka. Ne skladištimo ih. Sav trening je pohranjen u syn0.

    Za iter u xrange(10000):

    Ovdje počinje glavni mrežni kod za obuku. Kodna petlja se ponavlja mnogo puta i optimizuje mrežu za skup podataka.

    Prvi sloj, l0, su samo podaci. X sadrži 4 primjera obuke. Obradit ćemo ih sve odjednom - to se zove grupni trening. Ukupno imamo 4 različite l0 linije, ali ih možemo smatrati jednim primjerom obuke - u ovoj fazi nije bitno (možete učitati 1000 ili 10000 njih bez ikakvih promjena u kodu).

    L1 = nonlin(np.dot(l0,syn0))

    Ovo je korak predviđanja. Pustili smo da mreža pokuša da predvidi izlaz na osnovu ulaza. Onda ćemo vidjeti kako će ona to učiniti kako bismo to mogli poboljšati.

    Postoje dva koraka po redu. Prvi radi množenje matrice l0 i syn0. Drugi propušta izlaz kroz sigmoid. Njihove dimenzije su sljedeće:

    (4 x 3) tačka (3 x 1) = (4 x 1)

    Množenje matrice zahtijeva da dimenzije budu iste u sredini jednačine. Konačna matrica ima isti broj redova kao prva i isti broj stupaca kao i druga.

    Učitali smo 4 primjera obuke i dobili 4 nagađanja (4x1 matrica). Svaki izlaz odgovara pretpostavci mreže za dati ulaz.

    L1_greška = y - l1

    Pošto l1 sadrži nagađanja, možemo uporediti njihovu razliku sa stvarnošću oduzimanjem l1 od tačnog odgovora y. l1_error je vektor pozitivnih i negativnih brojeva koji karakteriziraju „promašaj“ mreže.

    A evo i tajnog sastojka. Ovaj red treba raščlaniti dio po dio.

    Prvi dio: derivat

    Nelinijski (l1, Tačno)

    L1 predstavlja ove tri tačke, a kod proizvodi nagib linija prikazanih ispod. Imajte na umu da kada velike vrijednosti kao x=2.0 ( zelena tačka) i vrlo male, poput x=-1.0 (ljubičaste) linije imaju blagi nagib. Najveći ugao u tački x=0 (plavo). Ovo čini veliku razliku. Također imajte na umu da se svi derivati ​​kreću od 0 do 1.

    Pun izraz: izvod ponderisan greškom

    L1_delta = l1_error * nonlin(l1,True)

    Matematički, postoje preciznije metode, ali u našem slučaju je i ova prikladna. l1_error je (4,1) matrica. nonlin(l1,True) vraća (4,1) matricu. Ovdje ih množimo element po element, a na izlazu dobijamo i matricu (4,1), l1_delta.

    Množenjem izvedenica greškama, smanjujemo greške u predviđanjima napravljenim s visokim povjerenjem. Ako je nagib linije bio mali, tada je mreža sadržavala ili vrlo veliku ili vrlo malu vrijednost. Ako je pretpostavka mreže blizu nuli (x=0, y=0,5), onda nije naročito sigurna. Ažuriramo ova neizvjesna predviđanja i ostavljamo predviđanja s visokom pouzdanošću množeći ih vrijednostima blizu nule.

    Syn0 += np.dot(l0.T,l1_delta)

    Spremni smo za ažuriranje mreže. Pogledajmo jedan primjer obuke. U njemu ćemo ažurirati težine. Ažurirajte najlijevu težinu (9.5)

    Weight_update = input_value * l1_delta

    Za najlijevu težinu to bi bilo 1,0 * l1_delta. Vjerovatno će ovo samo malo povećati 9,5. Zašto? Jer predviđanje je već bilo prilično pouzdano, a predviđanja su bila praktično tačna. Mala greška i blagi nagib linije znači vrlo malo ažuriranje.

    Ali pošto radimo grupni trening, ponavljamo gornji korak za sva četiri primjera treninga. Tako da izgleda vrlo slično gornjoj slici. Dakle, šta radi naša linija? Broji ažurirane težine za svaku težinu, za svaki primjer treninga, sumira ih i ažurira sve težine - sve u jednom redu.

    Nakon promatranja ažuriranja mreže, vratimo se našim podacima o treningu. Kada su i ulaz i izlaz jednaki 1, povećavamo težinu između njih. Kada je ulaz 1, a izlaz 0, smanjujemo težinu.

    Ulaz Izlaz 0 0 1 0 1 1 1 1 1 0 1 1 0 1 1 0

    Dakle, u našoj četvorci primjeri obuke ispod, težina prvog ulaza u odnosu na izlaz će se ili povećati ili ostati konstantna, a druge dvije težine će se povećavati i smanjivati ​​ovisno o primjerima. Ovaj efekat doprinosi učenju mreže zasnovanom na korelaciji ulaznih i izlaznih podataka.

    2. dio: teži zadatak

    Ulaz Izlaz 0 0 1 0 0 1 1 1 1 0 1 1 1 1 1 0

    Pokušajmo predvidjeti izlazne podatke na osnovu tri kolone ulaznih podataka. Nijedan od ulaznih stupaca nije u 100% korelaciji sa izlazom. Treći stupac nije povezan ni sa čim, jer sadrži jedinice cijelim putem. Međutim, ovdje možete vidjeti obrazac - ako jedan od prva dva stupca (ali ne oba odjednom) sadrži 1, tada će i rezultat biti jednak 1.

    Ovo je nelinearan dizajn jer ne postoji direktna korespondencija jedan-na-jedan između stupaca. Podudaranje se zasniva na kombinaciji unosa, kolone 1 i 2.

    Zanimljivo je da je prepoznavanje uzoraka vrlo sličan zadatak. Ako imate 100 slika bicikala i cijevi iste veličine, prisustvo određenih piksela na određenim mjestima nije u direktnoj korelaciji sa prisustvom bicikla ili cijevi na slici. Statistički, njihova boja može izgledati nasumično. Ali neke kombinacije piksela nisu slučajne – one koje formiraju sliku bicikla (ili cijevi).


    Strategija

    Da biste kombinirali piksele u nešto što može imati korespondenciju jedan-na-jedan na izlazu, trebate dodati još jedan sloj. Prvi sloj kombinuje ulaz, drugi dodeljuje podudaranje izlazu koristeći izlaz prvog sloja kao ulaz. Obratite pažnju na tabelu.

    Ulaz (l0) Skrivene težine(l1) Izlaz (l2) 0 0 1 0,1 0,2 0,5 0,2 0 0 1 1 0,2 0,6 0,7 0,1 1 1 0 1 0,3 0,2 0,3 0,9 1 1 1 1 0,2 3 0,1 .

    Slučajno Dodeljivanjem težina, dobićemo skrivene vrednosti za sloj br. 1. Zanimljivo je da je druga kolona skrivene težine već postoji mala korelacija sa izlazom. Nije idealno, ali postoji. I ovo je također važan dio procesa mrežne obuke. Trening će samo ojačati ovu korelaciju. Ažuriraće syn1 kako bi dodijelio svoje mapiranje izlaznim podacima i syn0 da bi bolje dobio ulazne podatke.

    Neuronska mreža u tri sloja

    import numpy kao np def nonlin(x,deriv=False): if(deriv==True): vrati f(x)*(1-f(x)) return 1/(1+np.exp(-x)) X = np.array([, , , ]) y = np.array([, , , ]) np.random.seed(1) # nasumično inicijalizira težine, u prosjeku - 0 syn0 = 2*np.random. random ((3,4)) - 1 syn1 = 2*np.random.random((4,1)) - 1 za j u xrange(60000): # ide naprijed kroz slojeve 0, 1 i 2 l0 = X l1 = nonlin(np.dot(l0,syn0)) l2 = nonlin(np.dot(l1,syn1)) # koliko smo pogriješili oko tražene vrijednosti? l2_error = y - l2 if (j% 10000) == 0: ispisati "Greška:" + str(np.mean(np.abs(l2_error))) # na koji način treba da se krećete? # ako smo bili sigurni u predviđanje, onda ga ne trebamo mnogo mijenjati l2_delta = l2_error*nonlin(l2,deriv=True) # koliko vrijednosti l1 utiču na greške u l2? l1_error = l2_delta.dot(syn1.T) # u kom pravcu treba da se krećemo da bismo došli do l1? # ako smo bili sigurni u predviđanje, onda ga ne trebamo mnogo mijenjati l1_delta = l1_error * nonlin(l1,deriv=True) syn1 += l1.T.dot(l2_delta) syn0 += l0.T.dot (l1_delta)

    Greška:0.496410031903 Greška:0.00858452565325 Greška:0.00578945986251 Greška:0.00462917677677 Greška:0.003958765280270 Er35060

    Varijable i njihovi opisi

    X je matrica ulaznog skupa podataka; žice - primjeri obuke
    y – matrica skupa izlaznih podataka; žice - primjeri obuke
    l0 – prvi sloj mreže definisan ulaznim podacima
    l1 – drugi sloj mreže, ili skriveni sloj
    l2 je završni sloj, ovo je naša hipoteza. Dok vježbate, trebali biste se približiti tačnom odgovoru.
    syn0 – prvi sloj pondera, Synapse 0, kombinuje l0 sa l1.
    syn1 – Drugi sloj pondera, Synapse 1, kombinuje l1 sa l2.
    l2_error – greška mreže u kvantitativnom smislu
    l2_delta – greška mreže, ovisno o pouzdanosti predviđanja. Gotovo identično grešci, osim sigurnih predviđanja
    l1_error – vaganjem l2_delta sa težinama iz syn1 izračunavamo grešku u srednjem/skrivenom sloju
    l1_delta – mrežne greške od l1, skalirane po pouzdanosti predviđanja. Gotovo identično l1_error, osim sigurnih predviđanja

    Kod bi trebao biti prilično jasan – to je samo prethodna implementacija mreže, složena u dva sloja, jedan na drugom. Izlaz prvog sloja l1 je ulaz drugog sloja. Nešto novo ima tek u sljedećem redu.

    L1_error = l2_delta.dot(syn1.T)

    Koristi greške ponderisane pouzdanošću predviđanja iz l2 za izračunavanje greške za l1. Dobijamo, moglo bi se reći, grešku ponderisanu doprinosima - izračunavamo koliko vrijednosti u čvorovima l1 doprinose greškama u l2. Ovaj korak se zove backpropagation. Zatim ažuriramo syn0 koristeći isti algoritam kao i dvoslojna neuronska mreža.

    Sada doživljavamo pravi procvat neuronskih mreža. Koriste se za prepoznavanje, lokalizaciju i obradu slike. Neuronske mreže već mogu učiniti mnoge stvari koje nisu dostupne ljudima. Moramo se sami uključiti u ovu stvar! Razmislite o neutronskoj mreži koja će prepoznati brojeve na ulaznoj slici. Vrlo je jednostavno: samo jedan sloj i funkcija aktivacije. Ovo nam neće omogućiti da prepoznamo apsolutno sve testne slike, ali možemo podnijeti veliku većinu. Kao podatke koristićemo zbirku podataka MNIST-a, dobro poznatu u svijetu prepoznavanja brojeva.

    Za rad s njim u Pythonu postoji biblioteka python-mnist. Za instaliranje:

    Pip instaliraj python-mnist

    Sada možemo učitati podatke

    Iz mnist import MNIST mndata = MNIST("/put_do_mnist_data_folder/") tr_images, tr_labels = mndata.load_training() test_images, test_labels = mndata.load_testing()

    Morate sami preuzeti arhive s podacima i odrediti put do direktorija s njima do programa. Sada varijable tr_images i test_images sadrže slike za obuku i testiranje mreže, respektivno. A varijable tr_labels i test_labels su oznake s ispravnom klasifikacijom (tj. brojevi sa slika). Sve slike su veličine 28x28. Postavimo varijablu s veličinom.

    Img_shape = (28, 28)

    Pretvorimo sve podatke u numpy nizove i normaliziramo ih (promijenimo im veličinu na veličinu od -1 do 1). Ovo će povećati tačnost proračuna.

    Uvezi numpy kao np za i u rasponu(0, len(test_images)): test_images[i] = np.array(test_images[i]) / 255 za i u rasponu(0, len(tr_images)): tr_images[i] = np.array(tr_images[i]) / 255

    Napominjem da iako su slike obično predstavljene u obliku dvodimenzionalni niz koristićemo jednodimenzionalni, lakši je za proračune. Sada morate razumjeti "šta je neuronska mreža"! A ovo je samo jednadžba sa velikim brojem koeficijenata. Imamo ulazni niz od 28*28=784 elemenata i još 784 težine za određivanje svake cifre. Tokom rada neuronske mreže, potrebno je pomnožiti ulazne vrijednosti ponderima. Dodajte rezultirajuće podatke i dodajte pomak. Rezultirajući rezultat se šalje funkciji aktivacije. U našem slučaju to će biti Relu. Ova funkcija je jednaka nuli za sve negativne argumente i nuli za sve pozitivne argumente.

    Postoji mnogo više funkcija za aktivaciju! Ali ovo je najjednostavnija neuronska mreža! Definirajmo ovu funkciju koristeći numpy

    Def relu(x): vrati np.maximum(x, 0)

    Sada, da biste izračunali sliku na slici, morate izračunati rezultat za 10 skupova koeficijenata.

    Def nn_calculate(img): resp = lista(opseg(0, 10)) za i u opsegu(0,10): r = w[:, i] * img r = relu(np.sum(r) + b[ i]) resp[i] = r vrati np.argmax(resp)

    Za svaki set ćemo dobiti izlazni rezultat. Izađite sa najveći rezultat najvjerovatnije je ovo naš broj.

    IN u ovom slučaju 7. To je to! Ali ne... Uostalom, te iste koeficijente morate negdje dobiti. Moramo trenirati našu neuronsku mrežu. U tu svrhu koristi se metoda povratnog razmnožavanja. Njegova suština je da izračuna izlaze mreže, uporedi ih sa ispravnim, a zatim od koeficijenata oduzme brojeve potrebne da bi rezultat bio tačan. Mora se imati na umu da je za izračunavanje ovih vrijednosti potreban izvod funkcije aktivacije. U našem slučaju, ona je jednaka nuli za sve negativne brojeve i 1 za sve pozitivne. Odredimo koeficijente nasumično.

    W = (2*np.random.rand(10, 784) - 1) / 10 b = (2*np.random.rand(10) - 1) / 10 za n u rasponu(len(tr_images)): img = tr_images[n] cls = tr_labels[n] #forward propagation resp = np.zeros(10, dtype=np.float32) za i u rasponu(0,10): r = w[i] * img r = relu( np.sum(r) + b[i]) resp[i] = r resp_cls = np.argmax(resp) resp = np.zeros(10, dtype=np.float32) resp = 1.0 #povratna propagacija true_resp = np. nule(10, dtype=np.float32) true_resp = 1.0 greška = resp - true_resp delta = greška * ((resp >= 0) * np.ones(10)) za i u rasponu (0,10): w[i ] -= np.dot(img, delta[i]) b[i] -= delta[i]

    Kako trening bude napredovao, koeficijenti će početi izgledati pomalo kao brojevi:

    Provjerimo tačnost rada:

    Def nn_calculate(img): resp = lista(opseg(0, 10)) za i u opsegu(0,10): r = w[i] * img r = np.maximum(np.sum(r) + b[ i], 0) #relu resp[i] = r vrati np.argmax(resp) ukupno = len(test_images) validno = 0 nevažeće = za i u opsegu(0, ukupno): img = test_images[i] predviđeno = nn_calculate (img) true = test_labels[i] ako je predviđeno == true: validno = validno + 1 else: invalid.append(("image":img, "predicted":predicted, "true":true)) print("accuracy ()".format(važeće/ukupno))

    Dobio sam 88%. Nije tako cool, ali veoma zanimljivo!

    Keras je popularna biblioteka dubokog učenja koja je uvelike doprinijela komercijalizaciji dubokog učenja. Keras je jednostavan za korištenje i omogućava vam da kreirate neuronske mreže sa samo nekoliko linija Python koda.

    U ovom članku ćete naučiti kako koristiti Keras za kreiranje neuronske mreže koja predviđa kako će korisnici ocijeniti proizvod na osnovu njihovih recenzija, klasificirajući ga u dvije kategorije: pozitivne ili negativne. Ovaj zadatak se zove analiza osjećaja (analiza osjećaja), a mi ćemo to riješiti uz pomoć stranice za pregled filmova IMDb. Model koji ćemo izgraditi može se primijeniti i za rješavanje drugih problema nakon manjih modifikacija.

    Imajte na umu da nećemo ulaziti u detalje o Kerasu i dubokom učenju. Ovaj post ima za cilj da pruži šemu u Kerasu i predstavi njegovu implementaciju.

    • Šta je Keras?
    • Šta je analiza osjećaja?
    • Dataset IMDB
    • Data Exploration
    • Priprema podataka
    • Kreiranje modela i obuka

    Šta je Keras?

    Keras je Python biblioteka otvorenog koda koja olakšava kreiranje neuronskih mreža. Biblioteka je kompatibilna sa , Microsoft Cognitive Toolkit, Theano i MXNet. Tensorflow i Theano su najčešće korišteni Python numerički okviri za razvoj algoritama dubokog učenja, ali su prilično teški za korištenje.


    Procjena popularnosti okvira mašinsko učenje u 7 kategorija

    Keras, s druge strane, pruža jednostavan i zgodan način kreiranje modela dubokog učenja. Njegov tvorac, François Chollet, razvio ga je kako bi što više ubrzao i pojednostavio proces stvaranja neuronskih mreža. Fokusirao se na proširivost, modularnost, minimalizam i podršku za Python. Keras se može koristiti sa GPU i CPU; podržava i Python 2 i Python 3. Keras Google je dao veliki doprinos komercijalizaciji dubokog učenja i zato što sadrži najsavremenije algoritme dubokog učenja koji su ranije bili ne samo nedostupni, već i neupotrebljivi.

    Šta je analiza osjećaja (analiza osjećaja)?

    Analiza osjećaja se može koristiti za određivanje stava osobe (tj. raspoloženja) prema tekstu, interakciji ili događaju. Dakle, analiza sentimenta spada u oblast obrade prirodnog jezika, u kojoj se značenje teksta mora dešifrovati da bi se iz njega izdvojili sentiment i sentiment.


    Primjer skale za analizu osjećaja

    Spektar raspoloženja se obično dijeli na pozitivno, negativno i neutralno kategorije. Koristeći analizu sentimenta, možete, na primjer, predvidjeti mišljenja kupaca i njihov stav prema proizvodu na osnovu recenzija koje pišu. Stoga se analiza osjećaja široko primjenjuje na recenzije, ankete, tekstove i još mnogo toga.

    IMDb skup podataka


    Recenzije na IMDb

    IMDb skup podataka sastoji se od 50.000 recenzija filmova korisnika, označenih kao pozitivne (1) i negativne (0).

    • Recenzije su prethodno obrađene i svaka je kodirana nizom indeksa riječi kao cijelih brojeva.
    • Riječi u recenzijama su indeksirane po njihovom opšta frekvencija pojavljivanje u skupu podataka. Na primjer, cijeli broj "2" kodira drugu najčešće korištenu riječ.
    • 50.000 pregleda podijeljeno je u dva skupa: 25.000 za obuku i 25.000 za testiranje.

    Skup podataka su kreirali istraživači sa Univerziteta Stanford i predstavljeni u radu iz 2011. godine, u kojem je postignuta tačnost predviđanja bila 88,89%. Skup podataka je također korišten kao dio takmičenja Keggle zajednice "Vreća riječi susreće vreće kokica" u 2011.

    Uvoz zavisnosti i dohvaćanje podataka

    Počnimo s uvozom potrebnih ovisnosti za prethodnu obradu podataka i izgradnju modela.

    %matplotlib inline import matplotlib import matplotlib.pyplot as plt import numpy kao np iz keras.utils import to_categorical iz keras import modela iz keras import slojeva

    Učitajmo IMDb skup podataka, koji je već ugrađen u Keras. Pošto ne želimo da imamo 50/50 podatke o obuci i testiranju, odmah ćemo spojiti ove podatke nakon učitavanja za kasnije razdvajanje u omjeru 80/20:

    Iz keras.datasets uvezite imdb (training_data, training_targets), (testing_data, testing_targets) = imdb.load_data(num_words=10000) data = np.concatenate((podaci_treninga, testing_data), axis=0) targeting_cate = np. , testing_targets), axis=0)

    Data Exploration

    Proučimo naš skup podataka:

    Print("Kategorije:", np.unique(ciljevi)) print("Broj jedinstvenih riječi:", len(np.unique(np.hstack(data)))) Kategorije: Broj jedinstvenih riječi: 9998 dužina = print ("Prosječna dužina recenzije:", np.srednja(dužina)) print("Standardna devijacija:", okrugla(np.std(dužina))) Prosječna dužina recenzije: 234,75892 Standardna devijacija: 173,0

    Možete vidjeti da svi podaci spadaju u dvije kategorije: 0 ili 1, što predstavlja osjećaj recenzije. Cijeli skup podataka sadrži 9998 jedinstvenih riječi, prosječna veličina pregleda je 234 riječi sa standardnom devijacijom od 173.

    Pogledajmo jednostavan način učenja:

    Print("Label:", targets) Label: 1 print(data)

    Ovdje vidite prvu recenziju iz skupa podataka, koja je označena kao pozitivna (1). Sljedeći kod pretvara indekse natrag u riječi kako bismo ih mogli čitati. U njemu se svaka nepoznata riječ zamjenjuje sa "#". Ovo se radi pomoću funkcije get_word_index().

    Index = imdb.get_word_index() reverse_index = dict([(vrijednost, ključ) za (ključ, vrijednost) u index.items()]) decoded = " ".join() print(decoded) # ovaj film je bio samo briljantan casting lokacija scenografija režija priče je svima zaista odgovarala uloga koju su igrali i možete samo zamisliti da ste tamo Robert # je nevjerovatan glumac i sada the isti kao režiser # otac je došao sa istog škotskog ostrva kao i ja pa mi se svidela činjenica da postoji stvarna veza sa ovim filmom, duhovite primedbe kroz film su bile sjajne da je bio toliko briljantan da sam kupio film čim je bio objavljeno za # i preporučio bih ga svima za gledanje i pecanje na mušicu je bilo nevjerovatno stvarno sam plakao na kraju bilo je tako tužno i znaš šta kažu ako plačeš na filmu mora da je bio dobar i ovo je definitivno bilo # za dva mala dječaka koji su igrali # normana i Paul, oni su bili samo briljantna djeca, često su izostavljena sa liste #, mislim jer su zvijezde koje glume sve odrasle tako veliki profil za cijeli film, ali ova djeca su nevjerovatna i treba ih pohvaliti za ono što su uradili don" ti misliš da je cijela priča bila tako lijepa jer je bila istinita i bio je nečiji život nakon svega što je podijeljeno sa svima nama

    Priprema podataka

    Vrijeme je za pripremu podataka. Trebamo vektorizirati svaku recenziju i ispuniti je nulama tako da vektor sadrži tačno 10.000 brojeva. To znači da svaku recenziju koja je kraća od 10.000 riječi popunjavamo nulama. Ovo je učinjeno jer najviše odlična recenzija je gotovo iste veličine, a svaki element ulaznih podataka u našu neuronsku mrežu trebao bi biti iste veličine. Takođe morate da konvertujete varijable u tip float.

    Def vectorize(sekvence, dimenzija = 10000): rezultati = np.zero((len(sekvence), dimenzija)) za i, sekvenca u enumerate(sekvence): rezultati = 1 vraćanje rezultata podaci = vektorizacija(podaci) ciljevi = np. array(targets).astype("float32")

    Podijelimo skup podataka na skupove za obuku i testiranje. Set za obuku će se sastojati od 40.000 pregleda, set za testiranje će se sastojati od 10.000.

    Test_x = podaci[:10000] test_y = ciljevi[:10000] train_x = podaci train_y = ciljevi

    Kreiranje modela i obuka

    Sada možete kreirati jednostavnu neuronsku mrežu. Počnimo s definiranjem tipa modela koji želimo kreirati. U Kerasu postoje dvije vrste modela: sekvencijalni i funkcionalni API.

    Zatim morate dodati ulazne, skrivene i izlazne slojeve. Kako bismo spriječili prekomjerno uklapanje, koristit ćemo izuzetak između njih ( "ispasti"). Imajte na umu da uvijek trebate koristiti stopu isključenja između 20% i 50%. Svaki sloj koristi funkciju "gusto" kako bi se slojevi u potpunosti povezali jedan s drugim. U skrivenim slojevima ćemo koristiti "relu", jer to gotovo uvijek dovodi do zadovoljavajućih rezultata. Nemojte se bojati eksperimentirati s drugim funkcijama aktivacije. Na izlaznom sloju koristimo sigmoidnu funkciju koja renormalizira vrijednosti u rasponu od 0 do 1. Imajte na umu da smo postavili veličinu ulaznih elemenata skupa podataka na 10.000 jer su naše recenzije veličine do 10.000 cijelih brojeva. Ulazni sloj prihvata elemente veličine 10.000 i izlazi elemente veličine 50.

    Konačno, pustite Keras da izbaci Kratki opis model koji smo upravo kreirali.

    # Input - Layer model.add(layers.Dense(50, activation = "relu", input_shape=(10000,))) # Hidden - Slojevi model.add(layers.Dropout(0.3, noise_shape=None, seed=None) ) model.add(layers.Dense(50, activation = "relu") model.add(layers.Dropout(0.2, noise_shape=None, seed=None)) model.add(layers.Dense(50, activation = "relu) ")) # Output- Layer model.add(layers.Dense(1, activation = "sigmoid"))model.summary() model.summary() ________________________________________________________________ Sloj (tip) Izlazni oblik Param # ======= =================================================== === ======== gusto_1 (Gusto) (Nema, 50) 500050 ___________________________________________________________________ ispadanje_1 (Otpadanje) (Nema, 50) 0 ________________________________________________________________ gusto_2 (Gusto) (Nema, 50) 2550 _2________________________________________________ , 50) 0 ________________________________________________________________ gusto_3 (Gusto) (nijedno, 50) 2550 ________________________________________________________________ gusto_4 (Gusto) (nijedno, 1) 51 ========================= ============================ Ukupni parametri: 505,201 Parametri koji se mogu obučiti: 505,201 Parametri koji se ne mogu obučiti: 0 ________________________________________________________________

    Sada treba da sastavimo naš model, odnosno da ga u suštini podesimo za obuku. Koristićemo optimizator "adam". Optimizator je algoritam koji mijenja težine i predrasude tokom treninga. As funkcije gubitka Koristimo binarnu unakrsnu entropiju (pošto radimo sa binarnom klasifikacijom), tačnost kao metriku evaluacije.

    Model.compile(optimizer = "adam", gubitak = "binary_crossentropy", metrics = ["accuracy"])

    Sada možemo trenirati naš model. Uradićemo to sa veličinom serije od 500 i samo dve epohe kako sam saznao model počinje da se obučava, ako ga duže trenirate. Veličina serije određuje broj elemenata koji će biti raspoređeni po mreži, a epoha je jedan prolaz kroz sve elemente skupa podataka. Obično veća veličina serija dovodi do bržeg učenja, ali ne uvijek do brzog približavanja. Manja veličina serije trenira se sporije, ali može brže konvergirati. Izbor jednog ili drugog definitivno ovisi o vrsti problema koji se rješava, a bolje je isprobati svaki od njih. Ako ste novi u ovome, preporučio bih vam da prvo koristite veličina parcele 32, što je svojevrsni standard.

    Rezultati = model.fit(train_x, train_y, epochs= 2, batch_size = 500, validation_data = (test_x, test_y)) Obučite na 40000 uzoraka, potvrdite na 10000 uzoraka Epoha 1/2 40000/40000 === [= =======================] - 5s 129us/korak - gubitak: 0,4051 - acc: 0,8212 - val_loss: 0,2635 - val_acc: 0,8945 Epoha 2/2 4000 /40000 [=============================] - 4s 90us/korak - gubitak: 0,2122 - acc: 0,9190 - val_loss: 0,2598 - val_acc: 0,8950

    Procijenimo performanse modela:

    Print(np.mean(results.history["val_acc"])) 0.894750000536

    Odlično! Naš jednostavan model je već oborio rekord tačnosti u članku iz 2011 spomenuto na početku posta. Slobodno eksperimentirajte s mrežnim parametrima i brojem slojeva.

    Kompletan kod modela je dat u nastavku:

    Uvezi numpy kao np iz keras.utils import to_categorical iz keras uvozi modele iz keras import slojeva iz keras.datasets import imdb (training_data, training_targets), (testing_data, testing_targets) = imdb.load_data(num_words)con data=10000(. (podaci_treninga, podaci_testiranja), axis=0) targets = np.concatenate((training_targets, testing_targets), axis=0) def vectorize(sekvence, dimenzija = 10000): rezultati = np.nule((len(sekvence), dimenzija) ) za i, niz u enumerate(sekvence): rezultati = 1 vraća rezultate podaci = vektorizirati(podaci) ciljevi = np.array(targets).astype("float32") test_x = podaci[:10000] test_y = ciljevi[:10000 ] train_x = podaci train_y = ciljni model = modeli.Sequential() # Ulaz - Slojevi model.add(layers.Dense(50, aktivacija = "relu", input_shape=(10000,))) # Skriven - Slojevi model.add( layers.Dropout(0.3, noise_shape=Nema, seed=None)) model.add(layers.Dense(50, activation = "relu")) model.add(layers.Dropout(0.2, noise_shape=Nema, seed=Ništa) ) model.add(layers.Dense(50, activation = "relu")) # Izlaz- Sloj model.add(layers.Dense(1, activation = "sigmoid")) model.summary() # kompajliranje modela modela. compile(optimizer = "adam", gubitak = "binary_crossentropy", metrics = ["accuracy"]) rezultati = model.fit(train_x, train_y, epochs= 2, batch_size = 500, validation_data = (test_x, test_y)) print( "Test-Accuracy:", np.mean(results.history["val_acc"]))

    Rezultati

    Naučili ste što je analiza osjećaja i zašto je Keras jedna od najpopularnijih biblioteka dubokog učenja.

    Napravili smo jednostavnu neuronsku mrežu sa šest slojeva koja može izračunati osjećaje recenzenata filmova sa 89% preciznosti. Sada možete koristiti ovaj model za analizu binarnih osjećaja u drugim izvorima, ali da biste to učinili, morat ćete napraviti njihovu veličinu jednakom 10.000 ili promijeniti parametre ulaznog sloja.

    Ovaj model (sa manjim modifikacijama) se može primijeniti na druge probleme strojnog učenja.

    Neuronske mreže se kreiraju i obučavaju uglavnom u Pythonu. Stoga je vrlo važno imati osnovno razumijevanje kako pisati programe u njemu. U ovom članku ću kratko i jasno govoriti o osnovnim konceptima ovog jezika: varijablama, funkcijama, klasama i modulima.

    Materijal je namijenjen osobama koje ne poznaju programske jezike.

    Prvo morate instalirati Python. Zatim morate instalirati pogodno okruženje za pisanje programa u Python-u. Portal je posvećen ova dva koraka.

    Ako je sve instalirano i konfigurirano, možete početi.

    Varijable

    Varijabilna- ključni koncept u bilo kojem programskom jeziku (i ne samo u njima). Najlakši način da zamislite varijablu je kao okvir s oznakom. Ova kutija sadrži nešto (broj, matricu, objekt,...) što nam je vrijedno.

    Na primjer, želimo da kreiramo varijablu x koja bi trebala pohraniti vrijednost 10. U Pythonu bi kod za kreiranje ove varijable izgledao ovako:

    Na lijevoj strani mi najavljujemo varijabla pod nazivom x. Ovo je ekvivalentno stavljanju oznake sa imenom na kutiju. Slijede znak jednakosti i broj 10. Znak jednakosti ovdje igra neobičnu ulogu. To ne znači da je "x jednako 10". Jednakost u ovom slučaju stavlja broj 10 u okvir. Tačnije rečeno, mi dodijeliti varijabla x je broj 10.

    Sada, u kodu ispod možemo pristupiti ovoj varijabli i također izvoditi razne akcije s njom.

    Možete jednostavno prikazati vrijednost ove varijable na ekranu:

    X=10 print(x)

    print(x) predstavlja poziv funkcije. Razmotrićemo ih dalje. Sada je važno da ova funkcija ispisuje na konzolu ono što se nalazi između zagrada. Između zagrada imamo x. Ranije smo x dodijelili vrijednost 10. Ovo je ono što se 10 ispisuje u konzoli ako pokrenete program iznad.

    S varijablama koje pohranjuju brojeve mogu se izvoditi razne jednostavne operacije: sabiranje, oduzimanje, množenje, dijeljenje i stepenovanje.

    X = 2 y = 3 # Sabiranje z = x + y print(z) # 5 # Razlika z = x - y print(z) # -1 # Proizvod z = x * y print(z) # 6 # Podjela z = x / y print(z) # 0,66666... ​​# Eksponencijacija z = x ** y print(z) # 8

    U kodu iznad, prvo kreiramo dvije varijable koje sadrže 2 i 3. Zatim kreiramo varijablu z koja pohranjuje rezultat operacije na x i y i ispisuje rezultate na konzoli. Ovaj primjer jasno pokazuje da varijabla može promijeniti svoju vrijednost tokom izvršavanja programa. Dakle, naša varijabla z mijenja svoju vrijednost čak 5 puta.

    Funkcije

    Ponekad postaje neophodno izvoditi iste radnje iznova i iznova. Na primjer, u našem projektu često moramo prikazati 5 redova teksta.

    “Ovo je veoma važan tekst!”
    “Ovaj tekst se ne može pročitati”
    „Greška u gornja linija posebno priznat"
    "zdravo i doviđenja"
    "kraj"

    Naš kod će izgledati ovako:

    X = 10 y = x + 8 - 2 print("Ovo je veoma važan tekst!") print("Ovaj tekst se ne može pročitati") print("Greška u gornjem redu je napravljena namjerno") print(" Zdravo i ćao") print ("Kraj") z = x + y print("Ovo je veoma važan tekst!") print("Ovaj tekst se ne može pročitati") print("Napravljena je greška u gornjem redu namjerno”) print(“Zdravo i ćao”) print ("Kraj") test = z print("Ovo je veoma važan tekst!") print("Ovaj tekst se ne može pročitati") print("Greška u gornji red je napravljen namjerno") print("Zdravo i ćao") print(" Kraj")

    Sve to izgleda veoma suvišno i nezgodno. Osim toga, došlo je do greške u drugom redu. Može se popraviti, ali će se morati popraviti na tri mjesta odjednom. Šta ako se ovih pet linija pozove 1000 puta u našem projektu? I sve je na različitim mjestima i fajlovima?

    Posebno za slučajeve kada trebate često izvršavati iste naredbe, možete kreirati funkcije u programskim jezicima.

    Funkcija- poseban blok koda koji se može pozvati po imenu.

    Funkcija se definira korištenjem ključne riječi def. Nakon toga slijedi naziv funkcije, zatim zagrade i dvotočka. Zatim morate navesti, uvučene, radnje koje će se izvršiti prilikom pozivanja funkcije.

    Def print_5_lines(): print("Ovo je veoma važan tekst!") print("Ovaj tekst se ne može pročitati") print("Greška u gornjem redu je napravljena namjerno") print("Zdravo i ćao") print("Kraj")

    Sada smo definirali funkciju print_5_lines(). Sada, ako u našem projektu još jednom trebamo umetnuti pet redaka, onda jednostavno pozivamo našu funkciju. Automatski će izvršiti sve radnje.

    # Definirajte funkciju def print_5_lines(): print("Ovo je veoma važan tekst!") print("Ovaj tekst se ne može pročitati") print("Greška u gornjem redu je bila namjerna") print("Zdravo i ćao ") print(" Kraj") # Kod našeg projekta x = 10 y = x + 8 - 2 print_5_lines() z = x + y print_5_lines() test = z print_5_lines()

    Zgodno, zar ne? Ozbiljno smo poboljšali čitljivost koda. Osim toga, funkcije su također dobre jer ako želite promijeniti neku od radnji, onda samo trebate ispraviti samu funkciju. Ova promjena će raditi na svim mjestima gdje se poziva vaša funkcija. To jest, možemo ispraviti grešku u drugom redu izlaznog teksta (“ne” > “ne”) u tijelu funkcije. Ispravna opcija će biti automatski pozvana na svim mjestima u našem projektu.

    Funkcije s parametrima

    Svakako je zgodno jednostavno ponoviti nekoliko radnji. Ali to nije sve. Ponekad želimo da prenesemo neku varijablu našoj funkciji. Na ovaj način, funkcija može prihvatiti podatke i koristiti ih dok izvršava naredbe.

    Pozivaju se varijable koje prosljeđujemo funkciji argumentima.

    Hajde da pišemo jednostavna funkcija, koji dodaje dva data broja i vraća rezultat.

    Def zbroj(a, b): rezultat = a + b vraća rezultat

    Prvi red izgleda skoro isto kao i obične funkcije. Ali između zagrada sada postoje dvije varijable. Ovo opcije funkcije. Naša funkcija ima dva parametra (odnosno, uzima dvije varijable).

    Parametri se mogu koristiti unutar funkcije baš kao i obične varijable. U drugom redu kreiramo varijabilni rezultat, koji je jednak zbiru parametara a i b. U trećem redu vraćamo vrijednost varijable rezultata.

    Sada, u daljem kodu možemo napisati nešto poput:

    Novo = suma(2, 3) print(novo)

    Pozivamo funkciju suma i prosljeđujemo joj dva argumenta redom: 2 i 3. 2 postaje vrijednost varijable a, a 3 postaje vrijednost varijable b. Naša funkcija vraća vrijednost (zbir 2 i 3) i koristimo je za kreiranje nove varijable, new .

    Zapamti. U kodu iznad, brojevi 2 i 3 su argumenti funkcije suma. A u samoj funkciji sume, varijable a i b su parametri. Drugim riječima, varijable koje prosljeđujemo funkciji kada se ona pozove nazivaju se argumenti. Ali unutar funkcije, ove proslijeđene varijable se nazivaju parametri. Zapravo, ovo su dva naziva za istu stvar, ali ih ne treba brkati.

    Pogledajmo još jedan primjer. Kreirajmo funkciju square(a) koja uzima jedan broj i kvadrira ga:

    Def square(a): vrati a * a

    Naša funkcija se sastoji od samo jedne linije. Odmah vraća rezultat množenja parametra a sa a.

    Mislim da ste već pogodili da takođe šaljemo podatke na konzolu pomoću funkcije. Ova funkcija se zove print() i ispisuje argument koji joj je proslijeđen u konzolu: broj, string, varijablu.

    Nizovi

    Ako se varijabla može smatrati kutijom koja pohranjuje nešto (ne nužno broj), onda se nizovi mogu smatrati policama za knjige. Sadrže nekoliko varijabli odjednom. Evo primjera niza od tri broja i jednog niza:

    Niz =

    Evo primjera kada varijabla ne sadrži broj, već neki drugi objekt. U ovom slučaju, naša varijabla sadrži niz. Svaki element niza je numerisan. Pokušajmo prikazati neki element niza:

    Niz = print(niz)

    U konzoli ćete vidjeti broj 89. Ali zašto 89, a ne 1? Stvar je u tome da u Pythonu, kao iu mnogim drugim programskim jezicima, numerisanje nizova počinje od 0. Dakle, niz nam daje sekunda element niza, a ne prvi. Da biste pozvali prvi, morali ste napisati niz .

    Veličina niza

    Ponekad je vrlo korisno dobiti broj elemenata u nizu. Za ovo možete koristiti funkciju len(). On će izbrojati broj elemenata i vratiti njihov broj.

    Niz = print(len(niz))

    Konzola će prikazati broj 4.

    Uslovi i ciklusi

    Podrazumevano, bilo koji program jednostavno izvršava sve naredbe u nizu od vrha do dna. Ali postoje situacije kada trebamo provjeriti neki uvjet, i ovisno o tome da li je istinit ili ne, izvršiti različite radnje.

    Osim toga, često postoji potreba za ponavljanjem gotovo istog niza naredbi mnogo puta.

    U prvoj situaciji pomažu uvjeti, a u drugoj pomažu ciklusi.

    Uslovi

    Uslovi su potrebni za izvođenje dva različita skupa radnji u zavisnosti od toga da li je iskaz koji se testira istinit ili netačan.

    U Pythonu, uslovi se mogu napisati pomoću if: ... else: ... konstrukcije. Neka nam je neka varijabla x = 10. Ako je x manje od 10, onda želimo podijeliti x sa 2. Ako je x veće ili jednako 10, tada želimo kreirati drugu novu varijablu, koja je jednaka zbroju x i broja 100. Ovo je kako će izgledati kod:

    X = 10 ako(x< 10): x = x / 2 print(x) else: new = x + 100 print(new)

    Nakon kreiranja varijable x, počinjemo pisati naš uvjet.

    Sve počinje ključnom riječi if (prevedeno s engleskog kao “ako”). U zagradama označavamo izraz koji treba provjeriti. U ovom slučaju provjeravamo da li je naša varijabla x zaista manja od 10. Ako je zaista manja od 10, onda je podijelimo sa 2 i ispisujemo rezultat na konzolu.

    Onda dolazi ključna riječ else , nakon čega počinje blok akcija koje će se izvršiti ako je izraz u zagradama iza if netačan.

    Ako je veći ili jednak 10, onda kreiramo novu varijablu new, koja je jednaka x + 100 i također je šaljemo na konzolu.

    Ciklusi

    Petlje su potrebne za ponavljanje radnji mnogo puta. Recimo da želimo prikazati tabelu kvadrata prvih 10 prirodni brojevi. To se može uraditi ovako.

    Print("Kvadrat 1 je " + str(1**2)) print("Kvadrat 2 je " + str(2**2)) print("Kvadrat 3 je " + str(3**2)) print( "Kvadrat 4 je " + str(4**2)) print("Kvadrat 5 je " + str(5**2)) print("Kvadrat 6 je " + str(6**2)) print("Kvadrat 7 je " + str(7**2)) print("Kvadrat od 8 je " + str(8**2)) print("Kvadrat od 9 je " + str(9**2)) print("Kvadrat od 10 je " + str(10**2))

    Nemojte biti iznenađeni činjenicom da dodajemo linije. "početak reda" + "kraj" u Pythonu jednostavno znači spajanje stringova: "početak kraja reda". Na isti način iznad, dodajemo niz „Kvadrat od x je jednak ” i rezultat podizanja broja na 2. stepen, konvertovan pomoću funkcije str(x**2).

    Kod iznad izgleda vrlo suvišan. Šta ako trebamo ispisati kvadrate prvih 100 brojeva? Muči nas da se povlačimo...

    Za takve slučajeve postoje ciklusi. Postoje 2 tipa petlji u Pythonu: while i for. Hajde da se pozabavimo njima jedan po jedan.

    Dok petlja ponavlja potrebne naredbe sve dok uvjet ostaje istinit.

    X = 1 dok je x<= 100: print("Квадрат числа " + str(x) + " равен " + str(x**2)) x = x + 1

    Prvo kreiramo varijablu i dodijelimo joj broj 1. Zatim kreiramo while petlju i provjeravamo da li je naš x manji od (ili jednak) 100. Ako je manje (ili jednako) onda izvodimo dvije radnje:

    1. Iznesite kvadrat x
    2. Povećajte x za 1

    Nakon druge naredbe, program se vraća u stanje. Ako je uslov ponovo tačan, onda ponovo izvodimo ove dvije akcije. I tako sve dok x ne postane jednako 101. Tada će se uvjet vratiti netačno i petlja se više neće izvršavati.

    Petlja for je dizajnirana za ponavljanje nizova. Napišimo isti primjer s kvadratima prvih sto prirodnih brojeva, ali kroz for petlju.

    Za x u rasponu (1,101): print("Kvadrat broja " + str(x) + " je " + str(x**2))

    Pogledajmo prvi red. Koristimo ključnu riječ for za kreiranje petlje. Zatim navodimo da želimo da ponovimo određene akcije za sve x u rasponu od 1 do 100. Funkcija range(1,101) kreira niz od 100 brojeva, počevši od 1 i završavajući sa 100.

    Evo još jednog primjera ponavljanja niza koristeći for petlju:

    Za i in : print(i * 2)

    Kod iznad daje 4 broja: 2, 20, 200 i 2000. Ovdje možete jasno vidjeti kako uzima svaki element niza i izvodi skup radnji. Zatim uzima sljedeći element i ponavlja isti skup radnji. I tako sve dok se elementi u nizu ne ponestanu.

    Klase i objekti

    U stvarnom životu ne operišemo sa varijablama ili funkcijama, već sa objektima. Olovka, auto, osoba, mačka, pas, avion - objekti. Sada počnimo da detaljno pogledamo mačku.

    Ima neke parametre. To uključuje boju dlake, boju očiju i njen nadimak. Ali to nije sve. Osim parametara, mačka može izvoditi razne radnje: prede, šištati i grebati.

    Upravo smo shematski opisali sve mačke općenito. Slično opis svojstava i radnji neki objekat (na primjer, mačka) u Pythonu se zove klasa. Klasa je jednostavno skup varijabli i funkcija koje opisuju objekt.

    Važno je razumjeti razliku između klase i objekta. klasa - shema, koji opisuje objekat. Predmet je ona materijalno oličenje. Klasa mačke je opis njenih svojstava i radnji. Objekat mačke je sama prava mačka. Može postojati mnogo različitih pravih mačaka - mnogo mačjih objekata. Ali postoji samo jedna klasa mačaka. Dobra demonstracija je slika ispod:

    Casovi

    Da biste kreirali klasu (naša mačja šema), potrebno je da napišete ključnu reč class, a zatim navedete ime ove klase:

    Klasa mačka:

    Zatim moramo navesti akcije ove klase (mačke akcije). Akcije, kao što ste mogli pretpostaviti, su funkcije definirane unutar klase. Takve funkcije unutar klase obično se nazivaju metodama.

    Metoda- funkcija definirana unutar klase.

    Već smo gore opisali mačje metode verbalno: predenje, siktanje, grebanje. Sada uradimo to u Pythonu.

    # Cat class class Cat: # Purr def purr(self): print("Purrr!") # Šištanje def hiss(self): print("Shhh!") # Scratch def scrabble(self): print("Scratch-scratch) !")

    To je tako jednostavno! Uzeli smo i definirali tri obične funkcije, ali samo unutar klase.

    Kako bismo se pozabavili neshvatljivim parametrom selfa, dodajmo još jednu metodu našoj mački. Ova metoda će pozvati sve tri već kreirane metode odjednom.

    # Cat klasa Cat: # Purr def purr(self): print("Purrr!") # Šištanje def hiss(self): print("Shhh!") # Scratch def scrabble(self): print("Scratch-scratch !") # Sve zajedno def all_in_one(self): self.purr() self.hiss() self.scrabble()

    Kao što vidite, self parametar, potreban za bilo koju metodu, omogućava nam pristup metodama i varijablama same klase! Bez ovog argumenta ne bismo bili u mogućnosti da izvodimo takve radnje.

    Postavimo sada svojstva naše mačke (boja krzna, boja očiju, nadimak). Kako uraditi? U apsolutno bilo kojoj klasi možete definirati funkciju __init__(). Ova funkcija se uvijek poziva kada kreiramo pravi objekt naše klase.

    U gore istaknutoj metodi __init__() postavljamo varijable naše mačke. Kako da ovo uradimo? Prvo, ovoj metodi prosljeđujemo 3 argumenta, koji su odgovorni za boju dlake, boju očiju i nadimak. Zatim koristimo self parametar da odmah postavimo našu mačku na 3 gore opisana atributa prilikom kreiranja objekta.

    Šta znači ova linija?

    Self.wool_color = boja_wool_color

    Na lijevoj strani kreiramo atribut za našu mačku pod nazivom wool_color, a zatim ovom atributu dodjeljujemo vrijednost koja je sadržana u parametru wool_color koji smo proslijedili funkciji __init__(). Kao što vidite, linija iznad se ne razlikuje od normalnog kreiranja varijable. Samo prefiks self označava da ova varijabla pripada Cat klasi.

    Atribut- varijabla koja pripada klasi.

    Dakle, napravili smo gotovu klasu za mačke. Evo njegovog koda:

    # Klasa Cat klase Cat: # Radnje koje treba izvršiti prilikom kreiranja objekta "Cat" def __init__(self, wool_color, eyes_color, name): self.wool_color = wool_color self.eyes_color = eyes_color self.name = name # Purr def purr( self): print("Purrr!") # Šištanje def šištanje(self): print("Shhh!") # Grebanje def scrabble(self): print("Grebanje-grebanje!") # Sve zajedno def all_in_one(self) : self.purr() self.hiss() self.scrabble()

    Objekti

    Napravili smo dijagram mačke. Sada kreirajmo pravi objekat mačke koristeći ovu šemu:

    My_cat = Mačka("crna", "zelena", "Zosya")

    U gornjoj liniji kreiramo varijablu my_cat i zatim joj dodjeljujemo objekt klase Cat. Sve ovo izgleda kao poziv neke funkcije Cat(...) . U stvari, to je istina. Ovim unosom pozivamo metodu __init__() klase Cat. Funkcija __init__() u našoj klasi uzima 4 argumenta: sam objekt klase self, koji ne treba specificirati, kao i još 3 različita argumenta, koji tada postaju atributi naše mačke.

    Dakle, koristeći gornju liniju kreirali smo pravi objekat mačke. Naša mačka ima sljedeće atribute: crno krzno, zelene oči i nadimak Zosya. Ispišimo ove atribute na konzolu:

    Print(my_cat.wool_color) print(my_cat.eyes_color) print(my_cat.name)

    To jest, možemo pristupiti atributima objekta tako što ćemo napisati ime objekta, staviti tačku i naznačiti ime željenog atributa.

    Atributi mačke se mogu mijenjati. Na primjer, promijenimo ime naše mačke:

    My_cat.name = "Nyusha"

    Sada, ako ponovo prikažete ime mačke na konzoli, vidjet ćete Nyusha umjesto Zosia.

    Dozvolite mi da vas podsjetim da naš čas mačke omogućava da izvodi određene radnje. Ako pomazimo našu Zosju/Njušu, ona će početi da prede:

    My_cat.purr()

    Izvršavanje ove naredbe će ispisati tekst “Purrr!” na konzoli. Kao što vidite, pristup metodama objekta je jednako jednostavan kao i pristup njegovim atributima.

    Moduli

    Svaki fajl sa ekstenzijom .py je modul. Čak i onu u kojoj radite na ovom članku. Za šta su oni potrebni? Za udobnost. Mnogi ljudi kreiraju datoteke s korisnim funkcijama i klasama. Drugi programeri povezuju ove module treće strane i mogu koristiti sve funkcije i klase definirane u njima, čime se pojednostavljuje njihov rad.

    Na primjer, ne morate gubiti vrijeme na pisanje vlastitih funkcija da biste radili s matricama. Dovoljno je povezati numpy modul i koristiti njegove funkcije i klase.

    On ovog trenutka drugi Python programeri su već napisali preko 110.000 različitih modula. Gore spomenuti numpy modul omogućava vam brz i praktičan rad sa matricama i višedimenzionalnim nizovima. Matematički modul pruža mnoge metode za rad s brojevima: sinuse, kosinuse, pretvaranje stupnjeva u radijane, itd., itd.

    Instalacija modula

    Python se instalira zajedno sa standardnim skupom modula. Ovaj set uključuje vrlo veliki broj modula koji vam omogućavaju rad s matematikom, web zahtjevima, čitanje i pisanje datoteka i obavljanje drugih potrebnih radnji.

    Ako želite da koristite modul koji nije uključen u standardni set, moraćete da ga instalirate. Da biste instalirali modul, otvorite komandnu liniju (Win + R, zatim unesite "cmd" u polje koje se pojavi) i unesite naredbu u nju:

    Pip instalacija [module_name]

    Proces instalacije modula će započeti. Kada se završi, možete bezbedno koristiti instalirani modul u svom programu.

    Povezivanje i korištenje modula

    Modul treće strane je vrlo jednostavan za povezivanje. Trebate napisati samo jednu kratku liniju koda:

    Uvezi [module_name]

    Na primjer, da biste uvezli modul koji vam omogućava rad s matematičkim funkcijama, trebate napisati sljedeće:

    Uvezi matematiku

    Kako pristupiti funkciji modula? Morate napisati naziv modula, zatim staviti tačku i napisati naziv funkcije/klase. Na primjer, faktorijel 10 se nalazi ovako:

    Matematika.faktorija(10)

    To jest, okrenuli smo se funkciji faktorijala(a), koja je definirana unutar matematičkog modula. Ovo je zgodno, jer ne trebamo gubiti vrijeme i ručno kreirati funkciju koja izračunava faktorijel broja. Možete spojiti modul i odmah izvršiti potrebnu radnju.

    Original: Kreiranje neuronske mreže u Pythonu
    Autor: John Serrano
    Datum objave: 26.05.2016
    Prijevod: A. Panin
    Datum prevoda: 6. decembar 2016

    Neuronske mreže su izuzetno složeni programi, razumljivi samo akademicima i genijima, s kojima po definiciji ne mogu raditi obični programeri, da ne spominjem mene. To ti misliš, zar ne?

    Pa, zapravo uopšte nije tako. Nakon odličnog govora Louisa Moniera i Grega Renarda na koledžu Holberton, shvatio sam da su neuronske mreže dovoljno jednostavne da ih svaki programer programa razumije i implementira. Naravno, najsloženije mreže su projekti velikih razmjera sa elegantnom i zamršenom arhitekturom, ali osnovni koncepti su također manje-više očigledni. Razvijanje bilo koje neuronske mreže od nule može biti popriličan izazov, ali na sreću postoji nekoliko sjajnih biblioteka koje mogu obaviti sav posao na niskom nivou umjesto vas.

    U ovom kontekstu, neuron je prilično jednostavan entitet. Prihvata nekoliko ulaznih vrijednosti i ako zbroj ovih vrijednosti premašuje određenu granicu, aktivira se. U ovom slučaju, svaka ulazna vrijednost se množi svojom težinom. Proces učenja je u suštini proces postavljanja pondera vrijednosti za generiranje traženih izlaznih vrijednosti. Mreže o kojima će biti reči u ovom članku nazivaju se „feedforward” mreže, što znači da su neuroni u njima raspoređeni u slojeve, pri čemu njihovi ulazni podaci dolaze sa prethodnog nivoa, a izlazni podaci se šalju na sledeći nivo.

    Postoje i druge vrste neuronskih mreža, kao što su rekurentne neuronske mreže, koje su organizirane na drugačiji način, ali to je tema za drugi članak.

    Neuron koji radi po gore opisanom principu naziva se perceptron i baziran je na originalnom modelu umjetnih neurona, koji se danas izuzetno rijetko koristi. Problem s perceptronima je što mala promjena ulaznih vrijednosti može dovesti do velike promjene izlazne vrijednosti zbog funkcije postupnog aktiviranja. U ovom slučaju, blagi pad ulazne vrijednosti može dovesti do činjenice da interna vrijednost neće preći postavljenu granicu i neuron se neće aktivirati, što će dovesti do još značajnijih promjena u stanju neurona koji ga prate. . Srećom, ovaj problem se lako rješava pomoću funkcije za glatku aktivaciju koja se nalazi na većini modernih mreža.

    Međutim, naša neuronska mreža će biti toliko jednostavna da su perceptroni sasvim prikladni za njeno stvaranje. Napravit ćemo mrežu koja izvodi logičku operaciju I. To znači da će nam trebati dva ulazna neurona i jedan izlazni neuron, kao i nekoliko neurona u srednjem "skrivenom" sloju. Ilustracija ispod prikazuje arhitekturu ove mreže, koja bi trebala biti prilično očigledna.

    Monier i Renard su koristili convnet.js skriptu da kreiraju demo mreže za svoj razgovor. Convnet.js se može koristiti za kreiranje neuronskih mreža direktno u vašem web pretraživaču, omogućavajući vam da ih istražujete i modificirate na gotovo bilo kojoj platformi. Naravno, ova implementacija u JavaScript-u takođe ima značajne nedostatke, od kojih je jedna mala brzina. Pa, za potrebe ovog članka koristit ćemo biblioteku FANN (Fast Artifical Neural Networks). U ovom slučaju će se na nivou programskog jezika Python koristiti modul pyfann koji sadrži veze za FANN biblioteku. Trebali biste odmah instalirati softverski paket sa ovim modulom.

    Uvoz modula za rad sa FANN bibliotekom izvodi se na sljedeći način:

    >>> iz pyfann import libfann

    Sada možemo početi! Prva operacija koju ćemo morati izvesti je stvaranje prazne neuronske mreže.

    >>> neural_net = libfann.neural_network()

    Kreirani neural_net objekat trenutno ne sadrži neurone, pa hajde da pokušamo da ih kreiramo. U tu svrhu koristit ćemo funkciju libfann.create_standard_array(). Funkcija create_standard_array() kreira neuronsku mrežu u kojoj su svi neuroni povezani sa neuronima iz susjednih slojeva, tako da se može nazvati "potpuno povezana" mreža. Funkcija create_standard_array() uzima niz sa numeričke vrijednosti, što odgovara broju neurona na svakom nivou. U našem slučaju ovo je niz.

    >>> neural_net.create_standard((2, 4, 1))

    Nakon toga ćemo morati postaviti vrijednost stope učenja. Ova vrijednost odgovara broju promjena težine unutar jedne iteracije. Ugradićemo dovoljno velika brzina trening jednak 0,7, jer ćemo rješavati prilično jednostavan problem koristeći našu mrežu.

    >>> neural_net.set_learning_rate(0.7)

    Sada je vrijeme da instalirate funkciju aktivacije, čija je svrha gore spomenuta. Koristićemo način aktiviranja SIGMOID_SYMMETRIC_STEPWISE, koji odgovara hiperboličnoj funkciji koraka tangente. Manje je precizan i brži od normalna funkcija hiperbolička tangenta i savršena je za naš zadatak.

    >>> neural_net.set_activation_function_output(libfann.SIGMOID_SYMMETRIC_STEPWISE)

    Konačno, trebamo pokrenuti algoritam mrežne obuke i sačuvati mrežne podatke u datoteku. Funkcija mrežnog treninga uzima četiri argumenta: ime datoteke sa podacima o kojoj će se obuka izvoditi, maksimalni iznos pokušava pokrenuti algoritam učenja, broj operacija učenja prije iznošenja podataka o stanju mreže i stopu greške.

    >>> neural_network.train_on_file("and.data", 10000, 1000, .00001) >>> neural_network.save("and.net")

    Datoteka "and.data" treba da sadrži sljedeće podatke:

    4 2 1 -1 -1 -1 -1 1 -1 1 -1 -1 1 1 1

    Prvi red sadrži tri vrijednosti: broj primjera u datoteci, broj ulaznih vrijednosti i broj izlaznih vrijednosti. Ispod su primjeri linija, gdje linije sa dvije vrijednosti sadrže ulazne vrijednosti, a linije s jednom vrijednošću pokazuju izlazne vrijednosti.

    Uspješno ste završili mrežnu obuku i sada želite da je isprobate, zar ne? Ali prvo ćemo morati učitati mrežne podatke iz datoteke u kojoj su ranije spremljeni.

    >>> neural_net = libfann.neural_net() >>> neural_net.create_from_file("and.net")

    Nakon toga možemo ga jednostavno aktivirati isti put:

    >>> print neural_net.run()

    Rezultat bi trebao biti [-1.0] ili slična vrijednost, ovisno o mrežnim podacima generiranim tokom procesa obuke.

    Čestitamo! Upravo ste naučili svoj računar kako da izvodi osnovne logičke operacije!

    Najbolji članci na ovu temu