2012-11-06 40 views
6

Tôi đang cố gắng thực hiện một hồi quy NN có 3 lớp (1 đầu vào, 1 lớp ẩn và 1 đầu ra với kết quả liên tục). Là một cơ sở Tôi lấy một phân NN từ coursera.org lớp, nhưng đã thay đổi hàm chi phí và tính toán độ dốc để phù hợp với một vấn đề hồi quy (và không phải là một phân loại một):Gradient trong hồi quy liên tục sử dụng mạng nơron

nnCostFunction của tôi bây giờ là:

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 

Sau đó, tôi sử dụng func này trong fmincg thuật toán, nhưng trong lần đầu tiên lặp lại fmincg kết thúc công việc của nó. Tôi nghĩ rằng gradient của tôi là sai, nhưng tôi không thể tìm thấy lỗi.

Ai đó có thể trợ giúp?

+0

Xin chào Mikhail, đó là câu hỏi hơn 1 năm trước, nhưng tôi đã tự hỏi liệu bạn đã giải quyết được vấn đề này chưa? Trên thực tế một anh chàng khác hỏi cùng một, và tôi đã cung cấp mã của tôi ở đó, so với checkNNGradients của Andrew Ng (lambda) và thu được sự khác biệt tương đối 1e-4: http://stackoverflow.com/questions/20648422/neural-networks-sigmoid- kích hoạt-chức năng-cho-liên tục-đầu ra-biến/20650561 # 20650561 Nếu bạn đã giải quyết vấn đề này và thậm chí còn có sự khác biệt tương đối ít hơn, xin vui lòng cập nhật bằng cách trả lời câu hỏi của riêng bạn; nếu không hy vọng mã của tôi là hữu ích. Cảm ơn – lennon310

+0

ngôn ngữ đó là gì ?? nó là * không * octave/matlab (đó là điều mà Giáo sư Ng đã dạy ..) – javadba

+0

@javadba, nó là octave –

Trả lời

1

Nếu tôi hiểu đúng, khối đầu tiên của mã (hình dưới đây) -

m = size(X, 1); 

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

là để có được sản lượng một (3) tại lớp đầu ra.

Trang trình bày của Ng về NN có cấu hình bên dưới để tính (3). Nó khác với mã của bạn.

  • ở lớp giữa/đầu ra, bạn không thực hiện chức năng kích hoạt g, ví dụ: chức năng sigmoid.

enter image description here

Xét về mặt chức năng chi phí J mà không cần điều kiện quy tắc, slide Ng vừa thể hiện công thức dưới đây:

enter image description here

Tôi không hiểu lý do tại sao bạn có thể tính toán nó sử dụng:

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

vì bạn là không bao gồm chức năng log.

+0

log() và sigmoid() - cách tiếp cận của hồi quy logic NN. Trong ví dụ coursera nó phát hiện ung thư, nhưng tôi muốn dự đoán chi phí nhà –

1

Mikhaill, tôi đã từng chơi với một NN để hồi quy liên tục, và có một số vấn đề tương tự tại một số điểm. Điều tốt nhất để làm ở đây là kiểm tra tính toán gradient so với phép tính số trước khi chạy mô hình. Nếu điều đó không đúng, fmincg sẽ không thể đào tạo mô hình. (Btw, tôi không khuyến khích bạn sử dụng gradient số khi thời gian tham gia lớn hơn nhiều).

Có tính đến việc bạn lấy ý tưởng này từ lớp Ng´s Coursera, tôi sẽ thực hiện một giải pháp khả thi để bạn thử sử dụng cùng một ký hiệu cho 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(:)]; 

Lưu ý rằng, vì bạn đã loại bỏ tất cả kích hoạt sigmoid, nên việc tính toán phái sinh khá đơn giản và dẫn đến đơn giản hóa mã gốc.

Các bước tiếp theo: 1. Kiểm tra mã này để hiểu xem điều đó có hợp lý với vấn đề của bạn hay không. 2. Sử dụng kiểm tra gradient để kiểm tra phép tính gradient. 3. Cuối cùng, sử dụng fmincg và kiểm tra bạn nhận được kết quả khác nhau.

0

Cố gắng bao gồm hàm sigmoid để tính giá trị lớp thứ hai (lớp ẩn) và tránh sigmoid khi tính toán giá trị đích (đầu ra).

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 

Bình thường hóa các đầu vào trước khi chuyển nó trong nnCostFunction.

Các vấn đề liên quan