一、前言
????????此时此刻,我正处于第五周课程的复习阶段,刚刚完成了折磨我整整三天的ex4,提交作业成绩:100。
个人认为ex4的难点在于:(1) 矩阵运算的深刻理解????? (2)反向传播算法的细节
所以如果您也正在或即将学习反向传播算法这一part,并且看完一两遍课程发现还是不会写代码,请不用担心,因为很正常!行得通的解决办法就是结合正确答案,反复看课程补全自己对于反向传播算法过程、细节上没能理解到位的地方。这个过程中您将收获对于反向传播算法的细节,矩阵运算的宏观理解,以及一份 “痛,并说不上很快乐” 的回忆。
二、代码部分
sigmoidGradient.m
g = sigmoid(z) .* ( 1 - sigmoid(z) );
randInitializeWeights.m
init_epsilon = 0.02; % 我也不知道该设置多大数量级,所以随便写了一个0.02,
% 感觉这个数量级应该合理
W = rand(L_out , 1 + L_in) * (2 * init_epsilon) - init_epsilon;
nnCostFunction.m
a1 = [ones(size(X,1),1) , X]; %5000 * 401 input layer
z2 = Theta1 * a1'; %25 * 5000
a2 = [ones(size(z2',1),1) , sigmoid(z2')]; %5000 * 26 hidden layer
z3 = Theta2 * a2'; %10 * 5000
a3 = sigmoid(z3); % 10 * 5000 output layer (i.e. h)
h = a3; % h: 10 * 5000 y: 5000 * 1
y_label = zeros(size(h',1) , num_labels); % 5000 * 10
for i = 1:m
y_label(i , y(i)) = 1;
end
% 最终 10 个输出节点
J = (-1/m) * sum(sum((log(h) .* y_label') + log(1 - h) .* (1 - y_label')))...
+(lambda/(2 * m)) * ( sum(sum(Theta1(:,2:end) .^2))+ sum(sum(Theta2(:,2:end) .^2)) );
delta_3 = h' - y_label; % 5000 * 10 output layer (i.e. h)
delta_2 = delta_3 * Theta2(:,2:end) .* sigmoidGradient(z2');
delta_2 = delta_2'; %25 * 5000
Delta_1 = zeros(size(Theta1)); % 25 * 401
Delta_2 = zeros(size(Theta2)); % 10 * 26
Delta_1 = Delta_1 + delta_2 * a1; % 25 * 401
Delta_2 = Delta_2 + delta_3' * a2; % 10 * 26 delta_3:5000 * 10 a2: 5000 * 26
Theta1_grad = (1/m) * Delta_1 + lambda/m * Theta1; % 25 *401
Theta2_grad = (1/m) * Delta_2 + lambda/m * Theta2; % 10 * 26
Theta1_grad(:,1) = 1 / m * Delta_1(:,1);
Theta2_grad(:,1) = 1 / m * Delta_2(:,1);
|