此系列文章主要为记录作业过程,也为卡在某处提供些许思路,所以还是建议独立完成,这样对知识的理解最为深刻。
ex4是神经网络算法的基本实现,还是有一定难度的。加油!
nnCostFunction-Part 1:
首先需要根据给定的参数,使用前向算法,计算出成本函数。我使用了for循环,每次循环计算一种分类(1…m)的成本,求和之后除以m,再加上偏移量,同样注意对第一个参数不需要偏移。
for i = 1:m
h = sigmoid(Theta2 * [ones(1); sigmoid(Theta1 * [ones(1); X(i,:)'])]);
tmpy = zeros(num_labels, 1);
tmpy(y(i)) = 1;
tmpJ = -(tmpy' * log(h)) -(1 - tmpy)' * log(1 - h);
J = J + tmpJ;
endfor
J = J / m;
J = J + lambda / 2 / m * (sum((sum(Theta1(:,2:end) .* Theta1(:,2:end))))' + sum((sum(Theta2(:,2:end) .* Theta2(:,2:end)))'));
sigmoidGradient
这个不难,直接套公式即可:
g = 1 ./ (1 + e .^ (-z));
g = g .* (1 - g);
randInitializeWeights
这部分的答案已经给出了,但是还是要认真读一下比较好。
###### nnCostFunction-Part 2:
这部分需要实现后向传播算法。也是试用for循环累加的方法,需要注意的是,在适当的地方使用移除第一个元素(参考偏移量的处理):
% 计算partial derivatives
deltaCap2 = zeros(num_labels, hidden_layer_size + 1);
deltaCap1 = zeros(hidden_layer_size, input_layer_size + 1);
for i = 1:m
% feedforward
a1 = [1; X(i,:)'];
z2 = Theta1 * a1;
a2 = [1; sigmoid(z2)];
z3 = Theta2 * a2;
a3 = sigmoid(z3);
% y
tmpy = zeros(num_labels, 1);
tmpy(y(i)) = 1;
% delta
delt3 = a3 - tmpy;
delt2 = Theta2' * delt3 .* sigmoidGradient([1; z2]);
% deltaCaps
deltaCap2 = deltaCap2 + delt3 * (a2)';
deltaCap1 = deltaCap1 + delt2(2:end) * (a1)';
endfor
###### nnCostFunction-Part 3:
正规化,加入正规化参数即可:
Theta1_grad = deltaCap1 / m + lambda * [zeros(hidden_layer_size, 1), Theta1(:,2:end)] / m;
Theta2_grad = deltaCap2 / m + lambda * [zeros(num_labels, 1), Theta2(:, 2:end)] / m;
剩下的工作,作业本身帮助我们完成了。