神经网络算法

神经网络 Neural Networks

本文介绍使用前向反馈传播神经网络,并使用该算法来预测手写数字。

代价函数 Cost Function

后向传递 Backpropagation

正则化 Regularization

代码实现

function [J grad] = nnCostFunction(nn_params, ...
                               input_layer_size, ...
                               hidden_layer_size, ...
                               num_labels, ...
                               X, y, lambda)
%NNCOSTFUNCTION 实现了一个输入层,一个隐藏层,一个输出层的分类神经网络代价函数
%   [J grad] = NNCOSTFUNCTON(nn_params, hidden_layer_size, num_labels,  X, y, lambda)
%  神经网络的参数nn_params展成了向量传递,在代码中应该重新转换成权重Theta矩阵�
%  返回的参数grad 应是展成向量的神经网络偏导值
%

% 重塑Theta1, Theta2
% for our 2 layer neural network
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));

% ====================== 自己需要完成的代码 ======================
a1 = X;
z2 = [ones(size(a1,1),1) a1]*Theta1';  % 5000训练集,对于同一个训练集运行相同的计算
a2 = sigmoid(z2);
z3 = [ones(size(a2,1),1) a2]*Theta2';
a3 = sigmoid(z3);
h = a3;
yNew = zeros(m,size(Theta2,1)); %需要把真实值转换成对应十个分类结果的矩阵 y = [0,0,...,0,1,0,...,0]

for i = 1:m
    yNew(i,y(i))=1;
end
y = yNew;

% 代价函数
J = (y.*log(h)+(1-y).*log(1-h)/(-m);

%正则化
Theta1(:,1)=0;%正则化一般不包含第一项
Theta2(:,1)=0;
regularization = (sum(sum(Theta1.*Theta1)) + sum(sum(Theta2.*Theta2)))*(lambda/(2*m));
  
%正则化后的代价函数
J = sum(sum(J))+regularization;

%%%%%% 
delta1 = 0;
delta2 = 0;
%使用for循环实现,速度慢很多
%for i = 1:m
%  sigma3 = a3(i,:) - y(i,:);
%  sigma2 = (sigma3*Theta2)(1,2:end).*sigmoidGradient(z2(i,:));
%  
%  delta2 += (sigma3'.*a2(i,:))';
%  delta1 += (sigma2'*a1(i,:))';
%end

%使用向量化来实现
sigma3 = a3 - y;
sigma2 = (sigma3*Theta2)(:,2:end).*sigmoidGradient(z2);  

delta2 = sigma3'*[ones(m,1) a2];%记得补充哇!
delta1 = sigma2'*[ones(m,1) a1];%记得补充哇!

%梯度
Theta1_grad = 1/m .* delta1;
Theta2_grad = 1/m .* delta2; 

%正则化后的梯度
Theta1_grad += lambda /m *Theta1;
Theta2_grad += lambda /m *Theta2;


% -------------------------------------------------------------

% =========================================================================

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



end

你可能感兴趣的:(神经网络算法)