SVM主体思路和代码实现
之前学习的KNN算法属于直接将所有的训练图片数据化,根据图片的像素值进行判断,最简单的NN算法是用与待判断图片的差距最小(距离最近)的那张图片的类别当做此图片的类别,我们不难看到,1NN算法的正确性很差,相较于完全随机的10%的正确率,其正确率也不过只有20%左右,正确率低。我们用KNN算法则是用与其临近的K张图图片进行“投票”,得票最多的类别即为此图片的类别,可以看到,KNN算法有效的排除了某些噪声的干扰,但是主体的思路仍然是直接进行比较,此算法的缺点在于时间复杂度高,即每次判断一张新图片时,我们都需要遍历所有的训练数据,将训练数据的值与待判断题图片的像素值进行比较,而且十分不精确。
SVM算法的特点是需要模型需要经过长时间的训练(例如在本次实践中,训练模型就花了2.5分钟,这还仅仅是在数据规模不是很大的情况下),而之前的KNN不需要任何的训练和迭代过程,所谓的训练,仅仅是将所有的像素值都存在了一个矩阵中进行比较而已。但是SVM的判断过程极其迅速,只需要做一个矩阵乘法,然后找到其中分数最高的类就可以实现,不需要遍历整个训练集,能够更为方便的判断数据,这是SVM相较于KNN在时间性能上比较优秀的地方,此外,在算法的正确性方面,SVM跟KNN比较也有了长足的进步,以下将说明SVM的整个代码流程:
首先:与KNN一样,我们需要将输入的训练集(共有N个元素,M个类)抽象为矩阵存储,然后得到了训练矩阵(N*M),我们通过对训练矩阵进行某种操作,得到一个新的矩阵(W)。此矩阵就是我们计算机所产生的线性分类器模型,对于每一个输入的图片(一个行向量或者一个列向量),我们期望将输入的图片做一个变换(与线性分类器相乘),得到变换后的向量,此向量共有M个元素,每个元素体现了不同的类的得分情况。我们认为,图片在某一类分数越高,则属于这一类的可能性就越大。不妨看下面的图片


(摘自CS231N的课程笔记)
其中b为偏置向量,我们可以考虑为y=kx+b中的b,b不同,则与y轴的截距不同。这样起到的作用是能够让我们的分类器在划出决策边界时可以上下移动,增强其泛化能力。在这个算法中,我们显然期望原本的类别的得分应该尽可能高,事实上,我们后续在线性分类做决策时也是根据这个得分做决策的。但是显然,并不是所有的时候正确的类别的分数都是最高的,像这个例子,本来是猫,但是猫的得分反而是最低的。对于单一照片的分类我们可以认为是偶然的误差,可是我们希望在所训练出的模型尽可能多的满足此项规律,即正确项得分最高,换言之,我们不希望在训练模型的过程中丢失训练样本原本的信息,希望尽可能的保有原来的信息。那么如何衡量我们的训练过后的model是否丢失了一些信息呢?我们就引入一个概念叫做损失函数:损失函数顾名思义,是衡量我们预测值与初始值相差的函数,我们想要知道在训练中到底损失了多少信息,即可以用损失函数来衡量,损失函数有SVM和softmax两种,本篇仅仅讨论SVM损失函数:

我们考虑,对于一个具体的图片,其所属类别一定是确定的,在坐标系中,即在决策边界的外侧,那么我们该如何衡量我们的损失呢?显然,如果我们在经过变换后得到不同类别的分数,此分数可以作为决策依据,那么我们很自然的考虑到如果正确类别的分数要高于其他类别,而且分数高出一个安全的边界,那么这种情况下,我们显然就十分满意,因为我们有充足的理由相信,这个图片我们判断的是对的,那么如果这张图片是我们的训练集中的元素,则可以认定为:我们训练出的model并没有磨灭掉其信息,其属性仍然存在,那么此时,我们就认为没有损失。由上面的文字叙述,我们可以得到以下的数学表达式:

其中,Li即为对于第i个样例的损失函数,值得注意的是,我们规定了j≠yi是因为我们需要判断正确的类与错误类的得分差,正确类在这里起到的是比较作用,j=yi的情况没有意义!

我们希望尽可能多的数据,其错误类别都要尽可能的在绿色区域,而正确类别的分数都要尽可能在蓝色区域,那么此时正确和错误的差就有一个安全的delta,此时我们就不需要积累损失,显然,损失函数衡量了我们对于原本训练数据的正确性的满意程度,或者说损失了多少信息。显然,我们接下来要做的就是尽可能的减少损失函数,当然最优的可能性是损失函数恰好为0,即没有损失任何信息!但是显然我们遇到了一个问题,那就是可能不只有一个W符合我们的要求,如果有一个W能够完美符合我们所有的要求,即损失函数为0,那么对于W的任意倍数也都满足这个条件,显然是因为我们SVM损失函数所看中的,仅仅是数据之间的绝对差异。为了解决W不确定的问题,我们引入正则项的概念,正则项可以起到简化模型的作用。我们希望用一些偏好去唯一确定W,我们可以采取用正则惩罚项R(W)扩大损失值的方法:最常见的正则化惩罚是平方l2范数,它通过对所有元素二次惩罚来阻止大的权值:

于是我们的损失函数可以定义为一下的样子:

值得注意的是,前面的部分为所有损失函数的平均值,后面为正则项。我们期望上面的式子达到最小值,观察上式不难发现:有几个超参数,其中一个为W,还有一个安全边界delta(实际上delta=1即可,具体证明过程参见cs231n的课程介绍),另一个则是正则惩罚项的系数λ。我们可以采用K折交叉验证的方式去确定λ超参数。显然,不同的超参数的取值显著性的影响了我们分类器的性能,也即分类的准确性,那么接下来我们需要确定W到底该如何选取。
我们可以采用动态的方式去确定W,具体的实现思路如下:我们可以先随机一个W矩阵,里面的元素完全随机,然后计算出此时的损失函数值以及当前的梯度。我们考虑梯度下降法(SGD),假定我们在一个山谷中,我们想要往山下走,我们显然最容易想到的办法就是,找到当前位置最陡的地方,然后迈开步子往下走,每次走之前,都调整方向为最陡的地方,那么显然我们可以走到山底。此算法的思想也同样。我们计算出当前的梯度,然后每次往梯度的相反方向移动一定的步长,移动一定次数。每次移动完得到一个新的损失函数,与当前存储最优的损失值比较,如果当前的更优,则更新。
SVM主体思路和代码实现的更多相关文章
- ASP.NET 大文件下载的实现思路及代码
文件下载是一个网站最基本的功能,ASP.NET网站的文件下载功能实现也很简单,但是如果遇到大文件的下载而不做特殊处理的话,那将会出现不可预料的后果.本文就基于ASP.NET提供大文件下载的实现思路及代 ...
- 【转】Android自定义Adapter的ListView的思路及代码
原文网址:http://www.jb51.net/article/37236.htm Android自定义Adapter的ListView的思路及代码,需要的朋友可以参考一下 在开发中,我们经常使 ...
- HTML5绘制矩形和圆形并且还有获取在这个图层内的坐标的思路和代码 - feilong_12的专栏 - 博客频道 - CSDN.NET
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- SVM 之 MATLAB 实现代码
MATLAB 中 SVM 实现 直接上代码 main.m %% Initialize data clear, clc, close all; load('data.mat'); y(y == 0) = ...
- 用Java实现断点续传的基本思路和代码
用Java实现断点续传的基本思路和代码 URL url = new URL(http://www.oschina.net/no-exist.zip); HttpURLConnection http ...
- 1.Two Sum(c++)(附6ms O(n) accepted 思路和代码)
问题描述: Given an array of integers, return indices of the two numbers such that they add up to a speci ...
- java 26 - 6 网络编程之 TCP协议 传输思路 以及 代码
TCP传输 Socket和ServerSocket 建立客户端和服务器 建立连接后,通过Socket中的IO流进行数据的传输 关闭socket 同样,客户端与服务器是两个独立的应用程序 TCP协议发送 ...
- n皇后2种解题思路与代码-Java与C++实现
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了n皇后问题的解题思路,并分别用java和c++实现了过程,最后,对于算法改进 ...
- Objective-C运行时编程 - 实现自动化description方法的思路及代码示例
发布自米高 | Michael - 博客园,源地址:http://www.cnblogs.com/michaellfx/p/4232205.html,转载请注明. 本文结构 基础实现 性能优化 参考 ...
- iOS高仿城觅应用客户端项目(开发思路和代码)
这是一款非常完整的一个ios项目,基本实现了我们常用的一些功能了,而且界面设计个人感觉还是挺不错的,是一个不错的学习ios项目,喜欢的朋友可以参考一下吧. 项目展示,由于没有数据,所以所有的cell显 ...
随机推荐
- [网鼎杯 2018]Fakebook
1.解题过程 1.sql注入 访问web页面有一个login和join 的递归缩写.在开发这种语言时,YAML的意思其实是 ...
- vue2升级vue3:vue-i18n国际化异步按需加载
vue2异步加载之前说过,vue3还是之前的方法,只是把 i18n.setLocaleMessage改为i18n.global.setLocaleMessage 但是本文还是详细说一遍: 为什么需要异 ...
- 【LeetCode贪心#09】用最少数量的箭引爆气球(涉及区间重叠情况判断)
用最少数量的箭引爆气球 力扣题目链接(opens new window) 在二维空间中有许多球形的气球.对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标.由于它是水平的,所以纵坐标并不重 ...
- Maven 的仓库、周期和插件
一.Maven 仓库 在 Maven 的世界中,任何一个依赖.插件或者项目构建的输出,都可以称为构建.Maven 在某个统一的位置存储所有项目的共享的构建,这个统一的位置,我们就称之为仓库.任何的构建 ...
- 更优雅的OrientDB Java API
OrientDB API v1.0.0(OrientDB 3.x) Gitee OrientDB介绍 OrientDB是一个开源的NoSQL数据库管理系统,同时也是一款高性能的图数据库,支持ACID事 ...
- Dijkstra(迪杰斯特拉)算法C++实现&讲解
Dijkstra迪杰斯特拉算法及C++实现 Dijkstra算法是典型的最短路径路由算法,用来计算一个节点到其他所有节点的最短路径.算法的基本思想和流程是:1. 初始化出发点到其它各点的距离dist[ ...
- NodeJS 实战系列:个人开发者应该如何选购云服务
这文章至少值一千元,因为这是我保守估计花出去的冤枉钱(请自行脑补一个苦笑的 emoji) 文章中会穿插选择云服务的一些建议,当然也会提供一些"薅羊毛"的技巧.不过在此之前我们要想清 ...
- 系统评价——主成分分析PCA的R语言实现(六)
主成分分析(Principal Component Analysis,PCA),是将多个变量通过线性变换以选出较少个数重要变量的一种多元统计分析方法,起到数据约减和集成的作用.在许多领域的研究与应用中 ...
- python之修改本地Ip地址
安装模块pip install wmi # -*- coding: cp936 -*- # # FileName: ModifyIP.py # Date : 2008-01-15 # import w ...