手把手教你写评分函数以及SVM损失函数和SoftMax损失函数

 

小时候,我们在学习的过程中,也可以认为是一个摸索的过程,不断犯错并且一点点修正的过程;通俗地讲,计算机训练模型的过程,也是一个如人一样学习的过程,每一次模型的训练就是一次尝试,这次尝试都会得出一个结果数值,用来得出这个结果数值的函数称之为评分函数(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.

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值