龙空技术网

cs231n之SVM算法

浮生偷闲 92

前言:

此时咱们对“pythonsvm代码”都比较讲究,各位老铁们都想要了解一些“pythonsvm代码”的相关知识。那么小编同时在网上搜集了一些有关“pythonsvm代码””的相关文章,希望大家能喜欢,看官们一起来学习一下吧!

内容导读

2.修改 W 的时候我们只是在尝试,如果能知道当前具体的下降趋势是不是速度就更快了呢?,注意这里还有一个参数 learning_rate 被称为 学习率 ,这个 学习率就表示我们在通往山谷的路上迈的步子有多的大,如果太大的话就越过山谷到另一边山坡去了,如果太小我们下降的又太慢,所以这是一个超参数,需要我们多试试找到最优结果 。1. 建议结合github代码食用 ,前面6行就不说了,我在上一篇博客中分析过,就是导入模块,然后从文件中读取数据: cs231n之KNN算法 ,只要看里面的第二节代码解析的前两个小结就行了。简单来说就是将每张图片拉伸成一维的矩阵,方便后面进行数据处理。这样的好处是统一量纲,和归一化操作类似,只是没有再除以方差而已 8.接下来两行定义了一系列 学习率和正则参数 ,在后面会使用两层循环找到最高正确率下的 学习率和正则参数 。2.定义一个 loss_history 用于储存每次迭代的损失值 3.进入一个循环,被循环的参数是 num_iters ,也就是前面说的 W 需要迭代的次数 1.从训练集 x_train和y_train 中再取出 batch_size 数量的数据集,再次减少训练时间。

1.环境搭建以及前置条件

1.前置环境:

1.mac

2.pycharm

3.python3

4.Anaconda

2.环境搭建:

1.preference-->project-->project interpreter

2.将Anaconda的解释器当做一个project interpreter添加

1.官网下载并安装Anaconda

2.官网下载并安装pycharm

3.在pycharm中使用Anaconda

4.下载assignment1作业项目并导入pycharm中,作业下载 。

5.下载数据集并解压到assignment1作业项目的 assignment1/cs231n/datasets/中。数据集下载

6.执行数据集中的.sh文件使得数据集可用

3.前置知识:numpy、python、SciPy基础学习,教程

2.SVM知识了解

假设我们有一个训练图片集10000*3072,也就是10000张像素为3072的图片,有一个测试图片集的图片100*3072,测试和训练图片集总共的图片类型有10种(这里图片类型指的是图片内容的类型,如:图片内容为猫、狗等)。我们将某一张训练图片命名为Tn,将一张测试图片命名为Cm,将一个图片的类型命名为La。

1.SVM是什么

1.我们定义一个函数为f(Cm,W)=W*Cm,在这里W为一个3072*10的矩阵。最终这个函数的结果是一个大小为10的数组,这里数组中的每个数字就是Cm这张图片在每个La下的得分,分数最高的La就表示我们预测这张测试图片是这种图片类型。

2.从1中我们可以知道要让我们的预测准确率高,那么W就需要找准。我们有很多方法来寻找一个好的W

1.随机法:不断随机生成W,然后计算准确率,最终试出符合要求的W,但是很明显这种方式效率很低

2.SVM:我们可以先随机初始化一个W,此时可以算出准确率为z1。此时我们可以尝试小幅度修改(整体加一个数或者减一个数)W中的某一行数据,然后再计算准确率z2。如果z1小于z2,那么表示我们修改对了,可以继续这样修改,否则我们需要往反方向修改。以上就是SVM的基本思想。如果把寻找一个最佳的W比作在一座山中寻找最低点的话,那么SVM就是不断尝试沿着下降的路向前走,一直走到山谷最低点。

2.SVM具体实现

我们在1中说了SVM算法的基本思想,但是我们也可以从中发现一些问题。1.每次要通过计算最终的准确率才能知道当前的W是否变好了,这样效率太低了。2.修改W的时候我们只是在尝试,如果能知道当前具体的下降趋势是不是速度就更快了呢?接下来的一节我们就会解决上面的问题。

1.损失函数:为了解决上面说到的第一个问题,我们就定义了一个损失函数来评价当前的W的好坏。

1.我们都知道f(Cm,W)的结果会是一个大小为10的数组,这个数组的下标表示的是La数组中某个图片类型的下标,那么我们就可以将这个数组比作:在W下Tm这张训练图片,在每个图片类型下面的得分。我们这里讲这个得分数组设为S[10]

2.我们都知道每个Tn都会有一个正确的图片类型La我们设为LaM,那么此时对于Tn我们就有衡量这个W是否标准的方法了,用每个S减去LaM(除了LaM本身)再加上一个x(这里的x是一个自定义的数字,可以是1,2等等,这个x是一个阈值,表示LaM的分数到底超过其他S多少才算可以接受),最后将每个的结果求和这样就可以得出一个数字Ls。这里的Ls就是Tn对于W的评价,Ls越大就表示,对于Tn来说这个W越不好,还有一个限制是0<=Ls,当Ls小于0的时候表示这个W对Tn来说已经够好了,所以小于0的Ls都算作0,到这里就是图片中公式Li的解释

3.我们在上面算出了一个Tn对于W的评价Ls,但是光有这一个样本太少了,我们需要让很多的Tn对W进行评价得出大量的Ls,然后去平均值,此时就能得出当前图片训练集对于这个W的评价,到这就是图片中公式L的解释。

4.我们能看见公式中最后还有一个直接定义的项,这个一项被称为正则项。大家可以想想,我们前面获取的评价LsM是基于训练图片集的,但是我们正在需要进行预测的是测试图片集。那么此时就会有个问题我们的W只对训练图片集的预测正确率高,对测试图片集的预测正确率很低,这个现象就被称为————过拟合,那么我们如何解决这个问题呢?这就要正则项出马了

正则化公式

,这几个公式就是常用的正则项,我们直接拿来使用就好了。

1.公式:

损失函数

2.解释:

2.优化函数:为了解决上面提出的第二个问题,我们可以定义一个优化函数,来不断的根据趋势优化我们的W

1.我们首先需要获取到当前W朝着好的方向前进的趋势,这里就要用上前面定义的损失函数了,因为损失函数是关于Wj和Wi的函数,也就是说这两个参数影响着损失函数的走向,而损失函数的结果就表示当前W的好坏程度。如果你知道偏导数的话就可以知道算出损失函数对于Wj和Wi的偏导数dW就是的W当前的趋势。所以便有了这个公式:

dw

2.我们得到了dW之后,优化的公式就出来了,我们需要不断更改W使得损失函数的结果向0靠近,所以优化函数是这样的:

优化函数

,注意这里还有一个参数learning_rate被称为学习率,这个学习率就表示我们在通往山谷的路上迈的步子有多的大,如果太大的话就越过山谷到另一边山坡去了,如果太小我们下降的又太慢,所以这是一个超参数,需要我们多试试找到最优结果。

3.随机梯度下降法:我们现在已经有了优化函数和损失函数,但是我们会发现每一次进行W优化的时候,都要遍历一整个图片训练集,这样效率就会很低,所以我们可以每次训练取一小部分,图片训练集,然后进行训练,这样的话效率就会比较高。一般来说,取的数字都是2的幂

2.SVM代码实现1.我的项目

1.先上一个github吧,会持续更新直到把cs231n课程学习完:cs231n

2.我的项目目录:

项目目录

2.代码分析

全局代码1

全局代码2

1.建议结合github代码食用,前面6行就不说了,我在上一篇博客中分析过,就是导入模块,然后从文件中读取数据:cs231n之KNN算法,只要看里面的第二节代码解析的前两个小结就行了。

2.定义了:

1.num_training:全体训练集数量(num_dev会从其中抽取一定数量的图片用于训练,减少训练时间)

2.num_validation:验证集数量(在不同的学习率和正则参数下使用该验证集获取最高的正确率,最终找到最好的学习率和正则参数)

3.num_test:测试集数量(在获取到最好的学习率和正则参数之后,测试最终的正确率)

4.num_dev:随机训练集数量(用于实现随机化梯度下降的)。

3.接下来三行是从训练数据x_train和y_train中获取验证集数据

4.接下来三行是从训练数据x_train和y_train中获取全体训练集数据

5.接下来三行是从num_training中随机选取随机训练集数据

6.接下来四行表示:将x_train,x_val,x_test,x_dev这些n*32*32*3的图片集,转化成n*3072的矩阵。简单来说就是将每张图片拉伸成一维的矩阵,方便后面进行数据处理。

7.接下来五行表示:将x_train,x_val,x_test,x_dev这些图片集进行去均值处理,简单来说就是计算出x_train全体图片的均值,然后让其他图片集的每张图片邱减去这个均值。这样的好处是统一量纲,和归一化操作类似,只是没有再除以方差而已

8.接下来两行定义了一系列学习率和正则参数,在后面会使用两层循环找到最高正确率下的学习率和正则参数。

9.接下来三行定义了:每个学习率和正则参数下的正确率键值对results,最高的正确率best_val,最高正确率下的SVM对象后面可以之间对测试集进行预测。

10.进入了两层循环,被循环测参数分别是学习率和正则参数

1.我们进入了训练W的代码中,先是获取了训练集图片数量num_train,图片种类数量num_classes。然后随机初始化了W。

2.定义一个loss_history用于储存每次迭代的损失值

3.进入一个循环,被循环的参数是num_iters,也就是前面说的W需要迭代的次数

4.W的循环迭代结束之后,返回上一层

3.获得了loss和W的趋势grad,也就是dW之后,将本次loss储存在了loss_history中

4.根据公式:

优化函数

,对W进行优化

5.这样一直循环直至迭代次数num_iters完成

1.有两种方式来计算损失值loss和W的趋势dW,我这里选择简单的方式。

2.先定义了一个与W同矩阵大小的dW,获取了训练集图片数量和图片种类数量num_train和num_classes

3.初始化loss为0

4.进入循环,循环参数是训练集图片数量num_train

5.退出两层循环,此时计算出了全部训练图片的dW和loss之和,所以dW和loss需要除以num_train,再为loss和dW加上正则项。

6.返回dW和loss

1.如果当前的图片种类j,就是当前训练图片X[i]真实的图片种类y[i],那么由前面损失函数的定义可知,我们不需要继续执行

2.如果1不成立,我们就能计算出对于当前训练图片X[i],在图片种类j下的损失分量margin。

3.由前面损失函数的定义可知loss只需要大于0的margin,所以如果margin小于0,那么就当0处理,接下来就没必要继续了。

4.如果margin大于0,那么为loss加上margin,并且给dW[,j]和dw[,y[i]]都加上公式:

求偏导

对Wj和Wyi求过偏导数之后的X[i]和-X[i]

1.计算当前W和当前训练图片X[i]在各个图片种类下的分数scores

2.获得当前训练图片X[i]真实图片种类的分数correct_class_score

3.进入循环,循环参数是图片种类数量num_classes

1.从训练集x_train和y_train中再取出batch_size数量的数据集,再次减少训练时间。

2.将再次减少的训练集X_batch和y_batch还有正则参数reg传入loss()方法中以获取损失值loss和W的趋势grad,也就是dW。

计算loss

1.在某个学习率和正则参数下,我们创建了一个SVM对象,然后将学习率和正则参数、训练集x_train和y_train、W需要迭代的次数num_iters,传入训练方法中。

训练代码

2.在当前学习率和正则参数下,将W训练完毕之后,分别使用x_train和x_val来进行预测并算出准确率train_accuracy和val_accuracy。

3.一直循环上面的操作,直至找到最大的正确率下的best_svm和best_val,并将历次的train_accuracy,val_accuracy储存在results中。

4.结束两层循环

11.输出10中历次循环的train_accuracy,val_accuracy与学习率和正则参数

12.使用上面找到的最佳的best_svm来预测测试集x_test得到了测试集的准确率test_accuracy并输出

13.获取最佳的best_svm中的W,将其重新转化为n*32*32*3,然后以图片形式输出。

3.结果

1.训练过程中在不同学习率和正则参数下训练好模型后,验证集和训练集进行预测的准确率:

结果1

2.最终测试集的准确率:

结果2

3.W最终学习成的图片:可以看出车子的图片还是有一点大概的模型存在的。

结果3

标签: #pythonsvm代码