CS231n 2017 学习笔记01——KNN(K-Nearest Neighbors)
本博客内容来自 Stanford University CS231N 2017 Lecture 2 - Image Classification
课程官网:http://cs231n.stanford.edu/syllabus.html
从课程官网可以查询到更详细的信息,查看视频需要翻墙上YouTube,如果不能翻墙或觉得比较麻烦,也可以从我给出的百度云链接中下载。
课程视频&讲义下载:http://pan.baidu.com/s/1gfu51KJ
问题背景
现在我有一张关于猫的图片,如何让计算机识别出这是只猫呢?
算法思路
我们人眼虽然可以很轻松的辨认出一只猫,但却说不出是怎么辨别的,这个过程对我们来说其实是一个黑匣子。自己说都说不出来,那就更没法用编程的方式写下来了。所以显式定义规则识别的思路不可取。
换一种思考的角度,我们采用一种叫做 “Data-Driven Approach” 的思路 。 这个思路顾名思义,不是显式的定义规则,而是让计算机沉浸在海量的数据中,试图让计算机自己从中学会某种规律,某种技巧。
def train(images, labels):
# Machine learning!
return model def predict(model, test_images):
# Use model to predict labels
return test_labels
在这种情况下,我们的代码结构应该是上面这段代码所呈现的。
首先将海量的数据输送给计算机
- images:代表图片的信息(比如说图片所有像素的rgb值)
- labels:代表图片所属类别的信息(比如说“猫”)
然后计算机通过这海量的数据,训练出一个模型——model
最后给计算机一个刚刚训练好的模型和一张测试用的图片,计算机用接受的模型对图片作出预测。
算法原理
谈起KNN之间,我们先介绍NN(Nearest Neighbor)。
NN的原理及其简单,模型训练的过程就是记住所有的数据以及对应的标签。而在预测的过程,我们将测试图片与已经记住的数据逐一对比,选出相似度最高的一张图片,然后预测他们属于同一类别。
那怎么定义相似度呢?简单的方式有两种——L1距离和L2距离。用两点间的距离代表相似程度,距离越小,二者越相似。
- L1 (Manhattan) distanc
- L2 (Euclidean) distance
为了更直观的表述整个算法,我们想象每一条数据都是二维平面中的一个点。
在这张图中,不同颜色的点代表不同类别的数据,而不同颜色的区域对应了NN的分类结果,颜色相近的点和区域属于同一类别。
这样我们就能看出NN算法的某些缺陷了,图片正中间有一块孤立的黄色区域,而按照常理,这块区域更可能是属于绿色类别,这个黄色的数据点很有可能是因为某些误差造成的。
为了解决这个问题,KNN出现了。
现在我们不是仅考虑最相似的一个数据点,我们考虑最相似的K个数据点,在这K个数据点中,我们采取多数表决的方式决定最终的结果。举个例子,如果我们采用K=3,而与某个区域最接近的三个点中有两个属于黄色标签,一个属于绿色标签,那么这一点属于黄色范围。
上述图片演示了不同K取值的时候形成的分类结果。可以看出当K变大的时候,不同区域之间的分界线变得更加圆滑。而白色的区域则是因为有多个相等的多数表决结果。举个例子,当K=3的时候,如果距离最近的三个点分别是蓝色、红色、绿色,这个区域就被表为白色。
下面的网站是 Stanford 的大佬自己做的,可以动手尝试不同的k取值、不同距离函数的选择对KNN分类结果的影响,有兴趣可以去玩一玩。
http://vision.stanford.edu/teaching/cs231n-demos/knn/
超参数——Hyperparameters
K这样的参数被称之为超参数,超参数也包括距离公式的选择(L1或者L2),它不是可以计算机通过数据能够学习到的,而是在学习之前,由我们人为的规定的。
那么具体而言,如何选择超参数呢?
其实并没有很好的办法,能普遍的方法是尝试,尝试不同的超参数,然后选取效果最好的一组超参数。
那如何衡量效果的好坏呢?
首先我们不能在训练集上衡量,试想,在K=1的KNN算法中,每一个训练数据都被算法“正确”得划分了,准确率是100%,难道这就是最好的超参数么?
显然不是,模型就是在训练集上训练得来的,在训练集上的准确率不具有代表性。
那我们可以将数据划分为训练集、测试集两部分么,在训练集上训练模型,在测试集上选择超参数。
也不行,因为如果根据测试集上的表现选择超参数,我们选择的必然是在测试机上表现最好的超参数,很可能过度拟合测试集,也不具有代表性,不能反映一般情况。
最常规的方式:将数据划分为训练集(training set)、验证集(validation set)、测试集(test set)三部分。在训练集上训练模型,在验证集上选择最合适的超参数,在测试集上测出最终结果。
这里要特别注意,在得出了测试集的结果之后,我们不能根据这个结果再修改参数。尽管这样可能在测试集上得到更高的准确率,但这事实上属于一种“作弊”的行为,我们的模型就又会又过度拟合测试集的问题,丧失了代表性。况且这样做无疑让验证集与测试集的划分毫无意义,他们此时起到了相同的作用,情况又回到了上一种划分方式。
KNN的缺陷
- 训练耗时短,测试耗时长
训练的时候仅需记忆所有数据即可,如果是传递指针的话,能够常数时间内完成 O(1)。
- 两点间距离公式不能提供足够的信息
上图中右侧的三张图片是在左侧图片上分别作出了某些修改后形成的,而通过精心的构建,这三张图片与左侧原本的图片有相同的距离,也就是说距离公式无法将他们区分开。
而事实上,如果进行精心的设计,我们甚至可以让任意两张修改后的图片都与某张照片具有相同的距离。
- 维度灾难
KNN算法翻译过来,是K-最临近算法,而为了能够有效的体现出“最邻近”这个概念,我们势必需要样本能够均匀的分布在整个空间中,将整个空间支撑起来。在一维或者二维的情况下还好说,如果是上图的例子中,一维需要4个样本点,二维需要16个样本点,而到了三维就需要64个样本点。所需的样本数量随着维数的增加呈现指数级增长的趋势,这无疑是灾难性的,所以被称作“维度灾难”。我们一张图片就算很小,10像素*10像素,再乘上rgb三个颜色值,一共有300个数值,这就意味着300维度,而 4300 是一个无法想象的天文数字,我们永远不可能取得足够多的数据。
CS231n 2017 学习笔记01——KNN(K-Nearest Neighbors)的更多相关文章
- opencv2.4.13+python2.7学习笔记--使用 knn对手写数字OCR
阅读对象:熟悉knn.了解opencv和python. 1.knn理论介绍:算法学习笔记:knn理论介绍 2. opencv中knn函数 路径:opencv\sources\modules\ml\in ...
- 软件测试之loadrunner学习笔记-01事务
loadrunner学习笔记-01事务<转载至网络> 事务又称为Transaction,事务是一个点为了衡量某个action的性能,需要在开始和结束位置插入一个范围,定义这样一个事务. 作 ...
- C++ GUI Qt4学习笔记01
C++ GUI Qt4学习笔记01 qtc++signalmakefile文档平台 这一章介绍了如何把基本的C++只是与Qt所提供的功能组合起来创建一些简单的图形用户界面应用程序. 引入两个重要概 ...
- SaToken学习笔记-01
SaToken学习笔记-01 SaToken版本为1.18 如果有排版方面的错误,请查看:传送门 springboot集成 根据官网步骤maven导入依赖 <dependency> < ...
- Redis:学习笔记-01
Redis:学习笔记-01 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 1. Redis入门 2.1 ...
- [机器学习系列] k-近邻算法(K–nearest neighbors)
C++ with Machine Learning -K–nearest neighbors 我本想写C++与人工智能,但是转念一想,人工智能范围太大了,我根本介绍不完也没能力介绍完,所以还是取了他的 ...
- PHP 学习笔记 01
例子: 为什么要学PHP 主观原因: 前段时间在学校处理了毕业的一些事情,回到上海后开始了找工作的旅程.意向工作是WPF开发或者ASP.NET 作为后端的WEB开发. 陆陆续续一直在面试,其中有一家公 ...
- vue.js 2.0 官方文档学习笔记 —— 01. vue 介绍
这是我的vue.js 2.0的学习笔记,采取了将官方文档中的代码集中到一个文件的形式.目的是保存下来,方便自己查阅. !官方文档:https://cn.vuejs.org/v2/guide/ 01. ...
- xml基础学习笔记01
注意:刚刚看了网上对于XML中的标签,节点和元素?到底应该怎么表述?起初我也有这个疑惑,现在我的想法是:下面出现node的应称作节点,节点对象.element应称作元素,毕竟这更符合英文的本意.至于标 ...
随机推荐
- python基础之五大标准数据类型
学习一门语言,往往都是从Hello World开始. 但是笔者认为,在一个黑框框中输出一个"你好,世界"并没有什么了不起,要看透事物的本质,熟悉一门语言,就要了解其底层,就是我们常 ...
- java 读取properties文件总结
一.java读取properties文件总结 在java项目中,操作properties文件是经常要做的,因为很多的配置信息都会写在properties文件中,这里主要是总结使用getResource ...
- 用Atom打造简单的java编译器以及对于可能出现的问题解答
如何用Atom打造简单的javaIDE 自己一直比较喜欢Atom编辑器,前段时间给Atom配置好了C/C++的运行环境,自己心里还是感觉挺好的,最近在学习java ,偶然的机会让我看到了一篇文章,就是 ...
- [js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)
接着上文线条样式[js高手之路] html5 canvas系列教程 - 线条样式(lineWidth,lineCap,lineJoin,setLineDash)继续. canvas提供两种输出文本的方 ...
- AngularJS小结
1.简介 AngularJS 通过 ng-directives 扩展了 HTML. 2.AngularJS指令 ng-app 指令定义一个AngularJS 应用程序的根元素.指令在网页加载完毕时会自 ...
- Java Byte取值范围
Java Byte 的取值范围大家都知道(-128 ~ 127),那么-128 和 127 这两个数是怎么计算的呢? #大学知识回顾: 概念:负数的补码是该 数 绝 对 值 的 原 码 按 位 取 反 ...
- Java EE开发环境——MyEclipse2017破解 和 Tomcat服务器配置
Java EE开发,我们可以搭建如下开发环境: 底层运行环境:jdk 和 jre. Web服务器:Tomcat 后台数据库:SQL Server 可视化集成开发环境:MyEclipse Java EE ...
- eclipse安装lombok插件问题解决
在 java平台上,lombok 提供了简单的注解的形式来帮助我们消除一些必须有但看起来很臃肿的代码, 比如属性的get/set,及对象的toString等方法,特别是相对于 POJO.简单的说,就是 ...
- Druid源码阅读之连接池
概述 Druid是阿里巴巴开源的一个数据库连接池 源码地址.下面简单分析一下连接池是怎么实现的 怎么开始阅读 如果使用过Druid连接池的都只要在Spring配置中配置jdbc的时候配置Driver是 ...
- HDU1305 Immediate Decodability(水题字典树)
巧了,昨天刚刚写了个字典树,手到擒来,233. Problem Description An encoding of a set of symbols is said to be immediatel ...