밑에 찾아 본 생키가 있어서 혹시 그 사이에 형이 업뎃 했는지 기억이 안나고, 마침 주석 똥글이 흥해서 싸줌.
참고로 전반부 주석은 응센세 과제에 원래 있던거거나 형이랑 생각이 달라서 형이 코드를 커맨트로 막아 버림. 주석 백날 봐봐라 코드를 모르면 주석을 봐도 걍 모르는게 이런 류 코드
드
(야 근데 이게 왜 원래 숙제 코드와 다른지 알아본건 아직까지 코세 뿐이여 ㅋㅋ)
function [J grad] = nnCostFunction(nn_params, ...
input_layer_size, ...
hidden_layer_size_vector, ...
num_labels, ...
X, y, lambda)
%% costFnNN Implements the neural network cost function for a two layer
%% neural network which performs classification
%% [J grad] = NNCOSTFUNCTON(nn_params, hidden_layer_size_vector, num_labels, ...
%% X, y, lambda) computes the cost and gradient of the neural network. The
%% parameters for the neural network are "unrolled" into the vector
%% nn_params and need to be converted back into the weight matrices.
%% The returned parameter grad should be a "unrolled" vector of the
%% partial derivatives of the neural network.
m = numel(y);
%% 1. Build Thetas
Thetas = nnThetaCell(nn_params, [input_layer_size hidden_layer_size_vector num_labels]);
%% 2. Set y_matrix
y_matrix = eye(num_labels)(y,:); % permutation over identity matrix of size num_labels!
%% 3. Init configuration
activationLayers = {[ones(m, 1) X]};
Zs = {};
sum_Thetas = 0;
num_theta = numel(Thetas);
num_layers = num_theta + 1;
%% 3. forward propagation
for thetai = 1:num_theta
z = activationLayers{thetai} * Thetas{thetai}';
if num_theta > thetai
activationLayers{thetai + 1} = [ones(m,1) sigmoid(z)];
else
activationLayers{thetai + 1} = sigmoid(z);
end
sum_Thetas = sum_Thetas + sum(sum(Thetas{thetai}(:,2:end) .^ 2));
Zs{thetai + 1} = z;
end
%% 4. backpropagation
error_d = activationLayers{num_layers} - y_matrix;
Deltas = {};
for i = num_layers-1:-1:1
Delta = error_d' * activationLayers{i};
Deltas{i} = Delta;
if i > 1 % Don't process input layer
error_d = error_d * Thetas{i}(:, 2:end) .* sigmoidGradient(Zs{i});
end
end
%% 5. compute J
true_classification = y_matrix .* log(activationLayers{num_layers});
false_classification = (1 - y_matrix) .* log(1 - activationLayers{num_layers});
scaled_sum_Thetas = (lambda * sum_Thetas)/ (2 * m);
J = -1/m * sum(sum(true_classification + false_classification)) + ...
scaled_sum_Thetas;
%% 6. Compute grad
grad = [];
for i = 1:num_theta
Thetas{i}(:, 1) = 0;
Theta_grad = 1/m * (Deltas{i} + lambda * Thetas{i});
grad = [grad; Theta_grad(:)];
end
end
이거 말고 어디 찾아보면 옵티마이즈 버전도 하나 만든거로 기억하는데 그건 코드가 짧고 빠른 대신 생각이 그대로 표현된게 아니라 이해하기 힘듬
님코드 보고 nnThetaCell을 어떻게 깔끔하게 구현할지 고민중이였는데, 다시보니까 [인풋 히든 아웃풋레이어] 다 합쳐서 벡터 하나로 넘겨 주는거였구나 ㅋㅋ 인풋따로 히든따로 아웃풋따로 하려니까 굉장히 지저분해졌었음..