【ufldl tutorial】Softmax Regression

今天太长姿势了,什么叫懂了也写不出代码说的不就是我吗,就那么几行代码居然叽叽歪歪写了一个小时。

首先exercise要实现的是softmax的cost function和gradient,如下图:

(1)

(2)

(3)

下面就来仔细分析怎么不借助for循环高效的实现上面三个函数。

首先P是一个关键,因为在J和梯度中都出现了,所以现在实现P。

可以看到theta和X的乘积是一个十分重要的量,因为在分子分母中都出现了,所以首先计算假设h=exp(θTX),那么h(k,i)就是exp(θ(k)T*x(i))的值了,实际就是计算样本i标签为k的概率,当然是没归一化的。这一句的代码十分简单(为何不支持matlab的代码?有种被歧视了的赶脚=。=):

h = exp(theta‘ * X);

此时要注意的一点是虽然有10个分类,但是通过ufldl的讲解我们知道有一个参数是多余的,更直观的理解就是如果得到了x(i)取前9类的概率,那么取第10类的概率直接用1减去前9类的概率和就得到了,所以theat矩阵是9行,而不是10行。我们得到的h也是9行,和公式里面K=10不一样,所以我们给h加上1行1,至于为什么是1,接下来就知道了。

h = [h;ones(1,m)];

接下来就可以计算P了,我们计算一个矩阵P,使得P(k,i)表示上述公式2的值。可以看到公式2里面的分子就是上面计算过的h(k,i)的值,而分母就是h的第i列的值相加。这里就可以借助bsxfun函数实现:

p = bsxfun(@rdivide,h,sum(h));
logp = log2(p);

bsxfun函数是一个十分高效的函数,上述第一个参数@rdivide表示对h中的每个值做“右除”除法,sum(h)就是上面分析出来的P的分母值,是一个行向量1*m(m是总样本数),即(sum(h))(i)表示h的第i列相加的值,这样bsxfun函数就会自动对h的每一行的每一个元素,都除以sum(h)这一个行向量的对应位置的值。

接下来就可以计算cost function J了。借助sub2ind这个函数实现。ufldl上有对这个函数的解释,这里大概总结以下:对于矩阵A,I=sub2ind(size(A), 1:size(A,1), y);执行后I中存放所有index为(1,y(1)),(2,y(2)),(3,y(3)),...(size(A,1),y(size(A,1)))的元素的index,所以A(I)就是这些元素实际的值了。对于cost function J,我们需要把logp中所有(k,i)位置上的值都拿出来,其中k是x(i)的ground truth的标签,所以我们可以这么写sub2ind函数:

index = sub2ind(size(logp),y,[1:m]);

再把index里面元素在logp中对应的值加起来就是cost function J了:

f = -sum(logp(index));

最后解释一下为什么要给h最后一行补1,我们知道如果h(10,i)接近1,说明分类器认为x(i)取第10类的概率大;如果h(10,i)接近0,说明x(i)分类器不太可能取第10类,如果是其他值,说明分类器“自信度”不高,我们不用考虑。我们只要考虑h(10,i)为1的情况,因为我们只要保证从logp中取(k,i)位置上的元素时候,在h(k,i)位置上接近1的元素(k,i)在logp中被取出来,其他位置上的1并不会给最终的梯度带来影响,因为它们不会被取出来,所以在最初的h的最后一行,即使x(i)不属于第k类,我们把h(k,i)置为1,也不会对后面的运算造成影响。但如果x(i)确实属于第k类,我们把h(k,i)置为1,就保证了这部分误差会被计算到最终的误差J中。



以上计算了cost function J的值,接下来计算梯度g:

首先我们知道上面计算出来的P是一个k*m的矩阵(k是类的数目,m是样本的数量),P(k,i)表示样本x(i)属于第k类的概率,公式3中重要的是怎么求出一个k*m的矩阵yk,使得yk(k,i)表示x(i)是否属于第k类,如果属于,yk(k,i)=1;否则yk(k,i)=0;也就是公式3中减号前面的项,可以用如下代码实现:

 yk = full(sparse(y,1:m,1));

full,sparse函数是非常神奇的。假设我们有一个矩阵A=[1,2,4],那么  full(sparse(A,1:3,1));就生成了如下的一个矩阵:

1     0     0
0     1     0
0     0     0
0     0     1

一般来说如果A是一个1*m的矩阵,那么full(sparse(A,1:m,1))就生成了一个(max(A),m)的矩阵,这个矩阵中(A(i),i)上的元素为1,其他元素都为0。这样我们用

 yk = full(sparse(y,1:m,1));

就可以得到上面要求的yk。

不过呢,y里面是有10个类标的,所以yk其实是一个10*m的矩阵,前面说了,我们只要知道一个样本x为前9类的样本的概率就可以了,所以我们其实只需要yk的前9行,所以要对yk进行一个截短,同样对上面的p也做一个,因为其实p的最后一行是我们手动加上去的,并且在公式3中yk要和p相减,我们需要保证p和yk的维度match。

yk = yk(1:num_classes-1,:);
p = p(1:num_classes-1,:);

最后就可以根据公式3计算梯度了

g = -X * (yk-p)‘;

就这么三个公式,想用代码高效的实现就这么困难,有时候不光要关注idea,更要关注idea的实现。我实现的第一个版本准确率只有87%,这个版本有92%,有时候真的不知道是算法不好,还是实现不好,所以会码是非常重要的!

最后上下结果,总共迭代了232次:

完整的代码可以在我的github上看到。

参考:

【1】http://blog.csdn.net/lingerlanlan/article/details/38425929

【2】http://ufldl.stanford.edu/tutorial/supervised/SoftmaxRegression/

时间: 2024-10-03 22:40:08

【ufldl tutorial】Softmax Regression的相关文章

【ufldl tutorial】Convolution and Pooling

卷积的实现: 对于每幅图像,每个filter,首先从W中取出对应的filter: filter = squeeze(W(:,:,filterNum)); 接下来startercode里面将filter旋转90度并且取出image: % Flip the feature matrix because of the definition of convolution, as explained later filter = rot90(squeeze(filter),2); % Obtain the

emacs 新手笔记(一) —— 阅读【emacs tutorial】

[emacs tutorial]是熟悉 emacs 的入门资料.一共几十个命令,不需硬记,勤练即可. 翻页命令: C-v:向前移动一屏 M-v:向后移动一屏 C-l:重绘屏幕,并将光标所在行置于屏幕的中央 光标控制: C-n:移动到下一行(next) C-p:移动到上一行(previous) C-f:向右移动一个字符(forward) C-b:向左移动一个字符(backward) M-f:向右移动一个词[对中文是移动到下一个标点符号] M-b:向左移动一个词[对中文是移动到上一个标点符号] C-

【machine learning】linear regression

一.曲线拟合 1.问题引入 ①假设现在有一份关于某城市的住房面积与相应房价的数据集 表1    居住面积与房价关系 图1    居住面积与房价关系 那么给定这样一个数据集,我们怎么学习出一个以住房面积大小为自变量的用于预测该城市房价的函数? 问题可形式化为 给定大小为m的训练样本集 我们希望学习的目标函数为 房价预测本质上是回归问题 a.回归分析挖掘自变量与因变量之间的关系 b.有监督的学习问题,所有的样本点都带有目标变量 c.输出变量为连续值,可取任意实数 ②假设现在我们有份更详尽的数据集,它

深度学习 Deep Learning UFLDL 最新Tutorial 学习笔记 5:Softmax Regression

Softmax Regression Tutorial地址:http://ufldl.stanford.edu/tutorial/supervised/SoftmaxRegression/ 从本节开始,难度开始加大了,我将更详细地解释一下这个Tutorial. 1 Softmax Regression 介绍 前面我们已经知道了Logistic Regression,简单的说就判断一个样本属于1或者0,在应用中比如手的识别,那么就是判断一个图片是手还是非手.这就是很简单的分类.事实上,我们只要把L

【转帖】UFLDL Tutorial(the main ideas of Unsupervised Feature Learning and Deep Learning)

UFLDL Tutorial From Ufldl Jump to: navigation, search Description: This tutorial will teach you the main ideas of Unsupervised Feature Learning and Deep Learning.  By working through it, you will also get to implement several feature learning/deep le

【DeepLearning】Exercise:Softmax Regression

Exercise:Softmax Regression 习题的链接:Exercise:Softmax Regression softmaxCost.m function [cost, grad] = softmaxCost(theta, numClasses, inputSize, lambda, data, labels) % numClasses - the number of classes % inputSize - the size N of the input vector % la

【UFLDL】Exercise: Convolutional Neural Network

这个exercise需要完成cnn中的forward pass,cost,error和gradient的计算.需要弄清楚每一层的以上四个步骤的原理,并且要充分利用matlab的矩阵运算.大概把过程总结了一下如下图所示: STEP 1:Implement CNN Objective STEP 1a: Forward Propagation Forward Propagation主要是为了计算输入图片经过神经网络后的输出,这个网络有三层:convolution->pooling->softmax(

ufldl学习笔记与编程作业:Softmax Regression(vectorization加速)

ufldl出了新教程,感觉比之前的好,从基础讲起,系统清晰,又有编程实践. 在deep learning高质量群里面听一些前辈说,不必深究其他机器学习的算法,可以直接来学dl. 于是最近就开始搞这个了,教程加上matlab编程,就是完美啊. 新教程的地址是:http://ufldl.stanford.edu/tutorial/ 本节是对ufldl学习笔记与编程作业:Softmax Regression(softmax回归)版本的改进. 哈哈,把向量化的写法给写出来了,尼玛好快啊.只需要2分钟,2

ufldl学习笔记和编程作业:Softmax Regression(softmax回报)

ufldl学习笔记与编程作业:Softmax Regression(softmax回归) ufldl出了新教程.感觉比之前的好,从基础讲起.系统清晰,又有编程实践. 在deep learning高质量群里面听一些前辈说,不必深究其它机器学习的算法,能够直接来学dl. 于是近期就開始搞这个了.教程加上matlab编程,就是完美啊. 新教程的地址是:http://ufldl.stanford.edu/tutorial/ 本节学习链接:http://ufldl.stanford.edu/tutoria