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:

Podobne dokumenty