文章目录
1. Multi-class Classfication
在逻辑回归的学习中,我们对于多类别分类的处理是将每个类别与非该类别看成一个1v1的分类,对于k个类别则需要训练k个分类器。每个分类器的作用是将该类别与非该类别分开。这里我们对10个数字进行分类,训练10个分类器实现手写数字的识别。
1.1 Dataset
一张图片可以看成由许多像素点组成的矩阵,每个点处的值是其灰度值。将每个图像的矩阵展开成一维行向量,我们就可以得到一个样本矩阵。行数代表样本个数,列数代表图片灰度图的像素点的个数。输出结果y就是其数值。
1.2 Visualizing the data
1.3 Vectorizing logistic regression
向量化可以使回归过程高效。
在之前的练习中,其实我们已经使用了向量化,这里给出数学推导。
在向量化时始终注意各个变量的维数:
θ
是
n
×
1
,
x
是
m
×
n
,
y
是
1
×
n
。
\theta是n\times 1,x是m\times n,y是1\times n。
θ是n×1,x是m×n,y是1×n。
代价函数
J
(
θ
)
=
1
m
∑
i
=
1
m
[
−
y
(
i
)
log
(
h
θ
(
x
(
i
)
)
)
−
(
1
−
y
(
i
)
)
log
(
1
−
h
θ
(
x
(
i
)
)
)
]
\ J(\theta) =\frac{1}{m}\sum_{i=1}^m{\left[-y^{(i)} \log(h_{\theta}(x^{(i)}))- (1-y^{(i)}) \log(1- h_{\theta}(x^{(i)}))\right]}
J(θ)=m1i=1∑m[−y(i)log(hθ(x(i)))−(1−y(i))log(1−hθ(x(i)))]
梯度
∂
J
(
θ
)
∂
θ
j
=
1
m
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
x
j
(
i
)
\frac{\partial J(\theta)}{\partial \theta_j} = \frac{1}{m}\sum_{i=1}^m{\left( h_\theta(x^{(i)})-y^{(i)}\right)x_j^{(i)}}
∂θj∂J(θ)=m1i=1∑m(hθ(x(i))−y(i))xj(i)
代码
J=-1/m*sum(y.*log(sigmoid(X*theta))+(1.-y).*log(1-sigmoid(X*theta)))+lambda/(2*m)*(sum(theta.*theta)-theta(1)^2);
grad=1/m*sum((sigmoid(X*theta)-y).*X)+lambda/m*theta';
grad(1)=1/m*sum((sigmoid(X*theta)-y));
1.4 One-vs-all classication
对于k个类别,需要训练k个分类器。注意这时 Θ \Theta Θ矩阵变成了 n × k ( n 为 参 数 个 数 ) n\times k(n为参数个数) n×k(n为参数个数)。
可以循环k次,每次求出 Θ \Theta Θ矩阵的一列。使用matlab自带的fmincg()函数,调用前面写好的 lrCostFunction()函数。有两点需要注意,一是矩阵y的变化,需要针对不同的列变换成不同的值;二是输入参数 θ \theta θ给lrCostFunction()函数的时候注意维数,应是 n × 1 n\times1 n×1。
代码
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
1.5 Prediction
变量分析
训练得的分类器必须可以泛化到其他样本对其进行预测才有意义。对于我们训练出来的
Θ
\Theta
Θ矩阵,是
400
×
10
400\times 10
400×10的矩阵,400是对
20
×
20
20\times 20
20×20个元素的特征值训练出来的回归曲线的参数值,10代表有10条这样的曲线。
原理
在这个回归曲线下,只有正确的数字的sigmoid()函数值大于0.5,我们认为这回归为1;其他数字在该曲线下的sigmoid()函数值小于0.5,我们认为回归为0。
思路
因此为了预测样本,我们只需使
X
m
×
n
×
Θ
n
×
k
X_{m\times n}\times\Theta_{n\times k}
Xm×n×Θn×k其中
n
n
n为特征个数,
m
m
m为样本个数,
k
k
k为类别个数。并将其代入sigmoid()函数中,得到
m
×
k
m\times k
m×k列的概率矩阵,每一行是一个样本对每一个类别的概率值,此时我们只需返回每一行的最大值的索引就可以完成预测。
predictionOneVsAll()代码
[probablity,p]=max(sigmoid(X*all_theta'),[],2);
求正确率
pred = predictOneVsAll(all_theta, X);
fprintf('\nTraining Set Accuracy: %f\n', mean(double(pred == y)) * 100);
正确率为:
2. Neural Networks
逻辑回归很难处理一些复杂的问题,因为其只是一个线性分类器时分类效果较差;并且添加高阶特征值得到非线性决策边界时,往往计算量很大。
神经网络是较早的一个概念,最初的目的是为了制造模拟大脑的机器。这里我们用其完成分类任务。
2.1 Model representation
神经网络的模型如下图:
第一层是输入层,中间是隐藏层,最后一层是输出层。
2.2 Feedforward propagation and prediction
层与层之间通过矩阵
Θ
\Theta
Θ联系,除第一层外,每一次的输入都是前一层与相应的参数矩阵,每一层的结果都为输入的逻辑回归值再加上偏置单元1。
z
(
j
)
=
Θ
(
j
−
1
)
×
a
(
j
−
1
)
a
(
j
)
=
g
(
z
(
j
)
)
(
a
d
d
a
0
(
j
)
=
1
)
\ z^{(j)}=\Theta^{(j-1)}\times a^{(j-1)} \\ \ a^{(j)}=g(z^{(j)}) \\ \ (add \ \ a^{(j)}_0=1)
z(j)=Θ(j−1)×a(j−1) a(j)=g(z(j)) (add a0(j)=1)
这样的方式也叫前向传播。
代码
z_1 = [ones(m, 1) X];
a_2=sigmoid(z_1*(Theta1'));
z_2 = [ones(m, 1) a_2];
a_3= sigmoid(z_2*Theta2');
对结果进行预测时,同样只需选择每个样本的k个概率值中概率最大的结果即可。
[probability,p]=max(a_3,[],2);
正确率为:
2.3 Presentation
下面可以随机挑选一些样本进行预测,并看一看样本的图片与预测结果是否符合。
代码
% Randomly permute examples
rp = randi(m);
% Predict
pred = predict(Theta1, Theta2, X(rp,:));
fprintf('\nNeural Network Prediction: %d (digit %d)\n', pred, mod(pred, 10));
% Display
displayData(X(rp, :));
结果
总体来看结果较好。