SVM, Softmax损失函数[通俗易懂]

SVM, Softmax损失函数[通俗易懂]版权声明:本文为博主原创文章,未经博主允许不得转载。目录(?)[+]Deeplearning在计算机视觉方面具有广泛的应用,包括图像分类、目标识别、语义分隔、生成图像描述等各个方面。本系列博客将分享自己在这些方面的学习和认识,如有问题,欢迎交流。在使用卷积神经网络进行分类任务时,往往使用以下几类损失函数:平方误差损失SVM损失s

大家好,又见面了,我是你们的朋友全栈君。

目录(?)[+]

Deep learning在计算机视觉方面具有广泛的应用,包括图像分类、目标识别、语义分隔、生成图像描述等各个方面。本系列博客将分享自己在这些方面的学习和认识,如有问题,欢迎交流。

在使用卷积神经网络进行分类任务时,往往使用以下几类损失函数:

  • 平方误差损失
  • SVM损失
  • softmax损失

其中,平方误差损失在分类问题中效果不佳,一般用于回归问题。softmax损失函数和SVM(多分类)损失函数在实际应用中非常广泛。本文将对这两种损失函数做简单介绍,包括损失函数的计算、梯度的求解以及Python中使用Numpy库函数进行实现。

SVM多分类

1. 损失函数

一般而言,深度学习中使用的SVM损失函数是基于 Weston and Watkins 1999 (pdf) 。 
其损失函数如下:

Li=jyimax(0,fjfyi+Δ)

在实际使用中, Δ  的值一般取1,代表间隔。

在神经网络中,由于我们的评分函数是: 

f=Wx




因此,可以将损失函数改写如下: 


Li=jyimax(0,WTjxiWTyixi+Δ)





如果考虑整个训练集合上的平均损失,包括正则项,则公式如下: 


L=1Nijyi[max(0,f(xi;W)jf(xi;W)yi+Δ)]+λklW2k,l

直观理解: 
多类SVM“想要”正确类别的分类分数比其他不正确分类类别的分数要高,而且至少高出delta的边界值。如果其他分类分数进入了红色的区域,甚至更高,那么就开始计算损失。如果没有这些情况,损失值为0。我们的目标是找到一些权重,它们既能够让训练集中的数据样例满足这些限制,也能让总的损失值尽可能地低。 
这里写图片描述



举一个具体的例子: 

例子来源于 斯坦福CS231n 课件。第一张图片是猫,神经网络计算得出其三个类别的分值分别为 3.2, 5.1 和 -1.7。很明显,理想情况下猫的分值应该高与其他两种类别,但根据计算结果,car的分值最高,因此在当前的权值设置下,该 network 会把这张图片分类为 car。此时我们可以根据公式计算损失 

损失计算如下:(S代表Score,即分值) 

Li=max(0,ScarScat+Δ)+max(0,SfrogScat+Δ)=2.9+0

这里写图片描述


2. 梯度公式推导

设置以下变量: 
– 矩阵  W  代表权值,维度是  DC ,其中  D  代表特征的维度, C  代表类别数目。 
– 矩阵  X  代表样本集合,维度是  ND , 其中  N  代表样本个数。 
– 分值计算公式为  f=XW ,其维度为  NC , 每行代表一个样本的不同类别的分值。

对于第  i  个样本的损失函数计算如下:

Li=jyimax(0,WT:,jxi,:WT:,yixi,:+Δ)

偏导数计算如下: 

LiW:,yi=(jyi1(wT:,jxi,:wT:,yixi,:+Δ>0))xi,:



LiW:,j=1(wT:,jxi,:wT:,yixi,:+Δ>0)xi,:

其中: 
–  w:,j  代表W矩阵第  j  列,其维度为  D 。 
–  xi,:  代表X矩阵的第  i  行,表示样本  i  的特征,其维度也为  D  。 
二者相乘,得出的是样本  i  在第  j  个类别上的得分。 
–  1  代表示性函数。 

3. python实现

包括向量化版本和非向量化版本:


def svm_loss_naive(W, X, y, reg):
""" # SVM 损失函数 native版本 Inputs have dimension D, there are C classes, and we operate on minibatches of N examples. Inputs: - W: A numpy array of shape (D, C) containing weights. - X: A numpy array of shape (N, D) containing a minibatch of data. - y: A numpy array of shape (N,) containing training labels; y[i] = c means that X[i] has label c, where 0 <= c < C. - reg: (float) regularization strength Returns a tuple of: - loss as single float - gradient with respect to weights W; an array of same shape as W """
dW = np.zeros(W.shape)    # initialize the gradient as zero
# compute the loss and the gradient
num_classes = W.shape[1]
num_train = X.shape[0]
loss = 0.0
# 对于每一个样本,累加loss
for i in xrange(num_train):
scores = X[i].dot(W)     # (1, C)
correct_class_score = scores[y[i]]
for j in xrange(num_classes):
if j == y[i]:
continue
# 根据 SVM 损失函数计算
margin = scores[j] - correct_class_score + 1    # note delta = 1
# 当 margin>0 时,才会有损失,此时也会有梯度的累加
if margin > 0:      # max(0, yi - yc + 1)
loss += margin
# 根据公式:∇Wyi Li = - xiT(∑j≠yi1(xiWj - xiWyi +1>0)) + 2λWyi
dW[:, y[i]] += -X[i, :]   # y[i] 是正确的类
# 根据公式: ∇Wj Li = xiT 1(xiWj - xiWyi +1>0) + 2λWj ,
dW[:, j] += X[i, :]
# 训练数据平均损失
loss /= num_train
dW /= num_train
# 正则损失
loss += 0.5 * reg * np.sum(W * W)
dW += reg * W
#
return loss, dW
#
def svm_loss_vectorized(W, X, y, reg):
""" SVM 损失函数 向量化版本 Structured SVM loss function, vectorized implementation.Inputs and outputs are the same as svm_loss_naive. """
loss = 0.0
dW = np.zeros(W.shape)   # initialize the gradient as zero
scores = X.dot(W)        # N by C 样本数*类别数
num_train = X.shape[0]
num_classes = W.shape[1]
scores_correct = scores[np.arange(num_train), y]
scores_correct = np.reshape(scores_correct, (num_train, 1))  # N*1 每个样本的正确类别
margins = scores - scores_correct + 1.0     # N by C 计算scores矩阵中每一处的损失
margins[np.arange(num_train), y] = 0.0      # 每个样本的正确类别损失置0
margins[margins <= 0] = 0.0                 # max(0, x)
loss += np.sum(margins) / num_train         # 累加所有损失,取平均
loss += 0.5 * reg * np.sum(W * W)           # 正则
# compute the gradient
margins[margins > 0] = 1.0                  # max(0, x) 大于0的梯度计为1
row_sum = np.sum(margins, axis=1)           # N*1 每个样本累加
margins[np.arange(num_train), y] = -row_sum  # 类正确的位置 = -梯度累加
dW += np.dot(X.T, margins)/num_train + reg * W     # D by C
return loss, dW
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82



Softmax 损失函数

1. 损失函数


Softmax 函数是 Logistic 函数的推广,用于多分类。

分值的计算公式不变: 

f(xi;W)=Wx

损失函数使用交叉熵损失函数,第  i  个样本的损失如下:

Li=log(efyijefj)

其中正确类别得分的概率可以被表示成:

P(yi|xi;W)=efyijefj

在实际使用中, efj  常常因为指数太大而出现数值爆炸问题,两个非常大的数相除会出现数值不稳定问题,因此我们需要在分子和分母中同时进行以下处理:

efyijefj=CefyiCjefj=efyi+logCjefj+logC



其中

C  的设置是任意的,在实际变成中,往往把

C 设置成: 


logC=maxfj


即第 

i  个样本所有分值中最大的值,当现有分值减去该最大分值后结果

0 ,放在 

e  的指数上可以保证分子分布都在
0-1之内。

2. 梯度推导

梯度的推导如下: 
这里写图片描述

3. Python实现

def softmax_loss_naive(W, X, y, reg):
""" Softmax loss function, naive implementation (with loops) Inputs have dimension D, there are C classes, and we operate on minibatches of N examples. Inputs: - W: A numpy array of shape (D, C) containing weights. - X: A numpy array of shape (N, D) containing a minibatch of data. - y: A numpy array of shape (N,) containing training labels; y[i] = c means that X[i] has label c, where 0 <= c < C. - reg: (float) regularization strength Returns a tuple of: - loss as single float - gradient with respect to weights W; an array of same shape as W """
# Initialize the loss and gradient to zero.
loss = 0.0
dW = np.zeros_like(W)
dW_each = np.zeros_like(W)
#
num_train, dim = X.shape
num_class = W.shape[1]
f = X.dot(W)        # 样本数*类别数 分值
#
f_max = np.reshape(np.max(f, axis=1), (num_train, 1))
# 计算对数概率 prob.shape=N*10 每一行与一个样本相对应 每一行的概率和为1
# 其中 f_max 是每行的最大值,exp(x)中x的值过大而出现数值不稳定问题
prob = np.exp(f - f_max) / np.sum(np.exp(f - f_max), axis=1, keepdims=True)
#
y_trueClass = np.zeros_like(prob)
y_trueClass[np.arange(num_train), y] = 1.0     # 每行只有正确的类别处为1,其余为0
#
for i in range(num_train):
for j in range(num_class):
loss += -(y_trueClass[i, j] * np.log(prob[i, j]))
dW_each[:, j] = -(y_trueClass[i, j] - prob[i, j]) * X[i, :]
dW += dW_each
loss /= num_train
loss += 0.5 * reg * np.sum(W * W)
dW /= num_train
dW += reg * W
return loss, dW
def softmax_loss_vectorized(W, X, y, reg):
""" Softmax loss function, vectorized version. Inputs and outputs are the same as softmax_loss_naive. """
loss = 0.0
dW = np.zeros_like(W)    # D by C
num_train, dim = X.shape
f = X.dot(W)    # N by C
# Considering the Numeric Stability
f_max = np.reshape(np.max(f, axis=1), (num_train, 1))   # N by 1
prob = np.exp(f - f_max) / np.sum(np.exp(f - f_max), axis=1, keepdims=True)
y_trueClass = np.zeros_like(prob)
y_trueClass[range(num_train), y] = 1.0    # N by C
# 计算损失 y_trueClass是N*C维度 np.log(prob)也是N*C的维度
loss += -np.sum(y_trueClass * np.log(prob)) / num_train + 0.5 * reg * np.sum(W * W)
# 计算损失 X.T = (D*N) y_truclass-prob = (N*C)
dW += -np.dot(X.T, y_trueClass - prob) / num_train + reg * W
return loss, dW
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72



Softmax、SVM损失函数用于CIFAR-10图像分类

CIFAR-10 小图分类是对于练习而言非常方便的一个数据集。通过在该数据集上实现基本的 softmax 损失函数 和 SVM 损失函数以及可视化部分结果,可以加深对算法的理解。

关于本文的全部代码可以到GitHub中下载

下面给出代码运行过程中的输出结果:

1. 可视化CIFAR-10的部分样本

这里写图片描述

原始像素作为特征使用SVM分类的损失图

这里写图片描述

两层神经网络使用softmax分类的损失和准确率图

这里写图片描述

两层神经网络使用softmax分类的第一个隐含层权重图:

这里写图片描述

参考资料

[1] http://www.jianshu.com/p/004c99623104 
[2] http://deeplearning.stanford.edu/wiki/index.php/Softmax%E5%9B%9E%E5%BD%92 
[3] http://blog.csdn.net/acdreamers/article/details/44663305 
[4] http://cs231n.github.io/

结束

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/153135.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • E-commerce 中促销系统的设计

    E-commerce 中促销系统的设计

  • 网络学习 局域网分类 以太网 令牌网 FDDI光纤分布式数据接口网 异步传输模式网(ATM) 无线局域网

    网络学习 局域网分类 以太网 令牌网 FDDI光纤分布式数据接口网 异步传输模式网(ATM) 无线局域网局域网虽然目前我们所能看到的局域网主要是以双绞线为代表传输介质的以太网,那只不过是我们所看到都基本上是企、事业单位的局域网,在网络发展的早期或在其它各行各业中,因其行业特点所采用的局域网也不一定都是以太网,目前在局域网中常见的有:以太网(Ethernet)、令牌网(TokenRing)、FDDI网、异步传输模式网(ATM)等几类,下面分别作一些简要介绍。1以太网是这样通信的,每台电…

  • UMLet的安装及使用

    UMLet的安装及使用

  • tomcat java_tomcat和maven的区别

    tomcat java_tomcat和maven的区别复杂的sql查询环境搭建CREATE TABLE `teacher` ( `id` INT(10) NOT NULL, `name` VARCHAR(30) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=INNODB DEFAULT CHARSET=utf8INSERT INTO teacher(id, name) VALUES (1,’秦老师’); CREATE TABLE `student` ( `id` INT(10) NOT NULL

  • 学单片机有前途还是嵌入式系统有前途好_嵌入式系统与单片机的前景

    学单片机有前途还是嵌入式系统有前途好_嵌入式系统与单片机的前景著名嵌入式工程师吴坚鸿曾经发过一贴“学单片机有前途还是嵌入式系统有前途?”原贴如下:http://www.makeru.com.cn/live/3523_1772.html?s=69821我在深圳一直搞单片机的开发,接的项目各种各样,不计其数。很多朋友问我学习单片机有前途还是嵌入式系统有前途,毫无疑问的,当然是单片机有前途。嵌入式系统现在炒得很火,满街到处都是嵌入式系统的培训。遇到很多刚入门…

  • BS架构和CS架构的优缺点

    BS架构和CS架构的优缺点1、CS、BS架构定义  CS(Client/Server):客户端—-服务器结构。C/S结构在技术上很成熟,它的主要特点是交互性强、具有安全的存取模式、网络通信量低、响应速度快、利于处理大量数据。因为客户端要负责绝大多数的业务逻辑和UI展示,又称为胖客户端。它充分利用两端硬件,将任务分配到Client和Server两端,降低了系统的通讯开销。C/S结构的软件需要针对不同的操作系

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号