此系列文章主要為記錄作業過程,也為卡在某處提供些許思路,是以還是建議獨立完成,這樣對知識的了解最為深刻。
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;
剩下的工作,作業本身幫助我們完成了。