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

這周和上周的作業(yè)一樣焦影,數(shù)據(jù)集還是5000個 20x20 像素的手寫字母鳞绕,這周會用到反向傳播的算法饥努。一共5段需要提交的代碼,如果上周的內(nèi)容弄清楚了颗胡,跟著教程的話作業(yè)是不太難的(雖然課程視頻內(nèi)容很燒腦)毫深。

  • 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

因為多元分類的神經(jīng)網(wǎng)絡(luò)中 y 是一個橫向的向量,包含了從0到9的標簽毒姨。但是如果我們要訓練一個神經(jīng)網(wǎng)絡(luò)哑蔫,需要將 y 轉(zhuǎn)化為一個只有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

接著就是構(gòu)建我們的神經(jīng)網(wǎng)絡(luò)模型了泉懦,和上周的內(nèi)容差不多。只不過因為神經(jīng)網(wǎng)絡(luò)的公式不同疹瘦,我們需要多加一個sum. 這個公式不難理解崩哩,代價函數(shù)求的是預(yù)測值和實際結(jié)果的平方差,

神經(jīng)網(wǎng)絡(luò)的正則化有些復(fù)雜,乍一看一個Σ套一個Σ邓嘹,不過在 matlab 里寫的時候就是一個sum套一個sum, 注意括號和公式就可以了(如果結(jié)果不對多半是公式寫錯了哈哈)酣栈。

神經(jīng)網(wǎng)絡(luò)代價函數(shù)公式
ex4 中的代價函數(shù)(Theta1 Theta2 分開來寫更明了)

對于前半部分這兩個Σ, K 為該神經(jīng)網(wǎng)絡(luò)輸出層的標簽數(shù)(本作用中為10),m 為樣本數(shù)汹押,我們先把一個樣本的10個標簽的代價求和矿筝,再將 m 個樣本的代價求和。

作業(yè)提示強調(diào)不要把 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

這個比較簡單妙痹。我犯的一個錯誤是用了 * . 雖然在主函數(shù)里得到了正確的結(jié)果0.25铸史,但是提交的時候出現(xiàn)了問題。所以提交前用 test code 測試一下會比較好(這些 test code 真的很有用)怯伊。這里應(yīng)該用 .* 因為是矩陣元素相乘琳轿。

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

Backpropogation Algorithm

作業(yè)里的 checkNNGradients.m 是一段單獨的程序,里面的Theta1, Theta2 和之前的不一樣耿芹,專門用來檢測偏導數(shù)計算是否正確崭篡。其實怎么寫公式里面都有,但是......

偏導數(shù)計算步驟

但是我在電腦前坐了2個多小時一直在寫這段代碼0娠酢(可能是自己智商比較捉急吧...)因為矩陣的 size 總是傻傻分不清琉闪,就不停在報錯說 Matrix dimensions must agree...

計算的時候可以用 size 函數(shù)看矩陣大小

我的代碼有點冗余...

% ==== 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;

寫完后執(zhí)行一下 checkNNGradients, 可以看到偏導數(shù)確實很相近:

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

到這里就完成作業(yè)啦吟秩!運行下面的代碼用 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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涵防,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沪铭,更是在濱河造成了極大的恐慌壮池,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杀怠,死亡現(xiàn)場離奇詭異椰憋,居然都是意外死亡,警方通過查閱死者的電腦和手機赔退,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門橙依,熙熙樓的掌柜王于貴愁眉苦臉地迎上來证舟,“玉大人,你說我怎么就攤上這事窗骑∨穑” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵创译,是天一觀的道長抵知。 經(jīng)常有香客問我,道長软族,這世上最難降的妖魔是什么刷喜? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮互订,結(jié)果婚禮上吱肌,老公的妹妹穿的比我還像新娘。我一直安慰自己仰禽,他們只是感情好氮墨,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吐葵,像睡著了一般规揪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上温峭,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天猛铅,我揣著相機與錄音,去河邊找鬼凤藏。 笑死奸忽,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的揖庄。 我是一名探鬼主播栗菜,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蹄梢!你這毒婦竟也來了疙筹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤禁炒,失蹤者是張志新(化名)和其女友劉穎而咆,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幕袱,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡暴备,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了们豌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馍驯。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡阁危,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汰瘫,到底是詐尸還是另有隱情,我是刑警寧澤擂煞,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布混弥,位于F島的核電站,受9級特大地震影響对省,放射性物質(zhì)發(fā)生泄漏蝗拿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一蒿涎、第九天 我趴在偏房一處隱蔽的房頂上張望哀托。 院中可真熱鬧,春花似錦劳秋、人聲如沸仓手。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗽冒。三九已至,卻和暖如春补履,著一層夾襖步出監(jiān)牢的瞬間添坊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工箫锤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留贬蛙,地道東北人。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓谚攒,卻偏偏與公主長得像阳准,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子五鲫,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容