Costfunction代价函数:
在前面的课程总我们了解了逻辑回归的代价函数:
在神经网络中,我们增加了对k个输出的误差进行了求和。得到代价函数如下:
K为输出的个数,在正则项中L表示神经网络的层数
Backpropagation algorithm反向传播算法:
当我们进行梯度下降算法的时候,便要计算J的偏导数。在神经网络中最后造成误差结果不单是由最后一层导致的。因此,需要对中间层的误差进行计算当。我们计算某一层的误差时,通过链式法则我们便要对后面的层的偏导进行计算。我们可以通过反向传播算法来计算这些偏导数。
其中delta为误差g'(z)可以化简为g(z)*(1-g(z))
其中a表示计算所得的值,a为正向传播。delta为第l层,第i个值对第j个下一个单元的误差值,从最后一层反向传播。
Gradient checking(梯度检验):
在行经梯度下降的时候常会有各种bug,有时候虽然代价函数的值在下降但实际上还有有很大的误差可能是由小bug导致的。我们可以使用梯度检验对其进行检测,保证产生模型的质量。
可以使用J(theta+ε)-J(theta-ε)/ε来检验J(theta)的导数
n为theta的数量,从theta的第一项开始,将thetaPlus赋值为theta+epsilon,thetaMinus赋值为theta-epsilon。gradApprox表示第i项上检测的偏导值。
Random initialization:
总结:
神经网络的输入输出中间层的参数选择:确定的特征集决定了输入的单元数量X的维度,分类的个数决定输出层的维度。
理论上来说隐藏层单元个数越多越好,中间层的单元个数一般与输入层的维度相匹配(相同或者二三四倍)。
编程作业:
编程作业的主要任务是写出神经网络的代价函数,然后通过反向传播算法进行梯度下降,最后是进行正则化。
nncostfunction:
function [J grad] = nnCostFunction(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));
% Setup some useful variables
m = size(X, 1);
% You need to return the following variables correctly
J = 0;
Theta1_grad = zeros(size(Theta1));
Theta2_grad = zeros(size(Theta2));
X = [ones(m, 1) X];
ylabel = zeros(num_labels, m);
for i=1:m
ylabel(y(i), i) = 1;
end
z2 = X*Theta1';
z2 = [ones(m, 1) z2];
a2 = sigmoid(X*Theta1');
a2 = [ones(m, 1) a2];
a3 = sigmoid(a2*Theta2');
for i=1:m
J=J-log( a3 (i,:) ) * ylabel(:,i)-log( 1-a3(i,:) )*(1-ylabel(:,i));
end
J=J/m;
J=J+lambda/(2*m)*(sum(sum(Theta1(:,2:end).^2))+sum(sum(Theta2(:,2).^2)));
Delta1 = zeros(size(Theta1));
Delta2 = zeros(size(Theta2));
for t=1:m
delta3=a3(t,:)'-ylabel(:,t);
delta2=Theta2'*delta3.*sigmoidGradient(z2(t,:)');
Delta1=Delta1+delta2(2:end)*X(t,:);
Deltal=Delta2+delta3*a2(t,:);
end
Theta1_grad = Delta1 /m;
Theta1_grad(:,2:end)=Theta1_grad(:,2:end)+lambda/m*Theta1(:,2:end);
Theta2_grad=Delta2 /m;
Theta2_grad(:,2:end)=Theta2_grad(:,2:end)+lambda/m*Theta2(:,2:end);
% -------------------------------------------------------------
% =========================================================================
% Unroll gradients
grad = [Theta1_grad(:) ; Theta2_grad(:)];
end
sigmoidgradient:用来计算g(z)*(1-g(z))
function g = sigmoidGradient(z)
%SIGMOIDGRADIENT returns the gradient of the sigmoid function
%evaluated at z
g = zeros(size(z));
g=sigmoid(z).*(1-sigmoid(z));
end
randinitalizeweight:生成随机初始theta
function W = randInitializeWeights(L_in, L_out)
W = zeros(L_out, 1 + L_in);
epsilon_init = 1;
W = rand(L_out, 1 + L_in) * 2 * epsilon_init - epsilon_init;
end