精华内容
下载资源
问答
  • 贝叶斯网络是一种概率网络,它是基于概率推理的图形化网络,而贝叶斯公式则是这个概率网络的基础。贝叶斯网络是基于概率推理的数学模型,所谓概率推理就是通过一些变量的信息来获取其他的概率...重点对评分函数进行总结
  • 通俗地讲,计算机训练模型的过程,也是一个如人一样学习的过程,每一次模型的训练就是一次尝试,这次尝试都会得出一个结果数值,用来得出这个结果数值的函数称之为评分函数(score function);如小时候做错事情一样,...

     

    小时候,我们在学习的过程中,也可以认为是一个摸索的过程,不断犯错并且一点点修正的过程;通俗地讲,计算机训练模型的过程,也是一个如人一样学习的过程,每一次模型的训练就是一次尝试,这次尝试都会得出一个结果数值,用来得出这个结果数值的函数称之为评分函数(score function);如小时候做错事情一样,犯错越大,就会得到越大的惩罚,计算机评估犯错程度大小的函数称之为代价函数(cost function),有些地方也称为损失函数(loss function);如教育小孩子一般,不断地去修正错误,最终得到较为正确的行为,在计算机中类似的方法称为梯度下降(gradient descent)

    1 评分函数

    这一小节将完成一个线性分类器的评分函数,获取一个随机的未进行训练模型的分数。首先看一下线性分类器的评分函数的原理。

    前面已经知道一副图像可以看做是一个3027维的向量,而CIFAR-10图像分类的结果共有10个可能,也就是说,评分函数输入一个为3027维的向量,最终得出一个10维的向量,这10维向量中十个数字代表各个类别的分类评分,当然,10个得分中的最高得分对应的类别会被认为是分类结果。获取分数的计算过程,即评分函数,如式1所示。

                                式1

    其中,f(X)为最终的到的分数,W为10*3027的矩阵,X为某副输入图像的转置,即单幅图像的大小为1*3027的向量,其转置为3027*1,这样W与X相乘的结果为10*1的矩阵;最后在将相乘结果加上一个偏执B,同样为10*1大小的矩阵,得到最终的分数。比对10个得分,最高分数为该类别。

    一个随机的W和B实现CIFAR-10分类

    在这一小节,先不对W和B的含义以及如何得到合适的W和B的方法进行探讨。先写一个程序,随机获取一个W和B进行分类,也可以认为是计算机的瞎蒙,看一看最终结果。程序如1所示。

    程序1 一个随机的W和B实现CIFAR-10分类

    import pickle
    import os
    import numpy as np
    
    n = 2
    
    def unpickle_as_array(filename):
        with open(filename, 'rb') as f:
            dic = pickle.load(f,encoding='latin1')
            dic_data = dic['data']
            dic_labels = dic['labels']
            dic_data = np.array(dic_data).astype('int')   
            dic_labels = np.array(dic_labels).astype('int')  
            return dic_data, dic_labels
    
    def load_batches(root,n):
        train_data = []
        train_labels = []
        for i in range(1,n+1,1):
            f = os.path.join(root,'data_batch_%d' %i)
            data, labels = unpickle_as_array(f)
            train_data.append(data)
            train_labels.append(labels)
        train_data_r = np.concatenate(train_data)   
        train_labels_r = np.concatenate(train_labels)
        del train_data, train_labels
        test_data, test_labels = unpickle_as_array(os.path.join(root, 'test_batch'))
        return train_data_r, train_labels_r, test_data, test_labels
    
    w = np.random.rand(10,3072)
    b = np.random.rand(10)
    train_data, train_labels, test_data, test_labels = load_batches('E:/cifar/cifar-10-batches-py', n)
    result = np.zeros(10000)
    for i in range(1000):
        score = w.dot(test_data[i,:])+b
        result[i] = np.argmax(score)
    print('the algorithm\'s accuracy: %f' % (np.mean(result == test_labels)))

    程序1 的30行以前代码参考https://blog.csdn.net/qq_36552550/article/details/105835108

    30以及31行得到随机矩阵w和b,32行读入图像数据;然后,通过for语句循环读入测试集中的10000副图像,因为每次只对一副图像进行计算,所以要读入的大小为10000*3072的test_data进行切片操作——test_data[i,:],得到第i张图片;计算得到评分score,通过argmax()函数找到最大的那个数对应的下标赋值给result[i],获取到这一副图像的分类。

    注意:这里test_data[i,:]并没有进行转置,因为在python中,test_data[i,:]为array类型,它的shape属性为(3072,),简单地讲,它既可以认为是线性代数中的行向量,也可以认为是列向量。在进行计算的时候,它会自动匹配矩阵进行运算;当然,这里将w.dot(test_data[i,:])改为w.dot(test_data[i,:].T),其结果是一致的。

    最后,37行将分类结果与测试集的正确结果比对,得出准确率,因为是随机获得的w和b,每次结果都不一样,但根据概率来讲,其结果都应趋近于0.10。随机的一次运行结果如1所示。

    图1 随机的w和b进行评分的准确率结果

    评分函数的理解

    这里先以二维为例,看一简单的例子,如图5-4-2所示,xd1表示横轴,xd2表示纵轴;图中叉点、圆点以及方块是三个类别,三条直线分别将三个类别分开,红线判别星点,蓝线判别方块,黄线判别圆点。如何得到正确的“分类线”会在后面进行学习。

    注意:从这里可以看出,偏执B的作用,如果没有偏执B,那么所有的“分类线”都过原点,如果一个点位于原点位置,那么它的所有分类得分都为0。

    以红线判别一个新的点是否为星点为例,若一个新的点为(x1,x2)位于红线上面,那么它的判定得分就是0,沿着红线的箭头方向,得分不断地增加;沿着红线箭头反方向,则得分不断地减少。

    图2 二维空间下三分类示例

    那么,对于一副图像来讲,3072个数值(32*32*3)可以看做是一个3072维空间下的一个点。而矩阵W和B则类似于图5-4-2中的“分类线”一般。

    通过后面的小节,可以得出正确的矩阵W(假定这里已经提前得出了正确矩阵)。将矩阵W缩放到0至255区间,将矩阵W对应的horse马分类和ship船分类的那一行提取出来;然后将其进行图片可视化,如图3所示。

     

    图3 矩阵W的马(左图)和船(右图)分类可视化

    可以看出,马分类的图片隐约可以看到一匹马,但是马似乎有两个头,这是因为数据库里面的马图片既可能左边站立,也可能朝右边站立,所以在中间位置给与马的棕红色较大的权重,同时,因为马匹可能左右站立,所以两种可能都给与了较大权重。

    而船分类的图片,图片大多呈现蓝色,因为船的图片大多在海面上,而海面大多是蓝色,所以给与蓝色特别大的权重,中间部位则隐约是一个白色的船只,则中间给与白色较大的权重。也就是说,矩阵W中船分类对应的那一行数字,对应于图片像素中RGB值,其中B值的地方,数值大多较高,而R值和G值则较低。可以想象,如果一副新的图片,整体呈现蓝色,而中间是白色的物体,那么进行计算,这幅图片在分类的时候,船分类对应的得分肯定会特别高。

    评分函数的简写

    式1可以简写——省略偏执B。如何省略偏执B呢?对于CIFAR-10来讲,W为10*3072的矩阵,只需将偏执B放在W矩阵的最后一列即可,新的W为大小为10*3073的矩阵,而Xi为第i副图像,其转置为3072*1列向量,只需在最后一行3072行后面在加一行,将其数值固定为1,这样新的Xi为大小为3073*1的列向量。并且计算结果和式1完全一致。最终可以简写为式2。

    式2

    2 损失函数

    犯错有大有小,计算机里面猜错了分类,也会进行评估错误的程度;评估错误大小的函数叫做损失函数(loss function),有些地方也有叫做代价函数(cost function)。错的离谱,那么损失函数的计算结果分值就大;反之,猜的很正确,那么损失函数计算结果分值就很小。

    损失函数的实现有多种方法,这里面介绍两种方法——SVM(Support Vector Machine)支持向量机以及SoftMax。

    SVM

    在CIFAR-10分类的训练中,通过目标函数获取到第i副图像xi的十个类别的得分,其中正确标签类别对应的得分为syi,其他的类别j的得分为sj;支持向量机的核心思想是让正确标签类别对应的得分syi比sj其他类别的得分多 ∆ 

    对于第i副训练集图像进行分类,SVM代价函数的计算如式3所示。

    可以看出,正确标签类别对应的得分syi比sj其他类别的得分多 ∆ 时候,小于0,此时0和比对,最大值为0;因为训练集的一副图像在十个类别里面有一个是正确的,其他九个是非正确的,所以,需要计算9次,然后求和得到最终的SVM损失函数结果。

    除此之外,SVM代价函数还需要加入正则化项regularization以便对W进行限制,得出唯一的W。可以想象,如果一个的W能够正确地分类所有的图像,那么其损失函数的结果为0,而使一个λ>1,λW对图像进行分类,依旧为能够满足损失函数的结果为0。这样W就不是唯一的。

    所以,对所有的训练图像(并非仅仅对第i副通过损失函数求结果)通过损失函数求结果,并求和;然后加入正则化项,4所示。

    其中,加号前半部分对所有训练集图像进行计算后求和,N为训练集图像的数量;后半部分为正则化项,对矩阵W每一个元素(即第r行第c列的元素)进行求平方然后全部相加,并乘以参数λ,得出正则化项的结果。

    注意:这里的正则化项W不需要包含偏执项B!

    然后,通过Python来编写一个SVM损失函数,并对一个随机的W和B,通过SVM损失函数计算最终结果,程序如2所示,注意该程序未加入正则化项。

    程序2 SVM损失函数实现

    import pickle
    import os
    import numpy as np
    from numpy import random,mat
    n = 2
    
    def unpickle_as_array(filename):
        with open(filename, 'rb') as f:
            dic = pickle.load(f,encoding='latin1')
            dic_data = dic['data']
            dic_labels = dic['labels']
            dic_data = np.array(dic_data).astype('int')
            dic_labels = np.array(dic_labels).astype('int')
            return dic_data, dic_labels
    
    def load_batches(root,n):
        train_data = []
        train_labels = []
        for i in range(1,n+1,1):
            f = os.path.join(root,'data_batch_%d' %i)
            data, labels = unpickle_as_array(f)
            train_data.append(data)
            train_labels.append(labels)
        train_data_r = np.concatenate(train_data)
        train_labels_r = np.concatenate(train_labels)
        del train_data, train_labels
        test_data, test_labels = unpickle_as_array(os.path.join(root, 'test_batch'))
        return train_data_r, train_labels_r, test_data, test_labels
    
    def svm_loss(x, y, W, n):
        delta = 1.0
        loss = np.zeros(10000 * n)
        for i in range(10000 * n):
            scores = W.dot(x[i])
            margins = np.maximum(0, scores - scores[y[i]] + delta)
            margins[y[i]] = 0
            loss[i] = np.sum(margins)
            #print('the %fth image\'s svm_loss is %f ' % (i,loss[i]))
        total_loss = np.sum(loss)
        return total_loss
    
    w = np.random.rand(10,3072)
    b = np.random.rand(10,1)
    W = np.concatenate((w,b),1)
    print(W.shape)
    train_data, train_labels, test_data, test_labels = load_batches('E:/cifar/cifar-10-batches-py', n)
    tail_1 = np.ones((n*10000,1))
    train_data = np.concatenate((train_data,tail_1), 1)
    print(train_data)
    t_loss = svm_loss(train_data, train_labels, W, n)
    print(t_loss)
    

    30行代码至40行实现了对n个训练集的图像数据通过SVM损失函数计算结果。函数名为svm_loss,其参数分别为训练集图像数据x,训练集图像的标签y,以及目标函数中的W(这里的W包含偏执B),n表示读入了几个数据集文件。

    这里将式3的∆值设置为1,即第31行代码。 loss存储了10000*n副训练集图像对应的损失函数计算的值。这里可以思考一下∆值的设置,例如的差值如果较大——大多数情况下都远大于100的话,那么∆值设置为100或者1对最终结果关系不大。

    34至37行代码实现了式5-4-3的计算;训练集的一副图像在十个类别里面有一个是正确的,其他九个是非正确的,所以,只需要计算非正确类别的9次;在第36行将正确类别对应的计算结果置零,来实现这九次计算,而非十次计算。最终将所有训练集图像的损失函数计算结果相加。

    回顾“评分函数的简写”这一小节我们知道,要将矩阵W和B进行简化。41至43行,随机创建了W矩阵和B矩阵,然后将B矩阵添加在W矩阵的后面,注意是横向添加矩阵,所有concatenate()函数的第二个参数是1,而不是0。然后,要在输入图像3072个元素后面追加一个元素1,47行至48行完成了该过程。此时,矩阵W大小应该为10*3073,而10000*2个训练集的图像原本读出后,其图像数据的矩阵大小为20000*3072,所有图像最后都加上一个1后,新的图像数据的矩阵大小为20000*3073。

    50行计算出结果并输出。一次随机的运行结果如图4所示。

    图4 SVM损失函数运行结果示意图

    通过SVM的损失函数得出结果后,要做的就是让计算机“犯得错误小”,即通过改变矩阵W让这个最终的损失函数得出的总的和值让其尽量的小,不断改变矩阵W最终使得损失函数的结果值最小化的方法叫做梯度下降

    在进行梯度下降的学习前,先看另一种常用的损失函数——SoftMax分类器的损失函数,该损失函数也用于卷积神经网络。

    SoftMax

    SVM的损失函数可以看出只要正确标签类别对应的得分syi比sj其他类别的得分多 就可以得到0的结果;但如果syi比sj多更多,即远大于 则结果依旧也为0,也就是说SVM损失函数只关心这个W有多差,而不关心W有多优秀。而SoftMax损失函数则同时兼顾两个方面。

    SoftMax和SVM在评分函数的步骤相同,都需要通过式5-4-1得出分数;但后面的计算不同。

    对于CIFAR-10而言,每幅图片对应10个类别,若将一副的图像进行分类测试,SoftMax分类器将得出10个类别分类的各自概率,即10个0至1的数值(10个数值相加为1)。

    那么,如果模型合理,那么图像真实类别的概率应该接近1,即接近100%,而其他错误类别的概率应接近0。这种合理的模型,其损失函数结果应该尽量小。

    反之,如果通过模型进行分类,图像真实的类别概率判定很小,那么这个模型肯定很不合理,那么损失函数结果应该尽量的大,表明模型“犯错”程度高。

    SoftMax的损失函数如式5所示。

    前面评分函数可对一副图像得出所有类别的评分,SoftMax损失函数第一步要得出正确类别评分占据总评分的概率。

    Li表示训练集第i幅图像的损失函数结果,fyi表示第i幅图像正确的类别对应的评分,fj表示该图像第j个类别的评分函数结果,则表示所有类别的之和。表示正确类别的分类概率。

    合理的分类,的值应该趋近于1,而越是不合理的分类,越趋近于0;log函数则特别适合作为概率分类的损失函数计算。

     

    通过图5可以看出,选取a大于1时,当logax中的x趋近于0时,y趋近于无穷;当x趋近于1时,y趋近于0。

    图5 -logax a>1函数图

    而a选取自然数e,从后面可以看到选取自然数e时,一些包含自然数e的式子求导特别方便。

    根据式5编写程序,通过SoftMax的损失函数计算一个随机的W(包含偏执B)的结果并显示,如程序3所示。

    程序3 SoftMax损失函数实现

    import pickle
    import os
    import numpy as np
    from numpy import random,mat
    n = 2
    
    def unpickle_as_array(filename):
        with open(filename, 'rb') as f:
            dic = pickle.load(f,encoding='latin1')
            dic_data = dic['data']
            dic_labels = dic['labels']
            dic_data = np.array(dic_data).astype('int')
            dic_labels = np.array(dic_labels).astype('int')
            return dic_data, dic_labels
    
    def load_batches(root,n):
        train_data = []
        train_labels = []
        for i in range(1,n+1,1):
            f = os.path.join(root,'data_batch_%d' %i)
            data, labels = unpickle_as_array(f)
            train_data.append(data)
            train_labels.append(labels)
        train_data_r = np.concatenate(train_data)
        train_labels_r = np.concatenate(train_labels)
        del train_data, train_labels
        test_data, test_labels = unpickle_as_array(os.path.join(root, 'test_batch'))
        return train_data_r, train_labels_r, test_data, test_labels
    
    def softmax_loss(x, y, W, n):
        loss = np.zeros(10000 * n)
        for i in range(10000 * n):
            scores = W.dot(x[i])
            scores -= np.max(scores)
            p = np.zeros(10)
            p = np.exp(scores) / np.sum(np.exp(scores))
            print(p)
            loss[i] = - np.log(p[y[i]])
        total_loss = np.sum(loss)
        return total_loss
    
    np.set_printoptions(suppress=True)
    w = np.random.rand(10,3072)
    b = np.random.rand(10,1)
    W = np.concatenate((w,b),1)
    train_data, train_labels, test_data, test_labels = load_batches('E:/cifar/cifar-10-batches-py', n)
    tail_1 = np.ones((n*10000,1))
    train_data = train_data/255
    train_data = np.concatenate((train_data,tail_1), 1)
    t_loss = softmax_loss(train_data, train_labels, W, n)
    print(t_loss)

    这里需要注意两点,48行程序将图像的数值全部除以255,因为在计算e的scores次方时,数值可能太大,超出Python的数值范围。

    同样为了防止数值过大,在编写程序的时候,将式5改为式6,最终结果不变;fmax为评分函数结果中10个评分最大的那个数。这样分子分母中e的次方都为小于等于0,即分子分母的值都小于等于1。

    式6

    一次随机的运行结果部分截图如图6所示。

    图6 SoftMax损失函数运行结果截图

    展开全文
  • 评分函数Socres: 以输入x和权值Wi为自变量的一个函数,比如评价x属于某个分类的可能性的分值 损失函数L:包含数据损失+规则化项损失 数据损失中的每一项的损失Li: 如下所示的例子,求max(0, sj-syi+1)的和,即SVM...

    基本概念

    • 评分函数Socres: 以输入x和权值Wi为自变量的一个函数,比如评价x属于某个分类的可能性的分值;
    • 损失函数L:包含数据损失+规则化项损失;
    • 数据损失中的每一项的损失Li: 如下所示的例子,求max(0, sj-syi+1)的和,即SVM损失。
      • 为什么实用max这样的运算? 答:为了增加非线性,因为生活中很多问题都不是线性的。
    • 计算图:
      • 由来:直接求解损失函数L对于W权值的导数,计算量较大,且更换一个损失函数式子,又需要重新推导,所以为了计算方便,人们提出了计算图和反向传播的计算方法。
      • 表达形式:将输入输出作为变量,将运算作为节点依次正向画出计算过程的图,称之为计算图。
      • 下图解释:如下所示,输入一个变量x, 一个权值W(相当于一层神经网络),经过*(乘法)运算得到评分函数s,再经过hinge loss(如SVM损失函数)计算得到“数据损失”,然后加上R(W),即“规则化项损失”,得到最终得损失L。
    展开全文
  • 分类评分函数 score function

    千次阅读 2018-12-14 14:36:31
    SVM 评分函数中,将输出 s j = f ( x i , W ) j s_j=f(x_i,W)_j s j ​ = f ( x i ​ , W ) j ​ 作为第 i i i 个数据针对第 j j j 个类别的得分,所以分类损失的详细定义为: L i = ∑ j ̸ = y i m a x ( ...

    从图像到标签分值的映射

    一个线性映射:

    f ( x i , W , b ) = W x i + b \displaystyle f(x_i,W,b)=Wx_i+b f(xi,W,b)=Wxi+b

    其中,参数 W W W 为权重(weights), b b b 称为偏差向量(bias vector)

    一个将图像映射到分类分值的例子:

    • 为了便于可视化,假设图像只有4个像素值,有3个分类。

    • 首先将图像像素拉伸为一个列向量,与 W W W 进行矩阵乘,再加上偏置项 b b b,得到各个分类的分值。

    • 需要注意的是,由于权值没有训练到位,猫分类的分值非常低。

    多类 SVM 分类器

    针对第 i i i 个数据的 j j j 类 SVM 的损失函数定义如下:

    L i = ∑ j ̸ = y i m a x ( 0 , s j − s y i + Δ ) \displaystyle L_i=\sum_{j\not=y_i}max(0,s_j-s_{y_i}+\Delta) Li=j̸=yimax(0,sjsyi+Δ)

    使用多类 SVM 分类时,正确分类的分数需要比其他不正确的分类分数高出 边界值 delta Δ \Delta Δ)。其他分类分数进入了红色的区域时,就开始计算损失。在红色区域之前,损失值为0。

    SVM 评分函数中,将输出 s j = f ( x i , W ) j s_j=f(x_i,W)_j sj=f(xi,W)j 作为第 i i i 个数据针对第 j j j 个类别的得分,所以分类损失的详细定义为:

    L i = ∑ j ̸ = y i m a x ( 0 , w j T x i − w y i T x i + Δ ) \displaystyle L_i=\sum_{j\not=y_i}max(0,w^T_jx_i-w^T_{y_i}x_i+\Delta) Li=j̸=yimax(0,wjTxiwyiTxi+Δ)

    加上正则化项:

    L = 1 N ∑ i ∑ j ̸ = y i [ m a x ( 0 , f ( x i ; W ) j − f ( x i ; W ) y i + Δ ) ] + λ ∑ k ∑ l W k , l 2 L=\frac{1}{N}\sum_i\sum_{j\not=y_i}[max(0,f(x_i;W)_j-f(x_i;W)_{y_i}+\Delta)]+\lambda \sum_k \sum_l W^2_{k,l} L=N1ij̸=yi[max(0,f(xi;W)jf(xi;W)yi+Δ)]+λklWk,l2

    其中:

    • m a x ( 0 , − ) max(0,-) max(0,) 函数,它常被称为 折叶损失(hinge loss)。有时候会听到人们使用 平方折叶损失SVM(即 L2-SVM),它使用的是 m a x ( 0 , − ) 2 max(0,-)^2 max(0,)2,将更强烈(平方地而不是线性地)地惩罚过界的边界值。可以通过交叉验证来决定到底使用哪个。

    • 在绝大多数情况下设置 Δ = 1.0 \Delta=1.0 Δ=1.0 都是安全的。超参数 Δ \Delta Δ λ \lambda λ 一起控制损失函数中的数据损失(data loss)和正则化损失(regularization loss)之间的权衡。

    • 不同分类分值之间的边界的具体值(比如 Δ = 1 \Delta=1 Δ=1 Δ = 100 \Delta=100 Δ=100)从某些角度来看是没意义的,因为权重自己就可以控制差异变大和缩小。也就是说,真正的权衡是我们允许权重能够变大到何种程度,通过正则化强度 λ \lambda λ 来控制,详见:正则化方法

    Softmax 分类器

    Softmax 分类器可以理解为 逻辑回归分类器 面对多个分类的一般化归纳,输出归一化的分类概率。

    在Softmax分类器中,函数映射 f ( x i ; W ) = W x i f(x_i;W)=Wx_i f(xi;W)=Wxi 保持不变,但将这些评分值视为每个分类的未归一化的对数概率,并且将折叶损失(hinge loss)替换为交叉熵损失(cross-entropy loss)。公式如下:

    L i = − l o g ( e f y i ∑ j e f j ) L_i=-log(\frac{e^{f_{y_i}}}{\sum_je^{f_j}}) Li=log(jefjefyi)

    或等价的:

    L i = − f y i + l o g ( ∑ j e f j ) L_i=-f_{y_i}+log(\sum_je^{f_j}) Li=fyi+log(jefj)

    其中:

    • 使用 f j f_j fj 来表示分类评分向量 f f f 中的第 j j j 个元素。

    • 函数 f j ( z ) = e z j ∑ k e z k f_j(z)=\frac{e^{z_j}}{\sum_ke^{z_k}} fj(z)=kezkezj 被称作 softmax 函数,其输入值是一个向量,向量中元素为任意实数的评分值( z z z 中的),函数对其进行压缩,输出一个向量,其中每个元素值在 0 到 1 之间,且所有元素之和为 1。

    对数的基本性质:

    • 函数拆分:
      ln ⁡ ( a b ) = ln ⁡ ( a ) + ln ⁡ ( b ) \ln(ab)=\ln(a)+\ln(b) ln(ab)=ln(a)+ln(b)
    • log( x x x) vs log( 1 / x 1/x 1/x) :
      l o g ( x ) = − l o g ( 1 / x ) log(x) = -log(1/x) log(x)=log(1/x)
      图中,蓝线为 ln( 1 / x 1/x 1/x) ,黑线为 ln( x x x)

    数值归一化:

    • 编程实现 softmax 函数计算的时候,中间项 e f y i e^{f_{y_i}} efyi ∑ j e f j \sum_j e^{f_j} jefj 因为存在指数函数,所以数值可能非常大。

    • 除以大数值可能导致数值计算的不稳定,所以使用归一化非常重要。如果在分式的分子和分母都乘以一个常数 C C C,并把它变换到求和之中,就能得到一个从数学上等价的公式:

    e f y i ∑ j e f j = C e f y i C ∑ j e f j = e f y i + l o g C ∑ j e f j + l o g C \frac{e^{f_{y_i}}}{\sum_je^{f_j}}=\frac{Ce^{f_{y_i}}}{C\sum_je^{f_j}}=\frac{e^{f_{y_i}+logC}}{\sum_je^{f_j+logC}} jefjefyi=CjefjCefyi=jefj+logCefyi+logC

    • 代码实现如下:
    f = np.array([123, 456, 789]) # 例子中有3个分类,每个评分的数值都很大
    p = np.exp(f) / np.sum(np.exp(f)) # 不妙:数值问题,可能导致数值爆炸
    
    # 那么将f中的值平移到最大值为0:
    f -= np.max(f) # f becomes [-666, -333, 0]
    p = np.exp(f) / np.sum(np.exp(f)) # 现在OK了,将给出正确结果
    

    SVM 和 Softmax的比较

    损失函数的不同:

    • SVM 分类器使用的是 折叶损失(hinge loss),有时候又被称为 最大边界损失(max-margin loss)

    • Softmax 分类器使用的是 交叉熵损失(corss-entropy loss)

    对分类分值的不同解释:

    • 针对一个数据点,两个分类器都计算了同样的分值向量 f f f

    • SVM分类器将 f f f 看做是分类评分,它的损失函数鼓励正确的分类(本例中是蓝色的类别2)的分值比其他分类的分值高出至少一个边界值。

    • Softmax分类器将 f f f 看做是每个分类没有归一化的对数概率,鼓励正确分类的归一化的对数概率变高,其余的变低。

    • SVM的最终的损失值是 1.58,Softmax 的最终的损失值是 0.452,但要注意这两个数值没有可比性。只在给定同样数据,在同样的分类器的损失值计算中,它们才有意义。

    在实际使用中,SVM 和 Softmax 经常是相似的:

    • 通常说来,两种分类器的表现差别很小。

    • 相对于 Softmax 分类器,SVM 更加局部目标化(local objective),这既可以看做是一个特性,也可以看做是一个劣势。

    • SVM 对于各个分类的得分细节并不关心:分数是 [ 10 , − 100 , − 100 ] [10, -100, -100] [10,100,100] 或者 [ 10 , 9 , 9 ] [10, 9, 9] [10,9,9],对于 SVM 来说没什么不同,只要分差超过边界值,那么损失值就等于 0,不会超过限制去细微地操作具体分数。

    • 对于 softmax 分类器,情况则不同。对于 [ 10 , 9 , 9 ] [10, 9, 9] [10,9,9] 来说,计算出的损失值就远远高于 [ 10 , − 100 , − 100 ] [10, -100, -100] [10,100,100] 的。换句话来说,softmax 分类器对于分数是永远不会满意的。

    展开全文
  • 针对论坛数据的层次特征,提出了一种基于层次评分函数的多粒度搜索方法。将论坛数据用树型层次结构表示,并基于多个因素提出了融合话题、发言、语句和单词多个粒度的层次评分函数。为了避免多种粒度的数据在返回结果...
  • 气象上常见评分函数及其python实现

    千次阅读 多人点赞 2020-04-27 12:47:38
    气象上常见评分函数及其python实现 文章目录气象上常见评分函数及其python实现1 简介2 评价指标及其python实现2.1 二分类介绍2.2 降水评价2.2.1 气象二分类指标2.2.2 TS评分 & CSI1 物理概念2 代码2.2.3 公平...

    气象上常见评分函数及其python实现

    1 简介

    气象部门在发布预报时,发布的是一定区域范围的网格化(或站点化)的气象要素结果,以降水预报为例,

    • 先将预报区域划分为60 * 60(视空间分辨率而定,空间分辨率越高,格点数值越大) 的网格,每个网格上都存在对应的降水预报值。
    • 事后需要对预测结果进行检验,如图1,左图为14时的预报结果y_pre,右图为真实观测结果y_obs,异同明显。那如何衡量预报好坏呢?即如何衡量预报场(y_pre)观测场(真值y_obs) 的异同程度呢?
    • 主要采取二分类思想进行评价。但针对不同需求,气象上有许多预报准确度评价指标
      在这里插入图片描述
      ​ 图1 14时的降水预测与观测值对比

    2 评价指标及其python实现

    2.1 二分类介绍

    假设有两个类别,正和负,分别用1,0表示,如下表格。

    预测 负例预测 正例
    真实 负例TN(True negative)FP(False positive)
    真实 正例FN(False negative)TP(True positive)

    该表格称为 混淆矩阵(confusion matrix)。

    • TN : 真阴性。实际为0,预测为0.

    • TP : 真阳性。实际为1,预测为1.

    • FP: 假阳性。实际为0,预测为1.

    • FN: 假阴性。 实际为1,预测为0.

    • 召回率(Recall):R=TP/(TP+FN) ,指的是被预测为正例的占总的正例的比重;

    • 精准度(precision):P = TP/(TP+FP) ,指被分类器判定正例中的正样本的比重;

    • 准确率(Accuracy):A = (TP+TN)/(TP+FN+FP+TN) ,反映了分类器对整个样本的判定能力,也就是说能将正

      的判定为正,负的判定为负。

    • F1为:
      在这里插入图片描述

    在实际应用中,我们不仅希望Accuracy高,还希望模型对每个类别都有很强的分类能力,即recall 和 precision都要高。

    2.2 降水评价

    2.2.1 气象二分类指标

    气象上的降水评价指标基本都建立在二分类基础上。

    以上面的y_pre 和 y_obs 为例,共计有3600个格点,选定一个阈值rain_threshold ,格点数值 >= rain_threshold 即为正例, 否则为负例。这里采取晴雨分类,即rain_threshold = 0.1

    在这里插入图片描述

    构建混淆矩阵,晴为负例,雨为正例,如下:

    预测 晴预测 雨
    真实 晴TN: 1968FP: 522020
    真实 雨FN: 458TP: 11221580
    24261174
    • Recall: R=TP/(TP+FN) = 1122/(1122 + 458) = 0.71

    • precision: p = TP/(TP + FP) = 1122/(1122 + 52) = 0.95

    • Accuracy: (TP + TN)/(TN + FP + FN + TP) = 0.86

    类比到气象上,概念一致,只是换了名称。

    预测 晴预测 雨
    真实 晴correctnegativesfalsealarms(误警)2020
    真实 雨misses(漏报)hits(击中)1580
    24261174

    代码如下:

    def prep_clf(obs,pre, threshold=0.1):
        '''
        func: 计算二分类结果-混淆矩阵的四个元素
        inputs:
            obs: 观测值,即真实值;
            pre: 预测值;
            threshold: 阈值,判别正负样本的阈值,默认0.1,气象上默认格点 >= 0.1才判定存在降水。
        
        returns:
            hits, misses, falsealarms, correctnegatives
            #aliases: TP, FN, FP, TN 
        '''
        #根据阈值分类为 0, 1
        obs = np.where(obs >= threshold, 1, 0)
        pre = np.where(pre >= threshold, 1, 0)
    
        # True positive (TP)
        hits = np.sum((obs == 1) & (pre == 1))
    
        # False negative (FN)
        misses = np.sum((obs == 1) & (pre == 0))
    
        # False positive (FP)
        falsealarms = np.sum((obs == 0) & (pre == 1))
    
        # True negative (TN)
        correctnegatives = np.sum((obs == 0) & (pre == 0))
    
        return hits, misses, falsealarms, correctnegatives
    
    
    def precision(obs, pre, threshold=0.1):
        '''
        func: 计算精确度precision: TP / (TP + FP)
        inputs:
            obs: 观测值,即真实值;
            pre: 预测值;
            threshold: 阈值,判别正负样本的阈值,默认0.1,气象上默认格点 >= 0.1才判定存在降水。
        
        returns:
            dtype: float
        '''
    
        TP, FN, FP, TN = prep_clf(obs=obs, pre = pre, threshold=threshold)
    
        return TP / (TP + FP)
    
    
    def recall(obs, pre, threshold=0.1):
        '''
        func: 计算召回率recall: TP / (TP + FN)
        inputs:
            obs: 观测值,即真实值;
            pre: 预测值;
            threshold: 阈值,判别正负样本的阈值,默认0.1,气象上默认格点 >= 0.1才判定存在降水。
        
        returns:
            dtype: float
        '''
    
        TP, FN, FP, TN = prep_clf(obs=obs, pre = pre, threshold=threshold)
    
        return TP / (TP + FN)
    
    
    def ACC(obs, pre, threshold=0.1):
        '''
        func: 计算准确度Accuracy: (TP + TN) / (TP + TN + FP + FN)
        inputs:
            obs: 观测值,即真实值;
            pre: 预测值;
            threshold: 阈值,判别正负样本的阈值,默认0.1,气象上默认格点 >= 0.1才判定存在降水。
        
        returns:
            dtype: float
        '''
    
        TP, FN, FP, TN = prep_clf(obs=obs, pre = pre, threshold=threshold)
    
        return (TP + TN) / (TP + TN + FP + FN)
    
    def FSC(obs, pre, threshold=0.1):
        '''
        func:计算f1 score = 2 * ((precision * recall) / (precision + recall))
        '''
        precision_socre = precision(obs, pre, threshold=threshold)
        recall_score = recall(obs, pre, threshold=threshold)
    
        return 2 * ((precision_socre * recall_score) / (precision_socre + recall_score))
    
    

    由以上四个基本指标,引申出许多气象降水评价指标。

    有一点需要注意:气象上的降水评价指标基本都建立在二分类基础上,即任何指标都必须指明rain_threshold。

    2.2.2 TS评分 & CSI
    1 物理概念
    • TS:风险评分ThreatScore;

    • CSI: critical success index 临界成功指数;

    • 两者的物理概念完全一致。

    • 如下图:y_pre_1为预测的降水区( >= threshold,下同),y_obs_1为观测的降水区,hits为两者交界区,
      TS = hits/(hits + falsealarms + misses) 。其中falsealarms = y_pre_1 - hits, misses = y_obs_1 - hits

    在这里插入图片描述

    2 代码
    def TS(obs, pre, threshold=0.1):
        
        '''
        func: 计算TS评分: TS = hits/(hits + falsealarms + misses) 
        	  alias: TP/(TP+FP+FN)
        inputs:
            obs: 观测值,即真实值;
            pre: 预测值;
            threshold: 阈值,判别正负样本的阈值,默认0.1,气象上默认格点 >= 0.1才判定存在降水。
        returns:
            dtype: float
        '''
    
        hits, misses, falsealarms, correctnegatives = prep_clf(obs=obs, pre = pre, threshold=threshold)
    
        return hits/(hits + falsealarms + misses) 
    
    2.2.3 公平技巧评分(ETS)
    1 物理概念
    • 公平技巧评分(Equitable Threat Score, ETS)用于衡量对流尺度集合预报的预报效果。ETS评分表示在预报区域内满足某降水阈值的降水预报结果相对于满足同样降水阈值的随机预报的预报技巧;

    • ETS评分是对TS评分的改进,能对空报或漏报进行惩罚,使评分相对后者更加公平.

    2 代码
    def ETS(obs, pre, threshold=0.1):
        '''
        ETS - Equitable Threat Score
        details in the paper:
        Winterrath, T., & Rosenow, W. (2007). A new module for the tracking of
        radar-derived precipitation with model-derived winds.
        Advances in Geosciences,10, 77–83. https://doi.org/10.5194/adgeo-10-77-2007
        Args:
            obs (numpy.ndarray): observations
            pre (numpy.ndarray): prediction
            threshold (float)  : threshold for rainfall values binaryzation
                                 (rain/no rain)
        Returns:
            float: ETS value
        '''
        hits, misses, falsealarms, correctnegatives = prep_clf(obs=obs, pre = pre,
                                                               threshold=threshold)
        num = (hits + falsealarms) * (hits + misses)
        den = hits + misses + falsealarms + correctnegatives
        Dr = num / den
    
        ETS = (hits - Dr) / (hits + misses + falsealarms - Dr)
    
        return ETS
    
    2.2.4 空报率(FAR)
    1 物理概念
    • False Alarm Rate 。在预报降水区域中实际没有降水的区域占总预报降水区域的比重。

    • FAR = (y_pre_1 - hits)/y_pre_1 = falsealarms / (hits + falsealarms)

    在这里插入图片描述

    2 代码
    def FAR(obs, pre, threshold=0.1):
        '''
        func: 计算误警率。falsealarms / (hits + falsealarms) 
        FAR - false alarm rate
        Args:
            obs (numpy.ndarray): observations
            pre (numpy.ndarray): prediction
            threshold (float)  : threshold for rainfall values binaryzation
                                 (rain/no rain)
        Returns:
            float: FAR value
        '''
        hits, misses, falsealarms, correctnegatives = prep_clf(obs=obs, pre = pre,
                                                               threshold=threshold)
    
        return falsealarms / (hits + falsealarms)
    
    2.2.5 漏报率(MAR)
    1 物理概念
    • Missing Alarm Rate。实际降水区域中漏报的区域占据全部实际降水区域的比重。
    • MAR = (y_obs_1 - hits)/y_obs_1 = misses / (hits + misses)

    在这里插入图片描述

    2 代码
    def MAR(obs, pre, threshold=0.1):
        '''
        func : 计算漏报率 misses / (hits + misses)
        MAR - Missing Alarm Rate
        Args:
            obs (numpy.ndarray): observations
            pre (numpy.ndarray): prediction
            threshold (float)  : threshold for rainfall values binaryzation
                                 (rain/no rain)
        Returns:
            float: MAR value
        '''
        hits, misses, falsealarms, correctnegatives = prep_clf(obs=obs, pre = pre,
                                                               threshold=threshold)
    
        return misses / (hits + misses)
    
    
    2.2.6 命中率(POD)
    1 物理概念
    • Probability of Detection。即预测出的实际的降水区域占据全部实际降水区域的比重。
    • POD = hits / y_obs_1 = hits / (hits + misses) = 1- MAR
    2 代码
    def POD(obs, pre, threshold=0.1):
        '''
        func : 计算命中率 hits / (hits + misses)
        pod - Probability of Detection
        Args:
            obs (numpy.ndarray): observations
            pre (numpy.ndarray): prediction
            threshold (float)  : threshold for rainfall values binaryzation
                                 (rain/no rain)
        Returns:
            float: PDO value
        '''
        hits, misses, falsealarms, correctnegatives = prep_clf(obs=obs, pre = pre,
                                                               threshold=threshold)
    
        return hits / (hits + misses)
    
    2.2.7 偏差评分(Bia score)
    1 物理概念
    • 偏差评分(Bias score)主要用来衡量模式对某一量级降水的预报偏差, 该评分在数值上等于预报区域内满足某降水阈值的总格点数与对应实况降水总格点数的比值(Kong et al, 2008)。用来反映降水总体预报效果的检验方法。
    • Bias = y_pred_1/y_obs_1 = (hits + falsealarms)/(hits + misses)
    2 代码
    def BIAS(obs, pre, threshold = 0.1):
        '''
        func: 计算Bias评分: Bias =  (hits + falsealarms)/(hits + misses) 
        	  alias: (TP + FP)/(TP + FN)
        inputs:
            obs: 观测值,即真实值;
            pre: 预测值;
            threshold: 阈值,判别正负样本的阈值,默认0.1,气象上默认格点 >= 0.1才判定存在降水。
        returns:
            dtype: float
        '''    
        hits, misses, falsealarms, correctnegatives = prep_clf(obs=obs, pre = pre,
                                                               threshold=threshold)
    
        return (hits + falsealarms) / (hits + misses)
    
    2.2.8 其他评分
    1. HSS

    HSS公式如下:

    在这里插入图片描述

    def HSS(obs, pre, threshold=0.1):
        '''
        HSS - Heidke skill score
        Args:
            obs (numpy.ndarray): observations
            pre (numpy.ndarray): pre
            threshold (float)  : threshold for rainfall values binaryzation
                                 (rain/no rain)
        Returns:
            float: HSS value
        '''
        hits, misses, falsealarms, correctnegatives = prep_clf(obs=obs, pre = pre,
                                                               threshold=threshold)
    
        HSS_num = 2 * (hits * correctnegatives - misses * falsealarms)
        HSS_den = (misses**2 + falsealarms**2 + 2*hits*correctnegatives +
                   (misses + falsealarms)*(hits + correctnegatives))
    
        return HSS_num / HSS_den
    
    2. BSS
    def BSS(obs, pre, threshold=0.1):
        '''
        BSS - Brier skill score
        Args:
            obs (numpy.ndarray): observations
            pre (numpy.ndarray): prediction
            threshold (float)  : threshold for rainfall values binaryzation
                                 (rain/no rain)
        Returns:
            float: BSS value
        '''
        obs = np.where(obs >= threshold, 1, 0)
        pre = np.where(pre >= threshold, 1, 0)
    
        obs = obs.flatten()
        pre = pre.flatten()
    
        return np.sqrt(np.mean((obs - pre) ** 2))
    
    3. MAE
    def MAE(obs, pre):
        """
        Mean absolute error
        Args:
            obs (numpy.ndarray): observations
            pre (numpy.ndarray): prediction
        Returns:
            float: mean absolute error between observed and simulated values
        """
        obs = pre.flatten()
        pre = pre.flatten()
    
        return np.mean(np.abs(pre - obs))
    
    
    4. RMSE
    def RMSE(obs, pre):
        """
        Root mean squared error
        Args:
            obs (numpy.ndarray): observations
            pre (numpy.ndarray): prediction
        Returns:
            float: root mean squared error between observed and simulated values
        """
        obs = obs.flatten()
        pre = pre.flatten()
    
        return np.sqrt(np.mean((obs - pre) ** 2))
    
    2.2.9 阈值选取
    • 上述评分都与阈值threshold密切相关,我们关注什么类型降水的预报准确度,就使用对应的threshold。
    threshold : mm0.1102550100
    降雨类型小雨中雨大雨暴雨特大暴雨

    3 应用举例

    选取上述例子,来看在不同阈值下各评分函数数值。

    在这里插入图片描述

    在这里插入图片描述

    • 除Bia外,其他评分函数数值范围都在**[0,1]之间**;其中FAR \ MAR越低越好,其他越高越好。
    • 实际情况:FAR和 MAR一般随着降水阈值增大而显著增加,CSI 、ETS、POD、HSS、BSS随阈值增大而减小。 即该预报模式对强降水的预报能力较弱,对是否降水预测更准确。

    在真实的检验中,y_obs并不是均匀网格的,而是站点分布的,依据相同思路,比较区域内的所有站点预测和站点观测值,也能得到对应评分。

    4 参考文献

    rainymotion v0.1 github

    分类模型评估指标——准确率、精准率、召回率、F1、ROC曲线、AUC曲线

    王在文,梁旭东,范水勇,等. 数值模式降水评分对分辨率的敏感性初探[J].暴雨灾害,2016,35(1):10-16

    吴启树,韩美,刘铭,等.基于评分最优化的模式降水预报订正算法对比.应用气象学报,2017,28(3):306317.DOI: 10.11898/10017313.20170305

    匡秋明,杨雪冰,张文生,何险峰,惠建忠.多源数据融合高时空分辨率晴雨分类.软件学报,2017,28(11):2925−

    \2939. http://www.jos.org.cn/1000-9825/5336.htm

    展开全文
  • seq2seq中的Global Attention机制的三种评分函数的理解—以pytorch为例 文章目录seq2seq中的Global Attention机制的三种评分函数的理解—以pytorch为例1 seq2seq简介2 Attention介绍2.1 Local Attention 与 Global ...
  • PeleAI-3D的目标是根据从分子模拟方法(如蒙特卡洛或对接)获得的模拟数据创建特定于目标的得分函数。 为此,计算出包含配体的结合位点的基于图的拓扑描述,此后可用于拟合预测给定姿势的活性或结合能的模型。 要求...
  • 评分函数(Scoring Function,SF)是衡量知识图谱(Knowledge Graph,KG)中三元组可编程性的重要指标,已成为知识图谱嵌入的关键。近年来,大量的评分函数被设计出来,用于捕捉知识图谱中的各种关系。然而,由于...
  • 基于新评分函数的基于WDBA的勾股模糊多准则决策算法
  • 高斯混合模型 评分函数III. 似然函数与参数IV . 生成模型法V . 对数似然函数VI . 高斯混合模型方法 步骤 I . 高斯混合模型 参数简介 1 . 模型 与 参数 : 高斯混合模型 概率密度函数 : p(x)=∑i=1kωig(x∣μi,...
  • SOLR中实现自定义评分函数FunctionQuery

    千次阅读 2014-07-18 16:35:54
    SOLR项目应用中,需要对搜索结果自定义排序,比如对一些质量好的网站权重高点。这里就需要定义一个自定义的valueSourceParser来实现。 先实现一个自定义的:B258DynamicSourceParser。主要代码如下: ...
  • 数据挖掘算法组件化 组件一 : 模型或模式结构 组件二 : 数据挖掘任务 组件三 : 评分函数 组件四 : 搜索和优化算法 组件五 : 数据管理策略 数据挖掘算法 组件化思想应用
  • 文章目录小心情前言将分箱后的评分转为小数踩坑点 小心情 平平无奇我真棒!!! 前言 toad包里的scorecard能自动将概率转为评分卡,想学习toad的童靴,可以参见:toad使用教程。 概率转评分卡,并将评分转到希望的...
  • solr 自定义函数 评分函数

    千次阅读 2014-04-04 13:54:10
    solr
  • 主要介绍了js实现的星星评分功能函数,涉及JavaScript响应鼠标事件实现针对页面元素的遍历与样式属性的修改技巧,非常简单实用的代码,需要的朋友可以参考下
  • 得分函数与损失函数

    千次阅读 2020-03-17 16:28:43
    得分函数就是对于给定的一个输入,通过计算,得到这个输入属于每种类别的得分。比如我们现在有三个类别:小猫、小狗和青蛙,对于一张给定的图片,计算出这个图片是小猫的得分,是小狗的得分以及是青蛙的得分。 对于...
  • 机器学习得分函数

    千次阅读 2020-02-08 23:40:03
    关于sklearn中GridSearch等中中scoring参数,有两个...问题2:自己定义得分函数(得分和损失函数),比较重要的一点是注意指标是越大越好还是越小越好,需要使用一个参数 greater_is_better 指定。 参考链接: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,581
精华内容 19,032
关键字:

评分函数