• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

Recommended Posts

本专栏的文章是我在斯坦福学习cs231n课程的笔记和体会。同时,也欢迎大家访问我的个人博客,查看这篇文章。

目录函数支持向量机SVM正则化正则化常用正则化函数多元Logistic回归(softmax)优化梯度递减计算梯度数值梯度解析梯度递减过程小批量随机递减参考

损失函数

如何确定W,如何利用训练数据得到一个好的W。

损失函数:定义一个函数,输入W,然后定量计算W的质量

支持向量机SVM

给定一个样本\((x_i,y_i)\),其中\(x_i\)是一个图片,\(y_i\)是图片真正对应的标签,是那种,I代表训练集中的第I个样本。表示为$ $ l _ i=\ sum _ {j \ neq y _ i} max (0,s _ j-s _ {y _ i} 1) $,s为分类器对该图片计算出的每一类的得分。

这个公式还表明,如果真实类的得分比其他类的得分多1,那么这个项目的损失为0。那么为什么选择大于1呢?其实1是一个可以任意确定的常数。我们不在乎损失函数中分数的绝对值,而是在乎分数的绝对差值,这样分类正确的分数远大于分类不正确的分数。所以这个常数项1不是很重要。如果W被放大缩小,那么每个分数也会被放大缩小,这个常数就消失了。

示例:

image-20220424153133348

分别计算每个样本的损耗值,求平均值。$ $ l=\ d frac { 1 } { n } \ sum n _ { I=1 } l _ I $ $此值反映了我们的分类器对数据集的当前分类效果。

如果汽车的分类得分发生变化,损失函数值会发生变化吗?

不,如果汽车的得分仍然大于其他类别的得分,那么损失函数值仍然为0。

损失函数的最大值和最小值是什么?

最小值为0,即所有样本的正确类别的得分远大于其他类别的得分,最大值可能为无穷大。

如果初始W很小且均匀分布,所有S都是0,那么一个样本的损失函数值是多少?

答案是类别数-1,因为正确的类别是0,其他n-1个不正确的类别是1。

如果我们在计算损失的时候,也加入了正确的类别(即加入j=\(y_i\)的情况),损失函数会有怎样的变化?

结果多了1个。

如果在计算样本的损失值时,平均值不是总和呢?

不会改变。

如果损失值是平方,分类会有怎样的变化?

它会变成另一个损失函数,从线性变成非线性。

代码:

def L _ i _矢量化(x,y,W):

分数=W.dot(x)

margins=np.maximum(0,scores - scores[y] 1)

边距[y]=0

loss_i=np.sum(毛利)

回波损耗_i

正则化

如果我们找到一个损失值为0的W,我们应该使用它吗?

实际上,我们并不关心函数在训练数据集上的拟合程度,而是更关心在测试数据集上的性能。如果你告诉分类器,你的唯一目标是拟合训练数据集,而分类器尽最大努力去拟合训练数据,甚至达到完美的程度,这其实是一个非常糟糕的情况。这时候如果加入一些新的数据,这条拟合曲线就很难拟合这些新的点。因此我们更加希望,分类器是那个绿色的线而非蓝色的完全拟合所有训练数据的线

增加一个正则项R(W)来鼓励模型以某种方式选择一个更简单的W。这里的简单性取决于任务的规模和模型的种类。奥卡姆剃刀理论:如果你有多个假设可以解释你的观察结果,一般来说,你应该选择最简单的一个,因为它可以用来解释未来新的观察结果。

442-20220503124823329-1964321190.png"/>

使用超参数\(\lambda\)来平衡损失函数中的数据损失项和正则项。

正则化的主要目的就是减轻模型的复杂度,而不是去视图拟合数据

常用的正则化函数

最常用的就是L2正则化 ,L2,\(\sum_k\sum_lW_{k,l}^2\)

多项逻辑斯蒂回归(softmax)

在SVM中,我们并没有过多的关注得分,只是想要真实的正确类别的分数要比不正确的分类得分要高才好。并没有解释这些分数的真实含义,在softmax中将对这些得分进行一些计算以便得到分数的概率分布。

公式为 $$ L_i = -log(\dfrac{e{s_{y_i}}}{\sum_je{s_j}})$$,其中i为第i个样本,$ y_i $表示正确的类别,S为各个类别的分数

流程:

  1. 将得分进行指数运算
  2. 进行归一化处理
  3. 计算正确类别的损失,我们使用log进行运算,log是单调函数,加上负号就和我们想要的意思一致

image-20220427204759488

下面是几个问题

  • softmax的最大值和最小值
  • 最小值:0,最大值:无穷。正确类别的概率为1取最小值,概率为0取最大值。实际中不可能取到,因为只有分数为无穷时才有可能
  • 比较SVM和softmax这两个函数,如果我将正确的分类的分数提高一点,那么会对函数的结果有什么影响
  • 我们已经分析过,对于SVM没有影响。但是对于softmax是会改变结果的,因为softmax是将所有的分数进行一个概率分布,如果正确的分类的分数提高,那么他在概率分布中占比就更大。这两种函数的策略有些不同,SVM是要求正确的分类分数比不正确的大于一个边界值就可以了,就不去管他了,而softmax是试着不断去提高正确分类的概率质量,并把不正确的分值降低。实际中这两个函数的差异不会造成很大的影响。

优化

我们已经通过数据集利用线性分类器计算出得分,并根据得分和数据真实的分类利用损失函数计算出损失值,通常会增加正则化操作,试图在训练数据之间进行权衡。那么下一步就是如何优化W,如何使W损失最小化?

image-20220430214906337

实践中,我们使用不同的迭代方法进行优化

最简单粗暴的想法可能就是随机搜索,就是盲搜,这是一个很烂的算法,这里不多介绍。

梯度下降

比如说我们在山顶,要以最快的速度下山,我们可以每一次都沿着最陡峭的方向走一步,这样一直走到山底。在数学中,我们可以用梯度这个概念来表示最陡的方向,梯度指向函数增加最快的方向,负梯度就是函数减小最快的方向。

image-20220430224651448

对于多元的情况,这个时候我们需要求的东西扩展成每个方向的『偏导数』,然后把它们合在一块组成梯度向量。

演示图片

计算梯度

数值梯度

从定义上来算,也叫有限差分法,就是对于每一个维度在原始数值上加上一个很小的h,然后求出这个维度上的偏导,最后组合在一起得到梯度grad

def eval_numerical_gradient(f, x):
  """ 
  一个最基本的计算x点上f的梯度的算法 
  - f 为参数为x的函数
  - x 是一个numpy的vector
  """ 
  fx = f(x) # 计算原始点上函数值
  grad = np.zeros(x.shape)
  h = 0.00001
  # 对x的每个维度都计算一遍
  it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
  while not it.finished:
    # 计算x+h处的函数值
    ix = it.multi_index
    old_value = x[ix]
    x[ix] = old_value + h # 加h
    fxh = f(x) # 计算f(x + h)
    x[ix] = old_value # 存储之前的函数值
    # 计算偏导数
    grad[ix] = (fxh - fx) / h # 斜率
    it.iternext() # 开始下一个维度上的偏导计算
  return grad

实际计算中,这个方法的问题很大。最突出的就是效率问题,比如在我们的CIFAR-10例子中,我们总共有30730个参数,因此我们单次迭代总共就需要计算30730次损失函数。这个问题在之后会提到的神经网络中更为严重,很可能两层神经元之间就有百万级别的参数权重,很低下

解析梯度

image-20220430230617836

直接使用微积分的知识,写下梯度的表达式,这里梯度的表达式就是每个参数的偏导数,每次计算只需要带入公式即可。从W开始,计算dW或每一步的梯度。

实际中,我们不会直接使用数值梯度的方法,但是我们可以使用数值梯度的方法来验证解析梯度的准确性。

再举一个小例子(这里的反向传播法暂时不介绍):对于函数\(f(x,y,z)=(x+y)z\)

# first method   解析法
def grad1(x,y,z):
    dx = z
    dy = z
    dz = (x+y)
    return (dx,dy,dz)
# second method  数值法
def grad2(x,y,z,epi): 
    # dx
    fx1 = (x+epi+y)*z
    fx2 = (x-epi+y)*z
    dx = (fx1-fx2)/(2*epi)
    # dy
    fy1 = (x+y+epi)*z
    fy2 = (x+y-epi)*z
    dy = (fy1-fy2)/(2*epi)
    # dz
    fz1 = (x+y)*(z+epi)
    fz2 = (x+y)*(z-epi)
    dz = (fz1-fz2)/(2*epi)
    return (dx,dy,dz)
# third method 反向传播法
def grad3(x,y,z): 
    # forward
    p = x+y;
    f = p*z;    
    # backward
    dp = z
    dz = p
    dx = 1 * dp
    dy = 1 * dp
    return (dx,dy,dz)
 
print ("<df/dx,df/dy,df/dz>: %.2f %.2f %.2f"%(grad1(1,2,3)))       
print ("<df/dx,df/dy,df/dz>: %.2f %.2f %.2f"%(grad2(1,2,3,1e-5)))
print ("<df/dx,df/dy,df/dz>: %.2f %.2f %.2f"%(grad3(1,2,3)))

result

梯度下降过程

在梯度下降算法中,首先我们初始化W为随机值,当为真时,我们计算损失和梯度,然后向着梯度相反的方向更新权重W值。

每次更新的步长是一个超参数,又叫学习率,就相当于每次选择最陡峭的方向走一步,这一步走多长。

其实在每次走一步时,会有很多种比较高级一点更新的法则,其本质就是梯度下降,每一步都试着朝着下坡走,这个后面详细讨论。

小批量随机下降

每次迭代时并不会去选择所有的数据集,这样的成本会很高,速度很慢。

随机梯度下降,每次迭代时,并不选择全部的样本,而是随机选择小部分的样本(minibatch),一般为2的次幂,利用小批量的数据来估计误差总和以及实际梯度

参考资料

  • 深度学习与计算机视觉(三)最优化与梯度下降
  • 计算梯度的三种方法: 数值法,解析法,反向传播法

欢迎大家可以访问我的个人博客,查看本篇文章

Link to comment
Share on other sites