假设我们有一个训练图片集10000*3072,也就是10000张像素为3072的图片,有一个测试图片集的图片100*3072,测试和训练图片集总共的图片类型有10种(这里图片类型指的是图片内容的类型,如:图片内容为猫、狗等)。我们将某一张训练图片命名为Tn,将一张测试图片命名为Cm,将一个图片的类型命名为La。
我们在1中说了SVM算法的基本思想,但是我们也可以从中发现一些问题。1.每次要通过计算最终的准确率才能知道当前的W是否变好了,这样效率太低了。2.修改W的时候我们只是在尝试,如果能知道当前具体的下降趋势是不是速度就更快了呢?接下来的一节我们就会解决上面的问题。
1.公式:
损失函数
- 2.解释:
- 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只对训练图片集的预测正确率高,对测试图片集的预测正确率很低,这个现象就被称为————过拟合**,那么我们如何解决这个问题呢?这就要**正则项**出马了
正则化公式
,这几个公式就是常用的正则项,我们直接拿来使用就好了。
dw
- 2.我们得到了**dW**之后,优化的公式就出来了,我们需要不断更改**W**使得**损失函数**的结果向0靠近,所以优化函数是这样的:
优化函数
,注意这里还有一个参数learning_rate被称为学习率,这个学习率就表示我们在通往山谷的路上迈的步子有多的大,如果太大的话就越过山谷到另一边山坡去了,如果太小我们下降的又太慢,所以这是一个超参数,需要我们多试试找到最优结果。
2.我的项目目录:
项目目录
全局代码1
全局代码2
训练代码
- 1.我们进入了训练**W**的代码中,先是获取了训练集图片数量**num\_train**,图片种类数量**num\_classes**。然后随机初始化了**W**。
- 2.定义一个**loss\_history**用于储存每次迭代的损失值
- 3.进入一个循环,被循环的参数是**num\_iters**,也就是前面说的**W**需要迭代的次数
- 1.从训练集**x\_train和y\_train**中再取出**batch\_size**数量的数据集,再次减少训练时间。
- 2.将再次减少的训练集**X\_batch和y\_batch**还有**正则参数reg**传入**loss()**方法中以获取损失值**loss**和**W**的趋势**grad,也就是dW**。
计算loss
- 1.有两种方式来计算损失值**loss**和**W**的趋势**dW**,我这里选择简单的方式。
- 2.先定义了一个与**W**同矩阵大小的**dW**,获取了训练集图片数量和图片种类数量**num\_train和num\_classes**
- 3.初始化**loss为0**
- 4.进入循环,循环参数是训练集图片数量**num\_train**
- 1.计算当前**W**和当前训练图片**X[i]**在各个图片种类下的分数**scores**
- 2.获得当前训练图片**X[i]**真实图片种类的分数**correct\_class\_score**
- 3.进入循环,循环参数是图片种类数量**num\_classes**
- 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求过偏导数之后的Xi和-Xi
- 5.退出两层循环,此时计算出了全部训练图片的**dW和loss**之和,所以**dW和loss**需要除以**num\_train**,再为**loss和dW**加上正则项。
- 6.返回**dW和loss**
- 3.获得了**loss**和**W**的趋势**grad,也就是dW**之后,将本次**loss**储存在了**loss\_history**中
- 4.根据公式:
优化函数
,对W进行优化
- 5.这样一直循环直至迭代次数**num\_iters**完成
- 4.**W**的循环迭代结束之后,返回上一层
- 2.在当前**学习率和正则参数**下,将**W**训练完毕之后,分别使用**x\_train和x\_val**来进行预测并算出准确率**train\_accuracy和val\_accuracy**。
- 3.一直循环上面的操作,直至找到最大的正确率下的**best\_svm和best\_val**,并将历次的**train\_accuracy,val\_accuracy**储存在**results**中。
- 4.结束两层循环11.输出10中历次循环的
结果1
结果2
结果3
我们前面做的了Svm算法就是不断根据损失函数对于Wi和Wj这两个分量的偏导数来优化W的算法。这里的损失函数定义了W的好坏,如果我们换一个损失函数的定义方式,会不会有不一样的结果呢?我们接下来要讲的就是另一种损失函数的算法SoftMax
1.损失函数:
softmax损失函数
- 1.解释:这里的**Li**公式我们只要看**Log**里面的东西就好了,这里的**j**表示某一个图片种类,**yi**表示该训练图片的真实种类,所以里面的东西就很好理解了,**即该训练图片真实种类的分数在总的分数中的占比**。最后Log内部算出的会是一个百分比,所以使用**Log**将其转化一下。
- 2.当然最终的**损失函数L**,还需要算所有**Li**的均值2.损失函数的梯度,这里就是对
softmax偏导