2012-11-06 3 views
6

3 개의 레이어 (1 개의 입력, 1 개의 숨겨진 레이어와 1 개의 출력 레이어가 연속 된 결과)가있는 회귀 NN을 구현하려고합니다.신경망을 사용한 연속 회귀의 기울기

내 nnCostFunction 지금 :

function [J grad] = nnCostFunctionLinear(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); 

a1 = X; 
a1 = [ones(m, 1) a1]; 
a2 = a1 * Theta1'; 
a2 = [ones(m, 1) a2]; 
a3 = a2 * Theta2'; 
Y = y; 

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

th1 = Theta1; 
th1(:,1) = 0; %set bias = 0 in reg. formula 
th2 = Theta2; 
th2(:,1) = 0; 

t1 = th1.^2; 
t2 = th2.^2; 
th = sum(sum(t1)) + sum(sum(t2)); 
th = lambda * th/(2*m); 
J = J + th; %regularization 


del_3 = a3 - Y; 
t1 = del_3'*a2; 
Theta2_grad = 2*(t1)/m + lambda*th2/m; 

t1 = del_3 * Theta2; 
del_2 = t1 .* a2; 
del_2 = del_2(:,2:end); 
t1 = del_2'*a1; 
Theta1_grad = 2*(t1)/m + lambda*th1/m; 

grad = [Theta1_grad(:) ; Theta2_grad(:)]; 
end 
회귀 문제 (그리고 분류 하나)에 맞게 할 수 있도록 기초로서 나는 비용 함수 및 그라데이션 계산을 coursera.org 클래스에서 분류 NN 걸렸지 만 변경

그럼이 함수를 fmincg 알고리즘으로 사용합니다.하지만 처음에는 fmincg 반복 작업을 끝냅니다. 내 그라디언트가 잘못되었다고 생각하지만 오류를 찾을 수 없습니다.

아무도 도와 줄 수 있습니까? 만약 내가 제대로 이해하고

+0

안녕하세요. Mikhail, 1 년 전의 질문 이었지만 아직이 문제를 해결했는지 궁금합니다. 실제로 다른 사람이 같은 것을 물었고 Andrew Ng의 checkNNGradients (lambda)와 비교하여 1e-4 상대 차이를 얻었습니다. http://stackoverflow.com/questions/20648422/neural-networks-sigmoid- 활성화 기능을위한 연속 출력 변수/20650561 # 20650561이 문제를 이미 해결했고 상대적인 차이가 더 적 으면 자신의 질문에 대답하여 업데이트하십시오. 그렇지 않으면 잘하면 내 코드가 도움이됩니다. 감사합니다 – lennon310

+0

어떤 언어입니까? 그것은 옥타브/matlab (교수님이 가르친 것입니다 ..) – javadba

+0

@javadba, 그것은 옥타브 –

답변

1

, 코드의 첫 번째 블록 (아래 그림 참조) -

m = size(X, 1); 

a1 = X; 
a1 = [ones(m, 1) a1]; 
a2 = a1 * Theta1'; 
a2 = [ones(m, 1) a2]; 
a3 = a2 * Theta2'; 
Y = y; 

출력을 얻을 수있는 (3) 출력 계층에서.

Ng에 관한 Ng의 슬라이드는 (3)을 계산하기위한 아래의 구성을가집니다. 그것은 당신의 코드가 제시하는 것과는 다릅니다. 중간/출력 층

  • , 당신은 예컨대 활성화 함수 g 안, sigmoid 기능을 수행하지 않는다. 당신이 사용하여 계산할 수있는 이유

    enter image description here

    가 이해가 안 : 정규화 조건없이 비용 함수 J의 측면에서

enter image description here

는 잉의 슬라이드는 아래의 공식을 가지고 :

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

log 기능을 전혀 포함하지 않습니다.

+0

log() 및 sigmoid() - 논리적 회귀 NN의 접근입니다. coursera 예제에서 그것은 암 탐지지만 집 비용 예측을 원합니다. –

1

Mikhaill, 나는 지속적인 회귀를 위해 NN으로 놀았으며, 어떤 시점에서 비슷한 문제가있었습니다. 여기서 가장 좋은 방법은 모델을 실행하기 전에 수치 계산에 대한 그래디언트 계산을 테스트하는 것입니다. 그게 맞지 않으면 fmincg는 모델을 훈련시킬 수 없게됩니다. (Btw, 나는 관련된 시간이 훨씬 더 길 때 수치 그라디언트를 사용하지 못하게한다.)

Ng의 Coursera 클래스에서이 아이디어를 얻은 점을 감안하여 Octave와 동일한 표기법을 사용해 볼 수있는 가능한 솔루션을 구현하겠습니다. 당신은 모든 시그 모이 드 활성화를 꺼낸 이후, 파생 계산이 원래 코드의 단순화에 아주 간단하고 결과이며,

% Cost function without regularization. 
    J = 1/2/m^2*sum((a3-Y).^2); 

    % In case it´s needed, regularization term is added (i.e. for Training). 
    if (reg==true); 
J=J+lambda/2/m*(sum(sum(Theta1(:,2:end).^2))+sum(sum(Theta2(:,2:end).^2))); 
    endif; 

    % Derivatives are computed for layer 2 and 3. 
    d3=(a3.-Y); 
    d2=d3*Theta2(:,2:end); 

    % Theta grad is computed without regularization. 
    Theta1_grad=(d2'*a1)./m; 
    Theta2_grad=(d3'*a2)./m; 

    % Regularization is added to grad computation. 
    Theta1_grad(:,2:end)=Theta1_grad(:,2:end)+(lambda/m).*Theta1(:,2:end); 
    Theta2_grad(:,2:end)=Theta2_grad(:,2:end)+(lambda/m).*Theta2(:,2:end); 

    % Unroll gradients. 
    grad = [Theta1_grad(:) ; Theta2_grad(:)]; 

참고.

다음 단계 : 1.이 코드를 검사하여 문제가되는지 확인하십시오. 2. 그래디언트 검사를 사용하여 그래디언트 계산을 테스트합니다. 3. 마지막으로 fmincg를 사용하여 다른 결과가 나타나는지 확인하십시오.

0

두 번째 레이어 (숨겨진 레이어) 값을 계산하고 시그널이 목표 (출력) 값을 계산하는 것을 방지하기 위해 시그 모이 드 함수를 포함 시키십시오.

function [J grad] = nnCostFunction1(nnParams, ... 
            inputLayerSize, ... 
            hiddenLayerSize, ... 
            numLabels, ... 
            X, y, lambda) 

Theta1 = reshape(nnParams(1:hiddenLayerSize * (inputLayerSize + 1)), ... 
       hiddenLayerSize, (inputLayerSize + 1)); 

Theta2 = reshape(nnParams((1 + (hiddenLayerSize * (inputLayerSize + 1))):end), ... 
       numLabels, (hiddenLayerSize + 1)); 

Theta1Grad = zeros(size(Theta1)); 
Theta2Grad = zeros(size(Theta2)); 

m = size(X,1); 

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

Y = y'; 

r1 = lambda/(2 * m) * sum(sum(Theta1(:, 2:end) .* Theta1(:, 2:end))); 
r2 = lambda/(2 * m) * sum(sum(Theta2(:, 2:end) .* Theta2(:, 2:end))); 

J = 1/(2 * m) * (a3 - Y) * (a3 - Y)' + r1 + r2; 

delta3 = a3 - Y; 
delta2 = (Theta2' * delta3) .* sigmoidGradient([ones(1, m); z2]); 
delta2 = delta2(2:end, :); 

Theta2Grad = 1/m * (delta3 * a2'); 
Theta2Grad(:, 2:end) = Theta2Grad(:, 2:end) + lambda/m * Theta2(:, 2:end); 
Theta1Grad = 1/m * (delta2 * a1'); 
Theta1Grad(:, 2:end) = Theta1Grad(:, 2:end) + lambda/m * Theta1(:, 2:end); 

grad = [Theta1Grad(:) ; Theta2Grad(:)]; 

end 

nnCostFunction에서 전달하기 전에 입력을 표준화하십시오.