这篇文章是基于bilibili的吴恩达机器学习经典名课【中英字幕】所写的第三周的编程练习,这个作业是关于逻辑回归的。
作业大纲
1 多分类问题
在这个任务中,你需要使用逻辑回归和神经网络去解决数字识别问题(从0-9)。
1.1 数据集
老师给了ex3data1.mat这个文件,文件中包含了5000个手写的数字训练集。每一个训练集是20px*20px的灰度图像,并且这个图像被展开形成一个400维的向量。值得注意的是,为了兼容matlab的下标,将0写成10,其余的不变。
1.2 数据可视化
在这个部分,我们将调用 displayData function去随机展示100个数字,如下图:
1.3 向量化逻辑回归 lrCostFunction
你需要使用多次的一对多逻辑回归模型建立多元分类器。因为有十分类,所以需要训练十个独立的逻辑回归分类器。为了让训练更有效率,确保你的代码向量化是非常重要的。在这个部分里面,你需要使用实现逻辑回归的向量化版本,不能使用任何的循环。
1.3.1 向量化代价函数
这个是不带正则项的代价函数。
1.3.2 向量化梯度
不带正则项的梯度函数
1.3.3 向量化正则逻辑函数
这个是带正则项的代价函数。
带正则项的梯度函数,需要注意的是对于j=0的时候我们不需要计算他的正则项。
代码如下:
function [J, grad] = lrCostFunction(theta, X, y, lambda)
m = length(y); % number of training examples
h = sigmoid(X*theta);
temp = theta;
temp(1) = 0; % 正则化时theta0没有在求和多项式中
J = -1/m * (y'*log(h)+(1-y)'*log(1-h)) + lambda/(2*m) * (temp'*temp);
grad = 1/m * (X'*(h - y)) + lambda/m*temp;
1.4 一对多分类 oneVsAll.m
在这个练习部分中,你将通过训练多元正则逻辑回归分类器来实现一对多分类。在手写数字训练集中,你将要实现十个分类器。
function [all_theta] = oneVsAll(X, y, num_labels, lambda)
m = size(X, 1);
n = size(X, 2);
all_theta = zeros(num_labels, n + 1);
X = [ones(m, 1) X];
for c = 1:num_labels
initial_theta = zeros(n + 1, 1);
options = optimset('GradObj', 'on', 'MaxIter', 50);
all_theta(c,:) = fmincg (@(t)(lrCostFunction(t, X, (y == c), lambda)),initial_theta, options);
end
1.4.1 一对多预测 predictOneVsAll.m
在完成训练之后,就可以用得到的模型进行训练啦,对于每一个输入,你应该计算每一个类别的可能性。完成predictOneVsAll.m的编程,将模型的准确率输出。(准确率是94.9%)
function p = predictOneVsAll(all_theta, X)
m = size(X, 1);
num_labels = size(all_theta, 1);
p = zeros(size(X, 1), 1);
X = [ones(m, 1) X];
type = sigmoid(X*all_theta');
for i =1:m
A = type(i,1:num_labels);
p(i) = find(A==max(A));
end
end
2 神经网络
逻辑回归不能组成更复杂的假设,因为它是一个线性分类器,在这个部分的练习中,你将实现神经网络去识别手写数字。这周的神经网络的参数我们已经训练好,你需要实现的是编写前馈传播算法去进行识别。
2.1 模型表示
本次训练的模型是一个三层的神经网络,一个输入层,有400个单元。一个隐含层,有25个单元。一个输出层,有十个单元,分别对应了十个数字类别。
2.2 前馈传播和预测 predict.m
function p = predict(Theta1, Theta2, X)
%PREDICT Predict the label of an input given a trained neural network
% p = PREDICT(Theta1, Theta2, X) outputs the predicted label of X given the
% trained weights of a neural network (Theta1, Theta2)
% Useful values
m = size(X, 1);
num_labels = size(Theta2, 1);
X = [ones(m,1),X];
% You need to return the following variables correctly
p = zeros(size(X, 1), 1);
% ====================== YOUR CODE HERE ======================
% Instructions: Complete the following code to make predictions using
% your learned neural network. You should set p to a
% vector containing labels between 1 to num_labels.
%
% Hint: The max function might come in useful. In particular, the max
% function can also return the index of the max element, for more
% information see 'help max'. If your examples are in rows, then, you
% can use max(A, [], 2) to obtain the max for each row.
%
type1 = sigmoid(X*Theta1');
type1 = [ones(m,1),type1];
type2 = sigmoid(type1*Theta2');
for i =1:m
A = type2(i,1:num_labels);
p(i) = find(A==max(A));
end
end
总结
以前对于多元的分类问题总是觉得很难,没有办法下手,在看了老师的课之后,就觉得还是蛮有意思的。在这次的练习中也稍微出现了一些些小问题。还是没有把公式了解透彻吧。希望抓紧时间学完机器学习!!!
我的成绩: