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

首先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/

【ufldl tutorial】Softmax Regression的更多相关文章

  1. 【ufldl tutorial】Convolution and Pooling

    卷积的实现: 对于每幅图像,每个filter,首先从W中取出对应的filter: filter = squeeze(W(:,:,filterNum)); 接下来startercode里面将filter ...

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

    ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 [emacs tutorial]是熟悉 emacs 的入门资料.一共几十个命令,不需硬记,勤练即可. 翻页命 ...

  3. 【深度学习】softmax回归——原理、one-hot编码、结构和运算、交叉熵损失

    1. softmax回归是分类问题 回归(Regression)是用于预测某个值为"多少"的问题,如房屋的价格.患者住院的天数等. 分类(Classification)不是问&qu ...

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

    Softmax Regression Tutorial地址:http://ufldl.stanford.edu/tutorial/supervised/SoftmaxRegression/ 从本节開始 ...

  5. 【DeepLearning】Exercise:Softmax Regression

    Exercise:Softmax Regression 习题的链接:Exercise:Softmax Regression softmaxCost.m function [cost, grad] = ...

  6. 【TensorFlow-windows】(一)实现Softmax Regression进行手写数字识别(mnist)

    博文主要内容有: 1.softmax regression的TensorFlow实现代码(教科书级的代码注释) 2.该实现中的函数总结 平台: 1.windows 10 64位 2.Anaconda3 ...

  7. 【UFLDL】Exercise: Convolutional Neural Network

    这个exercise需要完成cnn中的forward pass,cost,error和gradient的计算.需要弄清楚每一层的以上四个步骤的原理,并且要充分利用matlab的矩阵运算.大概把过程总结 ...

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

    ufldl学习笔记与编程作业:Softmax Regression(softmax回归) ufldl出了新教程.感觉比之前的好,从基础讲起.系统清晰,又有编程实践. 在deep learning高质量 ...

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

    ufldl学习笔记与编程作业:Softmax Regression(vectorization加速) ufldl出了新教程,感觉比之前的好.从基础讲起.系统清晰,又有编程实践. 在deep learn ...

随机推荐

  1. c#之习题

    int n = 1; double zg = 1; double rb = 4; while (zg < rb) { n++; int k = 1; while (k <= 4) { k+ ...

  2. SharePoint API测试系列——对Recorded Item做OM操作(委托的妙用)

    转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 对Recorded Item动态调用OM Methods进行测试,界面如下: 输入Site的URL ...

  3. UML的概念模型

    为 了理解UML,需要形成该语言的概念模型,这要求学习建模的3个要素:UML的基本构造块.支配这些构造块如何放在一起的规则和一些运用于整个UML的公 共机制.如果掌握了这些思想,就能够读懂UML模型, ...

  4. promise理解

    每个操作都返回一样的promise对象,保证链式操作 每个链式都通过then方法 每个操作内部允许犯错,出了错误,统一由catch error处理 操作内部,也可以是一个操作链,通过reject或re ...

  5. http_load的安装及使用方法

    http_load 程序非常小,解压后也不到100K http_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工 具,它可以以一个单一的进程运行,一般不会 ...

  6. C#在泛型类中,通过表达式树构造lambda表达式

    场景 最近对爬虫的数据库架构做调整,需要将数据迁移到MongoDB上去,需要重新实现一个针对MongoDB的Dao泛型类,好吧,动手开工,当实现删除操作的时候问题来了. 我们的删除操作定义如下:voi ...

  7. mysql查询中通配符的使用

    mysql查询中通配符的使用     在mysql查询中经常会使用通配符,并且mysql的通配符和pgsql的存在区别(稍候再讨论),而且mysql中还可以使用正则表达式. SQL模式匹配: “_” ...

  8. 统计map上的read数量

    samtools flagstat /SRA111111/SRR111222/accepted_hits.bam 78406056 + 0 in total (QC-passed reads + QC ...

  9. PigSPS: a database for pig SNPs and signatures of positive selection

    URL: http://www.ibiomedical.net/pigsps/ keywords: pig, boar, SNP, positive selection, database, db, ...

  10. C#窗体->>随机四则运算(计算表达式)

    用户需求: 程序能接收用户输入的整数答案,并判断对错程序结束时,统计出答对.答错的题目数量.补充说明:0——10的整数是随机生成的用户可以选择四则运算中的一种用户可以结束程序的运行,并显示统计结果.在 ...