Machine Learning week 5 programming exercise Neural Network Learning

Neural Networks Learning


Visualizing the data

这次试用的数据和上次是一样的数据。5000个training example,每一个代表一个数字的图像,图像是20x20的灰度图,400个像素的每个位置的灰度值组成了一个training example。


Model representation

这里我们使用如下的模型,共3层,其中第一层input有400个feature,另外还有bias unit。



这个练习中实现训练了一些theta,通过如下的代码把theta1和theta2读取出来
% Load saved matrices from file
load('ex4weights.mat');
% The matrices Theta1 and Theta2 will now be in your workspace
% Theta1 has size 25 x 401
% Theta2 has size 10 x 26

Feedforward and cost function

现在我们需要计算cost function和gradient

这里是没有regularization的情况下的cost function公式,m表示m个training example,k表示k个output,这里我们有10个output,分别代表1-10

y的值需要从数字形式转化为向量形式,如下,下面的例子中第一列表示1,第二列表示2



Regularized cost function

下面是regularized cost function,其实就是在普通的cost function后面加上每个theta的平方,当然不要忘了系数。不过这里并不是所有的theta,所有跟bias unit相关的theta都要排除。




我们现在这里写的程序,指针对3层网络,但是对于由于每层unit数量不一样出现的不同的网络,我们这里也要兼容

function [J grad] = nnCostFunction(nn_params, ...
                                   input_layer_size, ...
                                   hidden_layer_size, ...
                                   num_labels, ...
                                   X, y, lambda)
%NNCOSTFUNCTION Implements the neural network cost function for a two layer
%neural network which performs classification
%   [J grad] = NNCOSTFUNCTON(nn_params, hidden_layer_size, num_labels, ...
%   X, y, lambda) computes the cost and gradient of the neural network. The
%   parameters for the neural network are "unrolled" into the vector
%   nn_params and need to be converted back into the weight matrices. 
% 
%   The returned parameter grad should be a "unrolled" vector of the
%   partial derivatives of the neural network.
%

% Reshape nn_params back into the parameters Theta1 and Theta2, the weight matrices
% for our 2 layer neural network
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));

% Setup some useful variables
m = size(X, 1);
         
% You need to return the following variables correctly 
J = 0;
Theta1_grad = zeros(size(Theta1));
Theta2_grad = zeros(size(Theta2));

% ====================== YOUR CODE HERE ======================
% Instructions: You should complete the code by working through the
%               following parts.
%
% Part 1: Feedforward the neural network and return the cost in the
%         variable J. After implementing Part 1, you can verify that your
%         cost function computation is correct by verifying the cost
%         computed in ex4.m
%
% Part 2: Implement the backpropagation algorithm to compute the gradients
%         Theta1_grad and Theta2_grad. You should return the partial derivatives of
%         the cost function with respect to Theta1 and Theta2 in Theta1_grad and
%         Theta2_grad, respectively. After implementing Part 2, you can check
%         that your implementation is correct by running checkNNGradients
%
%         Note: The vector y passed into the function is a vector of labels
%               containing values from 1..K. You need to map this vector into a 
%               binary vector of 1's and 0's to be used with the neural network
%               cost function.
%
%         Hint: We recommend implementing backpropagation using a for-loop
%               over the training examples if you are implementing it for the 
%               first time.
%
% Part 3: Implement regularization with the cost function and gradients.
%
%         Hint: You can implement this around the code for
%               backpropagation. That is, you can compute the gradients for
%               the regularization separately and then add them to Theta1_grad
%               and Theta2_grad from Part 2.
%
#计算每层的结果,记得要把bias unit加上,第一次写把a1 写成了 [ones(m,1); X];
a1 = [ones(m,1) X];
z2 = Theta1 * a1';
a2 = sigmoid(z2);
a2 = [ones(1,m); a2]; #这里 a2 和 a1 的格式已经不一样了,a1是行排列,a2是列排列
z3 = Theta2 * a2;
a3 = sigmoid(z3);

# 首先把原先label表示的y变成向量模式的output,下面用了循环
y_vect = zeros(num_labels, m);
for i = 1:m,
    y_vect(y(i),i) = 1;
end;

#每一training example的cost function是使用的向量计算,然后for loop累加所有m个training example
#的cost function
for i=1:m,
    J += sum(-1*y_vect(:,i).*log(a3(:,i))-(1-y_vect(:,i)).*log(1-a3(:,i)));
end;
J = J/m;

#增加regularization,一开始只写了一个sum,但其实theta1 2 分别都是矩阵,一个sum只能按列累加,bias unit的theta不参与regularization
J = J + lambda*(sum(sum(Theta1(:,2:end).^2))+sum(sum(Theta2(:,2:end).^2)))/2/m;

#backward propagation
#Δ的元素个数应该和对应的theta中的元素的个数相同
Delta1 = zeros(size(Theta1));
Delta2 = zeros(size(Theta2));
for i=1:m,
    delta3 = a3(:,i) - y_vect(:,i);
    
    #注意这里的δ是不包含bias unit的delta的,毕竟bias unit永远是1,
    #不需要计算delta, 下面的2:end,: 过滤掉了bias unit相关值
    delta2 = (Theta2'*delta3)(2:end,:).*sigmoidGradient(z2(:,i));
    #移除bias unit上的delta2,但是由于上面sigmoidGradient式子中
    #的z,本身不包含bias unit,所以下面的过滤不必要,注释掉。
    #delta2 = delta2(2:end);
    Delta2 += delta3 * a2(:,i)';
    
    #第一层的input是一行一行的,和后面的结构不一样,后面是一列作为一个example
    Delta1 += delta2 * a1(i,:);
end;

#总结一下,δ不包含bias unit的偏差值,Δ对跟θ对应的,用来计算每个θ
#后面的偏导数的,所以Δ包含bias unit的θ
Theta2_grad = Delta2/m;
Theta1_grad = Delta1/m;

#regularization gradient

Theta2_grad(:,2:end) = Theta2_grad(:,2:end) .+ lambda * Theta2(:,2:end) / m;
Theta1_grad(:,2:end) = Theta1_grad(:,2:end) .+ lambda * Theta1(:,2:end) / m;






% -------------------------------------------------------------

% =========================================================================

% Unroll gradients
grad = [Theta1_grad(:) ; Theta2_grad(:)];


end


Backpropagation

Sigmoid gradient

sigmoid gradient反向传播计算gradient的公式的一部分


function g = sigmoidGradient(z)
%SIGMOIDGRADIENT returns the gradient of the sigmoid function
%evaluated at z
%   g = SIGMOIDGRADIENT(z) computes the gradient of the sigmoid function
%   evaluated at z. This should work regardless if z is a matrix or a
%   vector. In particular, if z is a vector or matrix, you should return
%   the gradient for each element.

g = zeros(size(z));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the gradient of the sigmoid function evaluated at
%               each value of z (z can be a matrix, vector or scalar).

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

% =============================================================
end


Random initialization

为了打破symmetry breaking,我们要在选取初始theta的时候,每次选择某一层的theta,然后让每个这一层的theta都随机选取,范围 [-ξ,ξ]
有如下经验公式可用来选择合适的theta范围

确定了范围之后,下面是随机选择的过程
% Randomly initialize the weights to small values
epsilon init = 0.12;
W = rand(L out, 1 + L in) * 2 * epsilon init − epsilon init;

Backpropagation

在反向传播过程中,我们要计算除了input layer之外的每层的小 delta,也就是δ。参考下图,



计算过程分为下面5步,每个training example都循环进行1-4:
1 forward propagation计算每一层的函数z,和每一层的activation,不要忘记途中增加bias unit
2 计算第三层的δ,

3 计算第二层的δ,

4计算每一层的Δ,这里要搞清楚,δ代表当前层的所有unit个数,如果是hidden layer的话,还包括了bias unit。Δ的最终结果是当前层的theta的偏导数,和当前层的theta维数一致,通过δ计算Δ的时候,由于后层的δ中的bias unit并不是有当前层的theta计算到的,反向计算theta的偏导数,Δ的时候则要把其中的bias unit去掉

5 上面m个training example都循环计算完成之后,计算最后的偏导数


实际上这里的第一步,可以一次性使用矩阵操作计算完成所有m个训练数据的结果,但是后面的几步,还是要循环计算每个训练数据的结果

Gradient checking

这里主要是对我们上面编写的计算偏导数的函数进行验证的一个方法,通过比较上面计算结果和这里计算的估计结果的关系来判断,我们的code是否正确。


这里我们选择ε= 10^−4, 最终我们会看到我们计算的偏导数和估计的偏导数差值应该是 1e-9的数量级。
当然这里计算的时候可以使用比较少的unit的网络,因为这里估计值的计算计算量很大。

function numgrad = computeNumericalGradient(J, theta)
%COMPUTENUMERICALGRADIENT Computes the gradient using "finite differences"
%and gives us a numerical estimate of the gradient.
%   numgrad = COMPUTENUMERICALGRADIENT(J, theta) computes the numerical
%   gradient of the function J around theta. Calling y = J(theta) should
%   return the function value at theta.

% Notes: The following code implements numerical gradient checking, and 
%        returns the numerical gradient.It sets numgrad(i) to (a numerical 
%        approximation of) the partial derivative of J with respect to the 
%        i-th input argument, evaluated at theta. (i.e., numgrad(i) should 
%        be the (approximately) the partial derivative of J with respect 
%        to theta(i).)
%                

numgrad = zeros(size(theta));
perturb = zeros(size(theta));
e = 1e-4;
for p = 1:numel(theta)
    % Set perturbation vector
    perturb(p) = e;
    loss1 = J(theta - perturb);
    loss2 = J(theta + perturb);
    % Compute Numerical Gradient
    numgrad(p) = (loss2 - loss1) / (2*e);
    perturb(p) = 0;
end

end

Regularized Neural Networks





计算的时候,所有和bias项对应的theta都不需要做regularization

Learning parameters using fmincg

Visualizing the hidden layer

这里很有意思,我们的input是400个像素点的灰度值,而theta1的每一行都是一个401的vector,去掉第一个,同样得到一个400的vector,然后我们把它可视化出来,可以大概看到我们做了什么




change lambda

不同的λ,会得到不同的结果,怎么选取lambda呢?

%% Machine Learning Online Class - Exercise 4 Neural Network Learning

%  Instructions
%  ------------
% 
%  This file contains code that helps you get started on the
%  linear exercise. You will need to complete the following functions 
%  in this exericse:
%
%     sigmoidGradient.m
%     randInitializeWeights.m
%     nnCostFunction.m
%
%  For this exercise, you will not need to change any code in this file,
%  or any other files other than those mentioned above.
%

%% Initialization
clear ; close all; clc

%% Setup the parameters you will use for this exercise
input_layer_size  = 400;  % 20x20 Input Images of Digits
hidden_layer_size = 25;   % 25 hidden units
num_labels = 10;          % 10 labels, from 1 to 10   
                          % (note that we have mapped "0" to label 10)

%% =========== Part 1: Loading and Visualizing Data =============
%  We start the exercise by first loading and visualizing the dataset. 
%  You will be working with a dataset that contains handwritten digits.
%

% Load Training Data
fprintf('Loading and Visualizing Data ...\n')

load('ex4data1.mat');
m = size(X, 1);

% Randomly select 100 data points to display
sel = randperm(size(X, 1));
sel = sel(1:100);

displayData(X(sel, :));

fprintf('Program paused. Press enter to continue.\n');
pause;


%% ================ Part 2: Loading Parameters ================
% In this part of the exercise, we load some pre-initialized 
% neural network parameters.

fprintf('\nLoading Saved Neural Network Parameters ...\n')

% Load the weights into variables Theta1 and Theta2
load('ex4weights.mat');

% Unroll parameters 
nn_params = [Theta1(:) ; Theta2(:)];

%% ================ Part 3: Compute Cost (Feedforward) ================
%  To the neural network, you should first start by implementing the
%  feedforward part of the neural network that returns the cost only. You
%  should complete the code in nnCostFunction.m to return cost. After
%  implementing the feedforward to compute the cost, you can verify that
%  your implementation is correct by verifying that you get the same cost
%  as us for the fixed debugging parameters.
%
%  We suggest implementing the feedforward cost *without* regularization
%  first so that it will be easier for you to debug. Later, in part 4, you
%  will get to implement the regularized cost.
%
fprintf('\nFeedforward Using Neural Network ...\n')

% Weight regularization parameter (we set this to 0 here).
lambda = 0;

J = nnCostFunction(nn_params, input_layer_size, hidden_layer_size, ...
                   num_labels, X, y, lambda);

fprintf(['Cost at parameters (loaded from ex4weights): %f '...
         '\n(this value should be about 0.287629)\n'], J);

fprintf('\nProgram paused. Press enter to continue.\n');
pause;

%% =============== Part 4: Implement Regularization ===============
%  Once your cost function implementation is correct, you should now
%  continue to implement the regularization with the cost.
%

fprintf('\nChecking Cost Function (w/ Regularization) ... \n')

% Weight regularization parameter (we set this to 1 here).
lambda = 1;

J = nnCostFunction(nn_params, input_layer_size, hidden_layer_size, ...
                   num_labels, X, y, lambda);

fprintf(['Cost at parameters (loaded from ex4weights): %f '...
         '\n(this value should be about 0.383770)\n'], J);

fprintf('Program paused. Press enter to continue.\n');
pause;


%% ================ Part 5: Sigmoid Gradient  ================
%  Before you start implementing the neural network, you will first
%  implement the gradient for the sigmoid function. You should complete the
%  code in the sigmoidGradient.m file.
%

fprintf('\nEvaluating sigmoid gradient...\n')

g = sigmoidGradient([1 -0.5 0 0.5 1]);
fprintf('Sigmoid gradient evaluated at [1 -0.5 0 0.5 1]:\n  ');
fprintf('%f ', g);
fprintf('\n\n');

fprintf('Program paused. Press enter to continue.\n');
pause;


%% ================ Part 6: Initializing Pameters ================
%  In this part of the exercise, you will be starting to implment a two
%  layer neural network that classifies digits. You will start by
%  implementing a function to initialize the weights of the neural network
%  (randInitializeWeights.m)

fprintf('\nInitializing Neural Network Parameters ...\n')

initial_Theta1 = randInitializeWeights(input_layer_size, hidden_layer_size);
initial_Theta2 = randInitializeWeights(hidden_layer_size, num_labels);

% Unroll parameters
initial_nn_params = [initial_Theta1(:) ; initial_Theta2(:)];


%% =============== Part 7: Implement Backpropagation ===============
%  Once your cost matches up with ours, you should proceed to implement the
%  backpropagation algorithm for the neural network. You should add to the
%  code you've written in nnCostFunction.m to return the partial
%  derivatives of the parameters.
%
fprintf('\nChecking Backpropagation... \n');

%  Check gradients by running checkNNGradients
checkNNGradients;

fprintf('\nProgram paused. Press enter to continue.\n');
pause;


%% =============== Part 8: Implement Regularization ===============
%  Once your backpropagation implementation is correct, you should now
%  continue to implement the regularization with the cost and gradient.
%

fprintf('\nChecking Backpropagation (w/ Regularization) ... \n')

%  Check gradients by running checkNNGradients
lambda = 3;
checkNNGradients(lambda);

% Also output the costFunction debugging values
debug_J  = nnCostFunction(nn_params, input_layer_size, ...
                          hidden_layer_size, num_labels, X, y, lambda);

fprintf(['\n\nCost at (fixed) debugging parameters (w/ lambda = 10): %f ' ...
         '\n(this value should be about 0.576051)\n\n'], debug_J);

fprintf('Program paused. Press enter to continue.\n');
pause;


%% =================== Part 8: Training NN ===================
%  You have now implemented all the code necessary to train a neural 
%  network. To train your neural network, we will now use "fmincg", which
%  is a function which works similarly to "fminunc". Recall that these
%  advanced optimizers are able to train our cost functions efficiently as
%  long as we provide them with the gradient computations.
%
fprintf('\nTraining Neural Network... \n')

%  After you have completed the assignment, change the MaxIter to a larger
%  value to see how more training helps.
options = optimset('MaxIter', 50);

%  You should also try different values of lambda
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, cost] = 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));

fprintf('Program paused. Press enter to continue.\n');
pause;


%% ================= Part 9: Visualize Weights =================
%  You can now "visualize" what the neural network is learning by 
%  displaying the hidden units to see what features they are capturing in 
%  the data.

fprintf('\nVisualizing Neural Network... \n')

displayData(Theta1(:, 2:end));

fprintf('\nProgram paused. Press enter to continue.\n');
pause;

%% ================= Part 10: Implement Predict =================
%  After training the neural network, we would like to use it to predict
%  the labels. You will now implement the "predict" function to use the
%  neural network to predict the labels of the training set. This lets
%  you compute the training set accuracy.

pred = predict(Theta1, Theta2, X);

fprintf('\nTraining Set Accuracy: %f\n', mean(double(pred == y)) * 100);




  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
神经网络学习的理论基础主要涉及三个方面:神经网络模型、反向传播算法和优化方法。 首先,神经网络模型是神经网络学习的基础,其建立在生物神经元工作原理的基础上。神经网络模型由输入层、隐藏层和输出层组成,每个神经元与其他神经元之间通过连接进行信息传递。不同的神经网络模型有不同的结构和激活函数,如前馈神经网络、循环神经网络和卷积神经网络等。 其次,反向传播算法是神经网络学习中最常用的优化算法之一。该算法通过计算损失函数关于网络参数的梯度,并将该梯度反向传播到网络的每一层,以更新参数的值。反向传播算法的关键步骤包括前向传播计算输出值、计算损失函数、反向传播计算梯度和更新参数。通过不断迭代这些步骤,神经网络可以逐渐调整参数,达到更好的学习效果。 最后,优化方法对神经网络学习也起到至关重要的作用。常用的优化方法有梯度下降法、随机梯度下降法、动量法和自适应学习率方法等。这些方法通过调整参数的更新策略,帮助神经网络更好地学习和适应输入数据。此外,正则化技术如L1和L2正则化也可用于控制神经网络的复杂度和避免过拟合的问题。 综上所述,神经网络学习的理论基础主要包括神经网络模型、反向传播算法和优化方法。这些理论基础使得神经网络能够从数据中学习,并取得优秀的预测和分类性能。不断的研究和发展神经网络的理论基础,将进一步促进神经网络的应用和发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值