2013-12-18 15 views
5

Ok, więc jestem w środku Andrew Ng's machine learning course on coursera i chcieliby dostosować sieć neuronową, która została zakończona w ramach cesji 4.Sieci neuronowe: Funkcja Sigmoid Aktywacja do ciągłej wyjściowej zmiennej

W szczególności sieć neuronowa które zakończyły prawidłowo jako część zadania następująco:

  • funkcji aktywacji Sigmoid: g(z) = 1/(1+e^(-z))
  • 10 urządzenia wyjściowe, z których każdy może się 0 lub 1
  • 1 hi dden warstwa
  • metoda wstecznej propagacji stosowane w celu minimalizacji funkcji kosztu
  • funkcja
  • Koszt:

-1/m sum^m_{i=1} sum^K_{k=1} (y_k_{(i)}) log((h_theta(x^{(i)}_k) + (1-y_k^{(i)}) log(1-h_theta(x^{(i)}_k) + lambda/(2*m)(sum_{l=1}^{L-1}sum_{i=1}^{s_l} sum_{j=1}^{s_{l=1}} (Theta_{ji}^{(l)})^{2}

gdzie L=number of layers, s_l = number of units in layer l, m = number of training examples, K = number of output units

Teraz chcę, aby dostosować ćwiczenia tak, że istnieje jedna ciągła jednostka wyjściowa, która przyjmuje dowolną wartość między [0,1] a próbuję ustalić, co należy zmienić, tak aby ar Mam

  • Zastępuje dane z własną, czyli takie, które wyjście jest zmienną ciągłą pomiędzy 0 a 1
  • Zaktualizowane odniesienia do liczby jednostek wyjściowych
  • Poprawiono funkcję kosztów w plecy - algorytm repropagacji do: J=1/(2m) * sum^m_{i=1} (g(a_3)-y)^2 + lambda/(2*m)(sum_{l=1}^{L-1}sum_{i=1}^{s_l} sum_{j=1}^{s_{l=1}} (Theta_{ji}^{(l)})^{2} gdzie a_3 jest wartością jednostki wynikowej określonej na podstawie propagacji do przodu.

Jestem pewien, że coś innego musi się zmienić, ponieważ metoda sprawdzania gradientu pokazuje gradient określony przez propagację wsteczną i że przez aproksymację numeryczną już nie pasuje. Nie zmieniłem gradientu esicy; pozostaje f(z)*(1-f(z)), gdzie f(z) jest funkcją sigmoidową 1/(1+e^(-z))), ani też nie zaktualizowałem numerycznego przybliżenia formuły pochodnej; po prostu (J(theta+e) - J(theta-e))/(2e).

Czy ktoś może doradzić, jakie inne czynności byłyby wymagane?

kodowane w Matlab następująco:

% FORWARD PROPAGATION 
% input layer 
a1 = [ones(m,1),X]; 
% hidden layer 
z2 = a1*Theta1'; 
a2 = sigmoid(z2); 
a2 = [ones(m,1),a2]; 
% output layer 
z3 = a2*Theta2'; 
a3 = sigmoid(z3); 

% BACKWARD PROPAGATION 
delta3 = a3 - y; 
delta2 = delta3*Theta2(:,2:end).*sigmoidGradient(z2); 
Theta1_grad = (delta2'*a1)/m; 
Theta2_grad = (delta3'*a2)/m; 

% COST FUNCTION 
J = 1/(2 * m) * sum((a3-y).^2); 

% Implement regularization with the cost function and gradients. 
Theta1_grad(:,2:end) = Theta1_grad(:,2:end) + Theta1(:,2:end)*lambda/m; 
Theta2_grad(:,2:end) = Theta2_grad(:,2:end) + Theta2(:,2:end)*lambda/m; 
J = J + lambda/(2*m)*(sum(sum(Theta1(:,2:end).^2)) + sum(sum(Theta2(:,2:end).^2))); 

mam ponieważ zrozumiał, że kwestia ta jest podobna do tej poproszony przez @Mikhail Erofeev on StackOverflow, jednak w tym przypadku życzę zmienna ciągła się między 0 a 1, a zatem używać funkcja sigmoidalna.

+0

Czy sprawiłeś, że zadziałał, aby uzyskać ciągły wynik? Zrobiłem to uruchomić, ale zatrzymuje się około 40. iteracji i nie daje dobrego wyniku. Byłoby wspaniale, gdybyś mógł podzielić się tym, co otrzymałeś? –

Odpowiedz

1

Po pierwsze, funkcja kosztu powinno być:

J = 1/m * sum((a3-y).^2); 

Myślę, że Theta2_grad = (delta3'*a2)/m; oczekuje się, aby dopasować się do zbliżenia numeryczną po zmieniona na delta3 = 1/2 * (a3 - y);).

Sprawdź to slide, aby uzyskać więcej informacji.

EDIT: W przypadku istnieją pewne drobne rozbieżności między naszymi kodami, ja wklejony mój kod poniżej w celach informacyjnych. Kod został już w porównaniu z funkcji numerycznej aproksymacji checkNNGradients(lambda);, różnica względna jest mniejsza niż 1e-4 (nie spełnia wymogu 1e-11 przez Dr.Andrew Ng chociaż)

function [J grad] = nnCostFunctionRegression(nn_params, ... 
            input_layer_size, ... 
            hidden_layer_size, ... 
            num_labels, ... 
            X, y, lambda) 

Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)), ... 
       hidden_layer_size, (input_layer_size + 1)); 

Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), ... 
       num_labels, (hidden_layer_size + 1)); 

m = size(X, 1); 
J = 0; 
Theta1_grad = zeros(size(Theta1)); 
Theta2_grad = zeros(size(Theta2)); 


X = [ones(m, 1) X]; 
z1 = sigmoid(X * Theta1'); 
zs = z1; 
z1 = [ones(m, 1) z1]; 
z2 = z1 * Theta2'; 
ht = sigmoid(z2); 


y_recode = zeros(length(y),num_labels); 
for i=1:length(y) 
    y_recode(i,y(i))=1; 
end  
y = y_recode; 


regularization=lambda/2/m*(sum(sum(Theta1(:,2:end).^2))+sum(sum(Theta2(:,2:end).^2))); 
J=1/(m)*sum(sum((ht - y).^2))+regularization; 
delta_3 = 1/2*(ht - y); 
delta_2 = delta_3 * Theta2(:,2:end) .* sigmoidGradient(X * Theta1'); 

delta_cap2 = delta_3' * z1; 
delta_cap1 = delta_2' * X; 

Theta1_grad = ((1/m) * delta_cap1)+ ((lambda/m) * (Theta1)); 
Theta2_grad = ((1/m) * delta_cap2)+ ((lambda/m) * (Theta2)); 

Theta1_grad(:,1) = Theta1_grad(:,1)-((lambda/m) * (Theta1(:,1))); 
Theta2_grad(:,1) = Theta2_grad(:,1)-((lambda/m) * (Theta2(:,1))); 


grad = [Theta1_grad(:) ; Theta2_grad(:)]; 

end 
+0

Dziękuję za sugestie; Próbowałem aktualizacji delta3 i delta2 zgodnie z sugestią, ale nadal gradienty nie pasują. – user1420372

+0

@ user1420372 Twoja funkcja kosztu powinna być a3-y zamiast sigmoid (a3) ​​-y, zobacz moją aktualizację w odpowiedzi. – lennon310

+0

Dzięki! Właśnie zauważyłem, że - mimo że gradient jest nadal nieprawidłowy - zmodyfikuje odpowiedni kod. – user1420372

0

Jeśli chcesz mieć ciągły dopływ Staraj się nie używać sigmoid aktywacja podczas obliczania wartości docelowej.

a1 = [ones(m, 1) X]; 
a2 = sigmoid(X * Theta1'); 
a2 = [ones(m, 1) z1]; 
a3 = z1 * Theta2'; 
ht = a3; 

Normalizuj wejście przed użyciem go w nnCostFunction. Wszystko inne pozostaje takie samo.

Powiązane problemy