cs231n学习笔记(二)图像分类
图像分类可说是计算机视觉中的基础任务同时也是核心任务,做好分类可为检测,分割等高阶任务打好基础。
本节课主要讲了两个内容,K近邻和线性分类器,都是以猫的分类为例。
一. K近邻
以猫的分类为例,一张含有猫的图片,也不过就是一堆像素点

问题就在于给你一堆点,如何判断出是一只猫,在很久很久以前,这还真是个超级难题,何况不同的猫,像素点完全不一致

具体来说可有以下几种
光照,目标的形变,遮挡,背景杂乱,类内差异等等。




如何利用K近邻算法解决这一问题呢,K近邻,就是将你要判别的目标与已有的大量目标进行比较,与谁最近,就是哪一类,有点物以类聚的意思,不过,只选
取最近的一张作为参照有致命缺陷,保不准就有哪只狗与该目标相近,于是你就把这只猫判断为狗了,所以保险起见,会取最近的K张图片作为参照,其中哪一类
最多,就归属于哪一类,这种做法难说完美,不过比一张靠谱多了。
下面以cifar-10数据集为例展示下k近邻算法。


cifar-10数据集包含10类目标,图像尺寸均为32x32,在充满着高清无码大图的现代社会,着实有些复古。
左图就是数据集的一个图示,右图是根据测试图片选取的10张最近图像,由于图像太小,有些看不清。
那么什么样的图像是比较接近的,或者说如何测量两张图象的距离呢
一种测距方式是L1距离,也叫曼哈顿距离,举例来说,坐标系中两个点(1,1)和(2,2),L1=(2-1)+(2-1)=2,通俗点说你只能直来直去,不能斜着来。
不过对于图像而言,L1并不是一种合适的测距方式,图像不过是一堆像素,你完全可以构造两个L1距离相同的图像,其像素排列却是有很多变化。
像下面这样,右侧三张图与最左侧的距离是一样的,然而三张图却各有不同。

具体计算方式可以像下面这样。

L2距离也许是一种更合适的方式,L2距离,也称欧式距离,L2=√((2-1)**2+(2-1)**2)=√2
在课程的k近邻算法展示主页上,可以自行感受下L1与L2的区别,http://vision.stanford.edu/teaching/cs231n-demos/knn/
除了距离的度量方式,K值的选择也是一个关键因素,很大程度上决定着k近邻算法的好坏,通常不会取为1,只参照一张最相近的的图像来判断测试图像有很大的偶然性。
下图是最好的说明。

在上图中,不同颜色代表不同类别,标出的点是训练数据集,那些没有点的颜色区代表你的测试图像,根据最近邻原则分类,并上色。
可以看到,k=1时类别边界崎岖不平,有些突起已经深入其它类内,显然不合理,再注意绿色中间的黄色区域,代表着该点周围的点被归为黄色类,只因为与该黄色点最近,
显然也是错误的,k=1时分类效果易受噪声影响,具有偶然性。随着k的加大,类别边界趋于平滑,给人的感觉也更加合理,出现的白色区域根据上面的演示网址所说,是投票
数均等的区域,就是无法决策的区域。
那么如何选择测距方式和K值呢,在机器学习里,这些无法训练得来,需要手动设定的参数成为超参数,超参数的设置需要通过实验试探得到,具体需要根据数据集划分来决定。

如上图所示,数据集最佳划分为训练集,验证集,测试集,仅有训练集和验证集都无法保证良好的泛化能力(也就是应用在其它未出现过的数据上),当然,有测试集也无法一定确保良好的泛化能力,但还是比前两个要好很多。
还有一种划分方式为交叉验证,一般用于小型数据集,数据集既能用来训练,又能用来验证。

下图是针对k近邻的5折交叉验证方式,k=7时取得最好结果。

最后总结下,k近邻作为一种简单的分类算法,有着其天然缺陷,一是k值的设置需要实验来确定,二是需要事先存储训练数据集以用来分类,三是致命的一点,每次测试都需要与所有数据进行距离计算,太耗计算资源。
那么,有没有其它办法呢,有,就是接下来要讲的线性分类器。
二.线性分类器
线性分类器基于简单的代数运算,就是相乘相加,以一张猫的图片为例,每一个像素点都有像素值,对每一个点乘以一个权重再相加,就可以输出一个标量值,当你为这个值赋予一定含义的时候,比如正代表动物,负代表其它,那它就构成了一个简单的线性分类器。

同样道理,你也可以输出一个向量,如果进行10分类,则可以输出10维向量。
再具体点,像下面这样。

下面这样

可以将整幅图像看成高维空间中的一点,线性分类器就是点与点之间的分类平面,如果是猫狗二分类,猫的点在一边,狗的点在另一边,中间是分类平面。
画出来就像下面这样。

有了这样的想法,下一步就是设置合适的权重w与偏置b,如何设置涉及到损失函数与最优化的学问,那是下堂课要讲的故事。
cs231n学习笔记(二)图像分类的更多相关文章
- WPF的Binding学习笔记(二)
原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...
- AJax 学习笔记二(onreadystatechange的作用)
AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...
- [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计
源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...
- JMX学习笔记(二)-Notification
Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...
- java之jvm学习笔记二(类装载器的体系结构)
java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...
- Java IO学习笔记二
Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...
- 《SQL必知必会》学习笔记二)
<SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...
- NumPy学习笔记 二
NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(二) indigo tools
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- Redis学习笔记二 (BitMap算法分析与BitCount语法)
Redis学习笔记二 一.BitMap是什么 就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身.我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省 ...
随机推荐
- HADOOP HDFS BALANCER介绍及经验总结(转)
1.集群执行balancer命令,依旧不平衡的原因是什么?该如何解决? 2.尽量不在NameNode上执行start-balancer.sh的原因是什么? 集群平衡介绍 Hadoop的HDFS集群非常 ...
- 嵌入式Linux启动优化手记2 U…
参考一下 原文地址:U-boot优化">嵌入式Linux启动优化手记2 U-boot优化作者:ZhaoJunling 既然不能使用新的U-boot,那就优化一点是一点,慢慢干吧. 1. ...
- Django之Model操作进阶篇
常用参数 null 数据库中字段是否可以为空 db_column 数据库中字段的列名 default 数据库中字段的默认值 primary_key 数据库中字段是否为主键 db_index 数据库中字 ...
- Mac系统下MySql下载MySQL5.7及详细安装流程
一.在浏览器当中输入以下地址 https://dev.mysql.com/downloads/mysql/ 二.进入以下界面:直接点击下面位置 ,选择跳过登录 点过这后直接下载. 三.下载完成后 ...
- SqlServer中把结果集放到到临时表的方法(转)
一. SELECT INTO 1. 使用select into会自动生成临时表,不需要事先创建 select * into #temp from sysobjects 01. 把存储过程结 ...
- session,cookie总结
不同的域名生成的session_id是不一样的,(就算是相同的主域,例如:www.test.com, blog.test.com 都不一样); 相同的主域,不同的二级域名,例如www和blog都是不共 ...
- python中list的使用
1.list(列表)是一种有序的集合,可以随时添加.修改.删除其中的元素. 举例:listClassName = ['Jack','Tom','Mark'] 列表可以根据索引获取元素,如:listCl ...
- scala中的注解
scala中很多注解实现java中关键字的用法 @volatile注解标记为易失的:@transient注解将字段标记为瞬态的:@strictfp注解对应strictfp修饰符:@native注解标记 ...
- 数据结构--树--AVL树
详情查看:http://www.cnblogs.com/skywang12345/p/3577360.html
- C++面试笔记--循环链表,队列,栈,堆
之前已经学会了单链表的建立删除插入转置以及一些普通操作,双链表和单链表差不多,就是多了一个前驱指针,在许多操作中很方便,但是加了一个指针开销应该会大一些,总体上影响不大,这里开始讨论循环链表以及其他的 ...