Machine Learning

编程作业 3: Multi-class Classificati

2017-08-10  本文已影响359人  伤口不该结疤

记录机器学习第3次编程作业的解题思路,通过这次的练习,你可以使用logistic regression和neural networks来进行手写数字识别。

Part 1. Multi-class Classification

1. Training Set 说明

ex3data1.mat中存放的是Multi-class Classification使用的Training Set,包含了X和y两个值,使用MATLAB打开后显示如下图:

ex3data1.mat

在ex3.m中,会调用load来加载ex3data1.mat中的数据

load('ex3data1.mat')

X中包含了5000个样本,每个样本代表1个数字,1个数字由20 * 20 的像素组成,代表一个灰度图像,每一个像素用一个浮点数表示。一个样本为400 * 1的行向量,因此,整个输入样本的维度是5000 * 400。

ex3.pdf中对X的描述

y中表示的是对应样本X表示的数字是多少,其中数字0被标记为10,数字1到9被标记为1到9,y的维度为5000 * 1

ex3.pdf中对y的描述

2. 可视化数据

在ex3.m中会调用displayData可以将由20 * 20 的像素点组成的数字绘制出来

ex3.m中调用displayData绘制数字

随机选择100个样本进行绘制,效果图如下:

随机选择100个样本进行显示

当然,我们可以绘制所有的5000个数字,displayData传入X作为参数即可,由于数据量太大了,每个数字会被缩小显示,点击Z+可以放大图像。

>displayData(X);
显示所有的样本

放大后的效果为下图所示,我们可以看到一个数字都有对应有很多种形状,即Multi-class Classification中的OneVsAll。

放大图片

3. lrCostFunction

和编程作业2的costFunctionReg实现代码一样

temp = theta(2:length(theta));
J = sum((-y).*log(sigmoid(X*theta)) - (1-y).*log(1 - sigmoid(X*theta)))/m + (lambda/(2*m))*sum(temp.^2);

for i=1:size(X,2)
    grad(i) = ((sigmoid(X*theta) - y)'*X(:,i))/m;
end

grad = grad + [0;((lambda/m)*temp)];

4. oneVsAll

这道题在注释里面有一段提示可以参考

Example Code for fmincg

实现代码如下:

initial_theta = zeros(n + 1, 1);
options = optimset('GradObj', 'on', 'MaxIter', 50);
for c = 1:num_labels
[theta] = ...
         fmincg (@(t)(lrCostFunction(t, X, (y == c), lambda)), ...
                 initial_theta, options);
all_theta(c,:) = theta';
end;

5. predictOneVsAll

首先,传入的all_theta是通过oneVsAll得到的,all_theta是一个 10 * 401的矩阵,一共10行,每一行代表一个数字,一共10个数字。

function p = predictOneVsAll(all_theta, X)

为了更容易理解算法的实现,我会把计算过程中得到的关键值保存为.mat格式的文件,下图为all_theta的值。

all_theta.mat

通过all_theta,我们可以计算出一个temp矩阵,维度为5000*10,每一行代表一个样本,一共5000个样本,每一列表示成为该num_labels的概率,num_labels值等于列值。

temp = zeros(size(X, 1), num_labels);
for i=1:num_labels,
    temp(:,i) = sigmoid(X*(all_theta(i,:)'));
end

例如:第一行第二列的值为0.0003518171008132601,表示第一个样本是数字2的概率为0.0003518171008132601。第一行中数值最大的是第10列,即:0.999561625035584,说明第一个样本最有可能对应的num_labels为10代表的数字,预测输出为10。

temp矩阵

因此,p的计算过程为:找出每一行的最大值的index,即为预测值输出值。

for i=1:m,
[x, ix] = max(temp(i,:));
p(i) = ix;
end

通过上面的代码计算得到的p的值,是一个5000 * 1的向量

p

完整实现代码如下:

predictOneVsAll

Part 2. Neural Networks

predict

第二部分只需要实现predict函数,predict传入的参数Theta1和Theta2,是从ex3weights.mat中加载来的,X仍然来自ex3data1.mat。

ex3weights.mat ex3weights.mat Neural network model.
X = [ones(m, 1) X];

z2 = X*Theta1';
a2 = sigmoid(z2);
a2 = [ones(size(a2, 1), 1) a2];

z3 = a2*Theta2';
a3 = sigmoid(z3);

再使用和predictOneVsAll一样的取最大值方法

for i=1:m,
[x, ix] = max(a3(i,:));
p(i) = ix;
end

完整实现代码

predict

提交以后完成本次作业

submit
上一篇下一篇

猜你喜欢

热点阅读