一、概述
多元线性分类应用及神经网络入门。
作业分为两部分,第一部分是利用OneVsAll来进行多元分类,第二部分是神经网络入门,不需要自己计算权重,只需要预测结果即可。
主要有四个函数。前三个用于多元分类,最后一个是神经网络应用。很简单,就是有几个细节问题,不处理好要费点时间。
二、分析
1、多元分类
多元分类的原理是对于n类,有n个预测函数,对于每组预测特征,带入n个预测函数,求出n个预测值,最大的就是真正的预测值。
第一个函数是lrCostFunction,负责完成代价函数J的计算和偏导数的计算,与第二次编程 作业中的代码相同,如下:
J=(-(y')*log(sigmoid(X*theta))-((1-y)')*log(1-(sigmoid(X*theta))))/m+(theta([2:length(theta)])'*theta([2:length(theta)]))*lambda/(2*m);
grad(1)=(sigmoid(X*theta)-y)'*X(:,1)/m;
for i=2:length(grad)
grad(i)=(sigmoid(X*theta)-y)'*X(:,i)/m+theta(i)*lambda/m;
end
不再赘述。
第二个函数是oneVsAll,简而言之,就是找到n组theta,形成n个预测函数,对于每组预测数据,给出n个分类的可能性。
对于每组theta值,使用与fminunc函数类似的fmincg函数找到全局最小值,如下:
for i=1:num_labels
initial_theta=zeros(n+1,1);
options = optimset('GradObj', 'on', 'MaxIter', 50);
[all_theta(i,:)]=fmincg(@(t)(lrCostFunction(t, X, (y == i), lambda)),initial_theta, options);
end
整个函数是一个大循环,循环次数为分类总数。
首先将theta初始化为0,然后设置fmincg函数的选项,递归步数等。最后输出对应的theta值。
我们观察fmincg函数的输入参数与输出值,这里的@t不用变,第一个参数就是lrCostFunction函数,此函数就是我们要找全局最小值的函数,其输入参数,第一个为t不用变,第二个是X,也即线性回归的参数,第三个注意,是一个向量,只含0或1。原因在于,lrCostFunction函数要求此处是一个变量,表达“是”或者“否”,根据这点,我们将向量构造如下“y==i”,这句代码将返回一个向量,长度与y相同,若y中某个元素与i相同,则返回的向量中,对应该元素的位置为1,否则为0。这样,就形成了符合条件的向量。由于我们共需n个预测函数,每个预测函数的预测功能是不同的,例如,y==1就只能分辨出输入是否为1,y==2就是分辨2,以此类推。因此这里需要用i进行循环,之后的变量就是约定俗成的了。
返回值即一组theta值,这组theta值可以预测输入是否是i。由于整个all_theta矩阵是按行排列,因此输出直接按行放进all_theta中即可。
第三个函数是predictOneVsAll,其功能是判断准确率。
观察其输入函数,all_theta代表所有预测函数,X代表每组的预测数据。输出为一个向量,储存对应的X的预测值。
如何得到输出呢?根据oneVsAll的原理,我们对X的每一行进行预测,得到n个预测值,最大的预测值就是我们要的。
在这里,预测操作通过all_theta*X'完成,因为X和theta都是按行的,因此要把X进行转置,乘完以后得到的是一个n*n的矩阵,矩阵每一列的最大值的下标就是预测的数字,这是因为,我们看all_theta*X',对于X'中的每列,all_theta的每行都要与之相乘,得到的积按列放置,因此是每列的最大值的下标。
如何得到这个下标呢?我们使用max函数实现该功能,这里的max函数有三个参数,max(A,[],1);,第一个是预测结果,第二个不用管,第三个表示按行找最大值或者按列找最大值,我们按列,因此取值为1。返回两个向量,第一个是最大的值,第二个是对应下标,第二个就是我们需要的。返回的向量是横的,因为我们找的是每列的最大值,因此要将其转置。
代码如下:
q=zeros(size(X,1),1);
A=all_theta*X';
[q,p]=max(A,[],1);
p=p';
这样就实现了多元分类。
2、神经网络应用
只有一个函数,predict。
这是一个三层神经网络,因此需要两个theta矩阵,即预测分两步。
本次作业暂不了解theta矩阵是如何得到的,只需要应用即可。
关键在于矩阵该如何乘,不要弄错。
输入参数有三个,theta1,theta2,X。整个过程就是先利用theta1和X进行第一部分处理,得到一个矩阵,再与theta2进行处理得到预测结果。注意矩阵的维度。神经网络的一大特点在于有偏移象bias,一般置为1。也就是说,对于矩阵X,我们需要为其添上一行/列的1。这个很容易填错。
为了避免错误,我们首先要知道X,theta1和2的大小。
X 5000*400
theta1 25*401
theta2 10*26
因此,我们首先需要对X处理。观察X可知,共有5000组数据,每个数据有400个元素。然后看theta1,有401列,因此偏移量1应该是5000行,放在最左面。使得X变为5000*401,然后用theta1*X',得到25*5000的矩阵A1,这就是第一隐藏层的结果。
接下来处理第二层。观察theta2,有10行26列,说明这次偏移量应该放在最上面,有5000行,使得结果变为26*5000,然后用theta2*A1,得到10*5000的预测结果,然后找出每列的最大值即可。
一定要把这些矩阵的关系捋清楚,否则会很麻烦。
同时要注意,每次theta和X乘完,都要过一遍sigmoid,不然会出错。代码如下:
X = [ones(m, 1) X];
%size(X)
%size(Theta1)
A1=Theta1*X';
A1=sigmoid(A1);
A1=[ones(1,m);A1];
%size(A1)
%size(Theta2)
A2=Theta2*A1;
sigmoid(A2);
[q,p]=max(A2,[],1);
p=p';
三、总结
算是一次承上启下的作业。
承上部分是多元分类,是一种效率很低但是很直观的分类方法,就是二元分类的拓展罢了。
启下部分是神经网络,目前学上去与我专业课的电路有异曲同工之妙。都是分模块输入输出。