[Coursera] Machine Learning ex4 反向传播算法

这周和上周的作业一样,数据集还是5000个 20x20 像素的手写字母,这周会用到反向传播的算法。一共5段需要提交的代码,如果上周的内容弄清楚了,跟着教程的话作业是不太难的(虽然课程视频内容很烧脑)。

  • Feedforward and cost function 30
  • Regularized cost function 15
  • Sigmoid gradient 5
  • Neural net gradient function (backpropagation) 40
  • Regularized gradient 10

Feedforward and cost function

因为多元分类的神经网络中 y 是一个横向的向量,包含了从0到9的标签。但是如果我们要训练一个神经网络,需要将 y 转化为一个只有0和1的矩阵。例如 x1 的标签为5,那 y 的第一行只有第五个元素是1,其他都是0. 我们可以用一个 for loop 完成(可能还有我不知道的更简洁的方法)。

Recode y
Y = zeros(m,num_labels);
for i = 1:m
    Y(i, y(i)) = 1;
end

接着就是构建我们的神经网络模型了,和上周的内容差不多。只不过因为神经网络的公式不同,我们需要多加一个sum. 这个公式不难理解,代价函数求的是预测值和实际结果的平方差,

神经网络的正则化有些复杂,乍一看一个Σ套一个Σ,不过在 matlab 里写的时候就是一个sum套一个sum, 注意括号和公式就可以了(如果结果不对多半是公式写错了哈哈)。

神经网络代价函数公式
ex4 中的代价函数(Theta1 Theta2 分开来写更明了)

对于前半部分这两个Σ, K 为该神经网络输出层的标签数(本作用中为10),m 为样本数,我们先把一个样本的10个标签的代价求和,再将 m 个样本的代价求和。

作业提示强调不要把 bias 算进去,之前在逻辑回归里是没有算 theta 的第一个元素,这里是跳过 Theta1 和 Theta2 的第一列。

% add bias
a1 = [ones(m,1) X];
% hidden layer
z2 = a1 * Theta1';
% add bias 
a2 = [ones(m,1) sigmoid(z2)];
z3 = a2 * Theta2';
a3 = sigmoid(z3);
cost = 1/m * sum(sum(-Y .* log(a3) - (1-Y) .* log(1-a3)));
% skip 1st column of Theta1 and Theta2
regCost = lambda/(2*m) * (sum(sum(Theta1(:,2:end) .^ 2))+ sum(sum(Theta2(:, 2:end) .^ 2)));
J = cost + regCost;

Sigmoid gradient

这个比较简单。我犯的一个错误是用了 * . 虽然在主函数里得到了正确的结果0.25,但是提交的时候出现了问题。所以提交前用 test code 测试一下会比较好(这些 test code 真的很有用)。这里应该用 .* 因为是矩阵元素相乘。

g = sigmoid(z) .* (1-sigmoid(z));

Backpropogation Algorithm

作业里的 checkNNGradients.m 是一段单独的程序,里面的Theta1, Theta2 和之前的不一样,专门用来检测偏导数计算是否正确。其实怎么写公式里面都有,但是......

偏导数计算步骤

但是我在电脑前坐了2个多小时一直在写这段代码!(可能是自己智商比较捉急吧...)因为矩阵的 size 总是傻傻分不清,就不停在报错说 Matrix dimensions must agree...

计算的时候可以用 size 函数看矩阵大小

我的代码有点冗余...

% ==== Part 2 ====
Delta1 = zeros(size(Theta1));
Delta2 = zeros(size(Theta2));

for i=1:m 
    a_1 = X(i,:)';
    % add bias
    a_1 = [1; a_1];
    % hidden layer
    z_2 = a_1' * Theta1';
    a_2 = sigmoid(z_2);
    % add bias
    a_2 = [1; a_2'];
    % output layer
    z_3 = a_2' * Theta2';
    a_3 = sigmoid(z_3);

    % compute the error
    delta_3 = a_3 - Y(i, :);
    % compute error on the second layer
    tmp = (Theta2' * delta_3')';
    delta_2 = tmp(2:end).* sigmoidGradient(z_2);
    Delta2 = Delta2 + delta_3' * a_2';
    Delta1 = Delta1 + delta_2' * a_1';
end 
Theta1_grad = 1/m * Delta1;
Theta2_grad = 1/m * Delta2;

写完后执行一下 checkNNGradients, 可以看到偏导数确实很相近:

Gradient checking result

Regularized Neural Networks

最后这步也是比较简单的,注意点就是不要把 bias 算进去。 Theta1 和 Theta2 是两个矩阵,这里也是无视他们的第一列。我尽量写得短一点。

% ==== Part 3 ====
% regularize Theta1_grad
Theta1_grad(:,2:end) = Theta1_grad(:,2:end) + lambda / m * Theta1(:, 2:end);

% regualize Theta2_grad
Theta2_grad(:,2:end) = Theta2_grad(:,2:end) + lambda / m * Theta2(:, 2:end);

Learning parameters

到这里就完成作业啦!运行下面的代码用 fmincg 返回 Theta 值,可以看到正确率大概为95.68%!

options = optimset('MaxIter', 50);
lambda = 1;

% Create "short hand" for the cost function to be minimized
costFunction = @(p) nnCostFunction(p, input_layer_size, hidden_layer_size, num_labels, X, y, lambda);

% Now, costFunction is a function that takes in only one argument (the
% neural network parameters)
[nn_params, ~] = fmincg(costFunction, initial_nn_params, options);
% Obtain Theta1 and Theta2 back from nn_params
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));
 
pred = predict(Theta1, Theta2, X);
fprintf('\nTraining Set Accuracy: %f\n', mean(double(pred == y)) * 100);
Learning parameters using fmincg

还有最后的显示隐藏层也很有趣呢!

Display hidden layer
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,392评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,258评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,417评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,992评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,930评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,199评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,652评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,327评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,463评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,382评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,432评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,118评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,704评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,787评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,999评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,476评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,057评论 2 341

推荐阅读更多精彩内容