5

Wdrażam sieć neuronową i chciałem użyć ReLU jako funkcji aktywacji neuronów. Ponadto ćwiczę sieć z SDG i propagacją wsteczną. Testuję sieć neuronową z paradygmatycznym problemem XOR i do tej pory poprawnie klasyfikuje nowe próbki, jeśli używam funkcji logistycznej lub stycznej hiperbolicznej jako funkcji aktywacyjnych.Uwagi dotyczące używania ReLU jako funkcji aktywacji

Czytałem o zaletach korzystania z nieszczelnego Relu jako funkcji aktywacji, i wprowadziły go w Pythonie, tak:

def relu(data, epsilon=0.1): 
    return np.maximum(epsilon * data, data) 

gdzie np to nazwa NumPy. Powiązana pochodna jest zaimplementowana w następujący sposób:

def relu_prime(data, epsilon=0.1): 
    if 1. * np.all(epsilon < data): 
     return 1 
    return epsilon 

Używając tej funkcji jako aktywacji, otrzymuję niepoprawne wyniki. Np

  • wejściowa = [0, 0] -> wyjściowy = [0,43951457]

  • wejściowa = [0, 1], -> wyjściowy = [0,46252925]

  • wejście = [1, 0] -> wyjściowy = [0,34939594]

  • wejściowy [1, 1] -> wyjściowy = [0,37241062]

Można zauważyć, że wyjścia różnią się znacznie od oczekiwanych XOR. Tak więc pytanie brzmi, czy jest jakaś szczególna uwaga, aby użyć ReLU jako funkcji aktywacyjnej?

Proszę, nie wahaj się prosić mnie o więcej kontekstu lub kodu. Z góry dziękuję.

EDYCJA: Występuje błąd w pochodnej, ponieważ zwraca tylko jedną wartość zmiennoprzecinkową, a nie tablicę NumPy. Poprawny kod powinien być:

def relu_prime(data, epsilon=0.1): 
    gradients = 1. * (data > epsilon) 
    gradients[gradients == 0] = epsilon 
    return gradients 
+0

czy to działa po zmodyfikowaniu części obliczeniowej gradientu? –

+0

@KrishnaKishoreAndhavarapu Po modyfikacji otrzymuję poprawne wyniki, ale jak 5 na 10 razy. Uważam, że za każdym razem powinienem uzyskać poprawne wyniki. Jest wyraźnie coś, czego mi brakuje w tej funkcji aktywacji. – tulians

+0

Czy jesteś pewien, że 'gradienty = 1. * (dane> epsilon) mają sens? Jaka jest twoja definicja nieszczelnej funkcji ReLU? Ustawiłoby to gradient równy epsilon dla niektórych wartości danych, które są większe od zera. –

Odpowiedz

6

Twoja funkcja relu_prime powinno być:

def relu_prime(data, epsilon=0.1): 
    gradients = 1. * (data > 0) 
    gradients[gradients == 0] = epsilon 
    return gradients 

Uwaga porównanie każdej wartości w macierzy danych na 0, zamiast epsilon. Wynika to ze standardowej definicji leaky ReLUs, która w innym przypadku tworzy fragmentaryczny gradient 1.

Nie mogę skomentować, czy nieszczelne ReLU są najlepszym wyborem dla problemu XOR, ale powinno to rozwiązać problem z gradientem.

+0

Teraz otrzymuję poprawne wyniki przez większość czasu. Wraz z tym, co odpowiedział @AnishiShaykh i twoje, dowiedziałem się, że wybór funkcji aktywacji zależy od wartości danych. – tulians

6

Krótka odpowiedź

Nie używaj Relu z cyfr binarnych. Jest przeznaczony do pracy z dużo większymi wartościami. Należy także unikać używania go, gdy nie ma wartości ujemnych, ponieważ będzie to w zasadzie oznaczać, że używasz liniowej funkcji aktywacji, która nie jest najlepsza. Najlepiej używać z Convolutional Neural Networks.

Długa odpowiedź

nie mogę powiedzieć, czy jest coś nie tak z kodem Pythona bo kodu w Javie. Ale logicznie rzecz biorąc, myślę, że używanie ReLU w tym przypadku jest złą decyzją. Ponieważ przewidujemy XOR, istnieje ograniczony zakres wartości NN [0,1]. Jest to również zakres aktywacji sigmoidalnej. Z ReLU operujesz z wartościami [0, nieskończoność], co oznacza, że ​​istnieje bardzo dużo wartości, których nigdy nie użyjesz, ponieważ jest to XOR. Ale ReLU nadal będzie brać pod uwagę te wartości, a błąd, który otrzymasz, wzrośnie. Właśnie dlatego otrzymujesz prawidłowe odpowiedzi w 50% przypadków. W rzeczywistości ta wartość może wynosić zaledwie 0% i aż 99%. Morał historii - przy podejmowaniu decyzji, której funkcji aktywacji użyć, należy dopasować zakres wartości wejściowych w NN do zakresu wartości funkcji aktywacji.

+0

Dzięki za wskazanie tego faktu. Nie myślałem o tym. Ma całkowity sens. – tulians

+0

Cieszę się, że było pomocne. –

Powiązane problemy