序
记录机器学习第3次编程作业的解题思路,通过这次的练习,你可以使用logistic regression和neural networks来进行手写数字识别。
Part 1. Multi-class Classification
1. Training Set 说明
ex3data1.mat中存放的是Multi-class Classification使用的Training Set,包含了X和y两个值,使用MATLAB打开后显示如下图:
在ex3.m中,会调用load来加载ex3data1.mat中的数据
X中包含了5000个样本,每个样本代表1个数字,1个数字由20 * 20 的像素组成,代表一个灰度图像,每一个像素用一个浮点数表示。一个样本为400 * 1的行向量,因此,整个输入样本的维度是5000 * 400。
y中表示的是对应样本X表示的数字是多少,其中数字0被标记为10,数字1到9被标记为1到9,y的维度为5000 * 1
2. 可视化数据
在ex3.m中会调用displayData可以将由20 * 20 的像素点组成的数字绘制出来
随机选择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
这道题在注释里面有一段提示可以参考
实现代码如下:
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,我们可以计算出一个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。
因此,p的计算过程为:找出每一行的最大值的index,即为预测值输出值。
for i=1:m,
[x, ix] = max(temp(i,:));
p(i) = ix;
end
通过上面的代码计算得到的p的值,是一个5000 * 1的向量
完整实现代码如下:
Part 2. Neural Networks
predict
第二部分只需要实现predict函数,predict传入的参数Theta1和Theta2,是从ex3weights.mat中加载来的,X仍然来自ex3data1.mat。
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
完整实现代码
提交以后完成本次作业