Zapisz jako PDF
Transkrypt
Zapisz jako PDF
powrót Spis treści 1 Nieliniowość 1.1 Perceptron Rosenblatta 1.1.1 Przykład 1.1.2 Dobieranie wag perceptronu prostego 1.1.2.1 Przykład: Bramka NAND 1.1.3 Uczenie perceptronu 1.1.3.1 Dlaczego ten algorytm działa? 1.1.4 Ograniczenia perceptronu prostego 1.1.5 Nowe możliwości: wielowarstwowe sieci perceptronów prostych Nieliniowość Nowością wprowadzoną przez Perceptron(Rosenblatt 1958) w stosunku do sieci MADALINE, było zastosowanie elementu nieliniowego. W perceptronie wyjście neuronu: Model neuronu z nieliniowością gdzie pobudzenie Pobudzenie neuronu w postaci ważonej sumy wejść nie jest jedynym możliwym, mogą to być np.: lub Dla własności neuronu największe znaczenie ma jednak forma nieliniowości . Perceptron Rosenblatta Najprostsza pojęciowo postać nieliniowości: Nieliniowa funkcja aktywacji w perceptronie Rosenblatta Interpretacja geometryczna: perceptron prosty działa jak dyskryminator liniowy. Obszar, w którym perceptron zwraca 1 — podejmuje decyzję tak jest ograniczony tworem o równaniu: Dla n = 2 jest to prosta, dla n = 3 płaszczyzna, w ogólności rozmaitość liniowa stopnia n − 1 hiperpłaszczyzna. Przykład Rozważmy perceptron z trzema wagami pobudzenie neuronu: Podział przestrzeni wejść na podprzestrzenie odpowiadające klasyfikacji jako "0" bądź "1" We właściwej przestrzeni wejść(tzn. równaniu: ) hiperpowierzchnia podejmowania decyzji jest prostą o Obcięty wektor wag jest prostopadły do prostej podejmowania decyzji. Wektor wag jest skierowany w stronę, gdzie y = 1. Dobieranie wag perceptronu prostego Wagi perceptronu prostego można dobrać na dwa sposoby: możemy obliczyć wagi neuronów lub znaleźć je w procesie iteracyjnego uczenia. Obliczanie Korzystamy z tego, że wektor w jest ortogonalny do hiperpłaszczyzny podejmowania decyzji, zatem musi spełniać równanie: także "obcięty" wektor wag jest ortogonalny do "obciętych" wektorów wejściowych bo: zatem Aby powyższa równość zachodziła musi zachodzić: Przykład: Bramka NAND Obliczmy wagi perceptronu realizującego funkcję logiczną NAND. Jej tabela wartości logicznych jest następująca: 0011 0101 1110 Spójrzmy na reprezentację graficzną: Reprezentacja graficzna funkcji NAND Można zaproponować następującą prostą podejmowania decyzji: wektor wag jest prostopadły do tej prostej i skierowany w stronę gdzie , więc: i wybieramy . Ostatecznie Uczenie perceptronu Algorytm uczenia perceptronu jest formalnie bardzo podobny do algorytmu spadku gradientowego. Mamy ciąg uczący: Ilustracja zmiany wag perceptronu zgodnie z regułą "delta" i regułę zmiany wag po zaprezentowaniu j-tego przykładu (reguła ta nazywana jest "regułą delta"): gdzie jest błędem perceptronu dla j-tego przykładu: Istotną różnicę stanowi fakt, że: , a co za tym idzie błąd może przyjmować tylko wartości dyskretne: Dlaczego ten algorytm działa? Ponieważ wejścia i wyjścia mogą przyjmować tylko kilka wartości możemy prześledzić wszystkie przypadki. Są tylko 4 możliwości zmiany wag: wkład do pobudzenia od i-tej współrzędnej po korekcie wag 0 0 0 (dobrze) 0 bez zmian 1 1 0 (dobrze) 0 bez zmian 0 1 -1 (odpowiedź za duża) 1 0 1 (odpowiedź za mała) Widać, że zawsze zmiana wagi (o ile nie jest zbyt duża) prowadzi w taką stronę aby po ponownym podaniu tego samego przykładu odpowiedź była bliższa pożądanej. Kod symulujący przykładowy perceptron prosty # -*- coding: utf-8 -*import numpy as np import pylab as py import matplotlib.animation as animation class Perceptron(object): """Perceptron Rosenblatta""" def __init__(self, w, w0): self.w = np.array(w) self.w0 = np.array(w0) self.first_plot = True def ucz(self, X, Z, eta): delta = Z - self.licz(X) self.w += eta*delta*X self.w0 += eta*delta return delta def licz(self, X): e = np.sum(self.w*X) + self.w0 if e >= : y = 1 else: y= return y def rysuj(data): linia.set_ydata(data) return linia, def licz_wynik(): global p, x, X, Z delta=1 y = np.zeros(len(x)) #while delta > 0: delta = for j in range(len(X)): d = p.ucz( X[j,:], Z[j], eta) # uczymy neuron j-tego elementu w ciagu uczacym delta += np.abs(d) # sumujemy wartosci bezwzgledne bladow y[] = (-p.w[]*x[] - p.w0) / p.w[1] y[1] = (-p.w[]*x[1] - p.w0) / p.w[1] print 'zla klasyfikacja ' +str(delta) +' na '+ str(len(Z)) + ' punktow ' yield y p = Perceptron(w = [0.1, 0.6], w0 = -0.4 ) eta=0.1 X=np.array([[1, 1], [3, 3],[4,1],[2, 3], [3, 4], [1.2, 3.2]]) Z=np.array([1, 1,1, , , , ]) xmin=-5 xmax=5 red = np.where( Z> ) blue = np.where( Z<=) fig1 = py.figure(1) py.plot(X[blue,], X[blue,1],'bo' , X[red, ], X[red,1] ,'ro') py.xlim([xmin-2, xmax+2]) py.ylim([-2,5+2]) x = np.array([xmin, xmax]) y = (-p.w[]*x - p.w0) / p.w[1] linia, = py.plot(x,y) line_ani = animation.FuncAnimation(fig1, rysuj, licz_wynik, blit=True,repeat=False) interval=100)#, py.show() Ograniczenia perceptronu prostego Ograniczeniem perceptronu prostego jest fakt, że za jego pomocą można rozwiązać tylko problemy separowalne liniowo. Co to oznacza zobaczmy na poniższym przykładzie: Ilustracja problemu, który jest (AND) i nie jest (XOR) separowalny liniowo Nowe możliwości: wielowarstwowe sieci perceptronów prostych Co dwie warstwy neuronów nieliniowych to nie jedna :-) Jedna warstwa perceptronów prostych na swoim wyjściu prezentuje zestaw podziałów przestrzeni hiperpłaszczyznami - każdy neuron jeden podział. Co się stanie jeśli wyjście tej warstwy wpuścimy na wejście następnej warstwy? Przykładowe rozwiązanie problemu XOR przez dwie warstwy perceptronów prostych Problem znalezienia wag w ogólności nie jest tu prosty. Dla XOR można go zapisać następująco: