2013-05-02 22 views
5

Uczę się o sieciach neuronowych, szczególnie patrząc na MLP z wdrożeniem propagacji wstecznej. Próbuję zaimplementować własną sieć w Pythonie i pomyślałem, że zanim zacznę, zajrzę do innych bibliotek. Po kilku poszukiwaniach znalazłem implementację Pythona Neila Schemenauera bpnn.py. (http://arctrix.com/nas/python/bpnn.py)Backpropagation sieci neuronowej Pythona

Pracując przez kod i czytać pierwszą część Christopher M. Bishop książce zatytułowanej „Sieci neuronowe Pattern Recognition” Znalazłem problem w funkcji backPropagate:

# calculate error terms for output 
output_deltas = [0.0] * self.no 
for k in range(self.no): 
    error = targets[k]-self.ao[k] 
    output_deltas[k] = dsigmoid(self.ao[k]) * error 

Linia kod, który oblicza błąd, jest inny w książce Bishops. Na stronie 145, równanie 4.41 definiuje błąd urządzenia wyjściowe jak:

d_k = y_k - t_k 

Gdzie y_k są wyjścia i t_k są cele. (Używam _ reprezentuje indeks) Więc moje pytanie brzmi powinien ten wiersz kodu:

error = targets[k]-self.ao[k] 

Bądź rzeczywiście:

error = self.ao[k] - targets[k] 

jestem najprawdopodobniej całkowicie błędne, ale może ktoś pomóc jasne moje zamieszanie proszę. Dzięki

+0

Ponieważ błąd jest taki, jak wynik w tej epoce jest oddalony od oczekiwanego, powinna to być właściwa linia: 'error = targets [k] -self.ao [k]' Ale oba mogą być prawidłowe, zależy to również od sygnału 'dsigmoid (self.ao [k])'. –

+0

Bez względu na to, czy wywodzisz (y-t)^2, czy (t-y)^2 w stosunku do y, nie ma różnicy, zawsze jest to y-t, nigdy t-y. – alfa

Odpowiedz

2

Wszystko zależy od używanej miary błędu. Aby podać tylko kilka przykładów działań błąd (dla uproszczenia będę używać ys oznaczać wektor n wyjść i ts oznaczać wektor n celów):

mean squared error (MSE): 
    sum((y - t) ** 2 for (y, t) in zip(ys, ts))/n 

mean absolute error (MAE): 
    sum(abs(y - t) for (y, t) in zip(ys, ts))/n 

mean logistic error (MLE): 
    sum(-log(y) * t - log(1 - y) * (1 - t) for (y, t) in zip(ys, ts))/n 

który z nich korzystać zależy wyłącznie od kontekst. MSE i MAE mogą być użyte, gdy docelowe wyniki mogą przyjmować dowolne wartości, a MLE daje bardzo dobre wyniki, gdy docelowymi wyjściami są 0 lub 1, a gdy y jest w otwartym zakresie (0, 1).

Po tym stwierdzeniu nie widziałem wcześniej używanych błędów (y - t lub t - y) (sam nie jestem bardzo doświadczony w uczeniu maszynowym). O ile widzę, podany kod źródłowy nie zmienia różnicy lub nie używa wartości bezwzględnej, czy na pewno książka też nie? Ja widzę to y - t lub t - y nie może być bardzo dobre środki błędach i oto dlaczego:

n = 2     # We only have two output neurons 
ts = [ 0, 1 ]   # Our target outputs 
ys = [ 0.999, 0.001 ] # Our sigmoid outputs 

# Notice that your outputs are the exact opposite of what you want them to be. 
# Yet, if you use (y - t) or (t - y) to measure your error for each neuron and 
# then sum up to get the total error of the network, you get 0. 
t_minus_y = (0 - 0.999) + (1 - 0.001) 
y_minus_t = (0.999 - 0) + (0.001 - 1) 

Edit: Per alfa's comment, w książce, y - t jest właściwie pochodną MSE. W takim przypadku t - y jest niepoprawny. Należy jednak zauważyć, że rzeczywistą pochodną MSE jest 2 * (y - t)/n, a nie tylko y - t.

Jeśli nie podzielisz przez n (więc faktycznie masz błąd zsumowanego kwadratu (SSE), a nie błąd średniej kwadratowej), wówczas pochodną będzie 2 * (y - t). Ponadto, jeśli używasz SSE/2 jako miary błędu, wtedy 1/2 i 2 w pochodnej znoszą się i pozostaje Ci y - t.

+1

Problem polega na tym, że do uzyskania backpropagacji potrzebny jest y-t (zobacz np. Https://github.com/OpenANN/OpenANN/blob/master/src/Net.cpp, wiersz 323). Nie jest miarą błędu, jest pochodną (średniej) sumy kwadratów błędów. I powinno to mieć wpływ na to, czy jest to y-t, czy t-y. – alfa

+0

Ohh, rozumiem, byłem zdezorientowany. –

+0

@alfa Mówisz w bpnn.py, że obecna implementacja jest niepoprawna? – FidesFacitFidem

0

pan do backpropagate pochodną

0,5 * (YT)^2 lub 0,5 * (TY)^2, w odniesieniu do Y

która jest zawsze

yt = (yt) (+1) = (ty) (-1)

0

W rzeczywistym kodzie, często obliczyć NEGATYWNĄ Grad (straty w odniesieniu do wag) i używać w + = eta * grad zaktualizować wagi. W rzeczywistości jest to stopniowanie.

W niektórych podręcznikach wyliczono POZYTYWNY grad i w - = eta * grad, aby zaktualizować wagę.

Powiązane problemy