Andrew Ng 机器学习课程笔记 ———— 通过简单的多元分类器解决手写数字识别问题

2018/03/06 17:06
阅读数 18

(咸鱼一只 QAQ  笔记更多是为了记录自己学习路上的困扰 ,和对近期学习的总结  由于才开始机器学习方面的学习  连机器学习的门都没入 hhhh  ,肯定会有许多纰漏(^∇^*)  希望大佬们别见怪   当然最好 能给菜鸡我指正下 QP 感激不尽~\(≧▽≦)/~)

 


问题描述: 给定 一定像素大小的手写数字图片 ,程序能够初步识别出数字的值

思路:通过对大量手写图片和对应值的数据集进行训练 ,构建逻辑回归(Logistic Regression) ,并应用于多元分类器上(K = 10)

实现:

出于对Andrew教授的敬意(其实就是因为我太菜0.0 不会Numpy啥的) ,我选择了Octave/Matlab 作为编程语言。 Andrew Ng 的课后作业给定的数据集是5000个 20 *20 的样例 , 因此对于每一个样例 ,即拥有 20*20 = 400 个像素点 ,即400个特征值 ,先将数据集读入Octave中,并存入 5000*400的矩阵X中,即 m = 5000 , n = 400 , 同时因为这是个分类问题 ,输出值只可能为0 —9 中的一个数  , 即需要设立10个分类器 ,num_labels = 10 (Octave 中下标从1开始 ,因此0实际对应值为10)  。将5000个对应数字值存入向量y中 ,其中y为5000*1的矩阵 。确定好各种基础值后 ,我开始计算代价函数(Cost Function) (10个分类器的代价函数是一样的,本质都是分类), 根据Andrew 第三周课程 ,我已经知道 ,分类问题中的代价函数如下:

其中htheta(x) = sigmoid(thetaT * x(i))  ,其中 sigmoid即为 s型函数 s(x)= 1/(1 + e^ -x) ; 由于上式为数值计算 ,较为庞杂 ,我希望可以通过向量化简化代码和运算 。

运用线性代数知识,不难看出上述求和 转换成向量形式为 J = (-yT * log(htheta(X)) -  (1 - y) * log(1 - htheta(X))) / m   。              

其中 X为5000*400的样本图像矩阵(矩阵每个值对应一个像素点),  y为5000*1的样本数值向量 (每一个样本对应的准确值)。

但通过第三周的学习,我了解到 ,对于复杂的拟合 ,有时候会出现过拟合(Overfitting)的情况 ,影响了预测的效能 ,因此我需要用上Andrew教授教过的Regulazation内容 ,去修正theta的值 ,使拟合的曲线更加平滑 ,更加贴近实际情况,避免出现过度拟合的问题 。

我对J补上了 多项式 ,去减少相应的theta参数 ,修改后的J如下:

J =  (-yT * log(htheta(X)) -  (1 - y) * log(1 - htheta(X))) / m  +lambda * (sum(theta.^2) - theta(1 , :) ^ 2)/ (2 * m) ;(小小吐槽一下博客园贴入代码不支持Matlab QAQ)  其中lambda过大可能会导致不拟合 ,我预设了lambda为0.1

运用微积分 ,计算出相应梯度

同理对之进行 向量化 ,得到

grad = (XT * (sigmoid(X * theta) - y)) / m;

同时为了防止过度拟合 ,我同样对他正则化处理。(注意 Octave中没有仅使矩阵某一行为0的直接操作)

至此 , 我对代价函数的处理已经完毕 , 通过代价函数的计算,传入相关数据X,y和对应参数theta ,lambda ,将返回相应的代价J 和梯度 grad 。

得到了代价函数 ,接下来就是训练数据集的过程。由于有十个分类器 ,因此我想要使用for循环 1:10 ,对每一个分类器单独训练,得到对应的参数 ,再将所得到的10个参数集合并 ,得到总的参数 all_theta 。

注意,训练之前 ,需要将每个样例的特征值前加上一个常数1去修正偏差 ,即X变成5000*401的矩阵,而最后得到的all_theta应为10 * 401的矩阵 。 矩阵的第i行代表第i个分类器对应的参数 。这样我们用每一个样例 x(i) 去乘上 all_theta的转置 ,即可得到这个样例对应每个分类器的值 ,其中最大的值所对应的分类器的索引即是这个样例通过逻辑回归所预测的值 

Andrew Ng教授推荐我们使用作业附带的fmincg()函数 ,但我还是选择了 Octave自带的 fminunc()函数 (因为我自知我自己是写不出来fmincg来的 hhhhhh ),我所做的循环如下:

我们直接使用得到的逻辑回归去反过来预测训练集 预测过程如下:

在Octave中运行完成的代码 ,得到

(hhhhh  乱码警告 !  吸取教训  看来还是得用 ANSI格式 或者老老实实用英文吧 hhh)

 由93.1的准确率和Andrew教授所用94.9的准确率来看 ,果然Octave自带的 fminunc函数 是没有 老师提供的 fmincg函数先进和准确的 ,看来,哪怕是如此入门的分类问题 , 也离不开算法的优化啊 ! 菜鸡QP的路还有好远好远哇!

由于本文是一只刚开始摆弄的菜鸡作为自己的第一篇学习笔记 , 希望大家可以友好的指出我的错误啦 QAQ   希望我可以在接下来一篇篇学习笔记中 ,取得一点一点的进步!~\(≧▽≦)/~

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部