搭建一个简单的Softmax分类器(基于CS231n)
来源:互联网 发布:淘宝老七 编辑:程序博客网 时间:2024/05/17 02:06
- 生成数据集
- 训练一个Softmax线性分类器
- 初始化参数
- 计算得分
- 计算损失
- 反向传播法(Backpropagation)计算梯度值
- 参数更新
- 完整代码
本文是基于Stanford CS231n的学习笔记,搭建一个简单的Softmax分类器。1
生成数据集
首先是生成一个不易线性分割的数据集,本文采用的例子是螺旋数据集(Spiral Dataset)
N = 100 # number of points per classD = 2 # dimensionalityK = 3 # number of classesX = np.zeros((N*K,D)) # data matrix (each row = single example)y = np.zeros(N*K, dtype='uint8') # class labelsfor j in xrange(K): ix = range(N*j,N*(j+1)) r = np.linspace(0.0,1,N) # radius t = np.linspace(j*4,(j+1)*4,N) + np.random.randn(N)*0.2 # theta X[ix] = np.c_[r*np.sin(t), r*np.cos(t)] y[ix] = j# lets visualize the data:plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)plt.show()
通常情况我们需要预处理每个特征,进行Z-score标准化:
Z-score标准化有两个好处
1.是消除量纲对最终结果的影响,使不同变量具有可比性。比如两个人体重差10KG,身高差0.02M,在衡量两个人的差别时体重的差距会把身高的差距完全掩盖,标准化之后就不会有这样的问题。
2.均值为0,标准差为1
其中
具体可参考2
但是这个数据集的特征已经很好的分布于[-1,1],所以我们跳过这个步骤
训练一个Softmax线性分类器
初始化参数
Softmax分类器是由一个线性的 Score Function 并使用 Cross-entropy Loss Function,这个线性分类器的参数由一个权重矩阵
# initialize parameters randomlyW = 0.01 * np.random.randn(D,K)b = np.zeros((1,K))
这里的D=2指的是数据集的维度,K=3指的是数据集包含的类别。
计算得分
# compute class scores for a linear classifierscores = np.dot(X, W) + b
在这个例子中我们有300个二维的点,所以计算得出的矩阵
计算损失
分类器的第二个重要构成部分是损失函数,损失函数是一个可微的用来量化我们对于计算出的得分是否满意的函数。 我们希望每个点对应的正确的类别相比于其他类别取得一个更高的得分。在这个例子中我们会使用 Cross-entropy 损失函数,
Softmax分类器解释
(
NOTE:这个公式的数值永远介于0到1之间,当正确类别的概率接近0时,损失值会接近正无穷。相反地,如果正确类别的概率接近于1,损失值会接近于0。所以,当
整个分类器的损失值是所有训练例子的损失值的平均值加上正则损失值。(正则损失值是为了防止过拟合)
以下是代码
num_examples = X.shape[0]# get unnormalized probabilitiesexp_scores = np.exp(scores)# normalize them for each exampleprobs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
所以我们现在有了一个[300*3]的数组
corect_logprobs = -np.log(probs[range(num_examples),y])
# compute the loss: average cross-entropy loss and regularizationdata_loss = np.sum(corect_logprobs)/num_examplesreg_loss = 0.5*reg*np.sum(W*W)loss = data_loss + reg_loss
这个代码中,正则强度值
反向传播法(Backpropagation)计算梯度值
我们已经有了方法测量损失值(loss),现在我们要降低它。我们会采取梯度下降法。 首先我们引进一个中间变量
则训练样本i的loss是
现在我们想要得到是
这是一个很漂亮的结果,假设我们求得一个训练样本的概率值是 p = [0.2, 0.3, 0.5], 然后这个训练样本的正确类是第二类,则 df = [0.2, -0.7, 0.5]. 表示只有提升f中的第二个值才能降低loss. 以下为代码:
dscores = probsdscores[range(num_examples),y] -= 1dscores /= num_examples
最后,因为我们有 scores = np.dot(X, W) + b ,所以我们得知了dscores就可反向传播求得 db 和 dW 。
dW = np.dot(X.T, dscores)db = np.sum(dscores, axis=0, keepdims=True)dW += reg*W # don't forget the regularization gradient
参数更新
# perform a parameter updateW += -step_size * dWb += -step_size * db
完整代码
import numpy as npimport matplotlib.pyplot as plt# initialize parameters randomlyN = 100 # number of points per classD = 2 # dimensionalityK = 3 # number of classesX = np.zeros((N*K,D)) # data matrix (each row = single example)y = np.zeros(N*K, dtype='uint8') # class labelsfor j in xrange(K): ix = range(N*j,N*(j+1)) r = np.linspace(0.0,1,N) # radius t = np.linspace(j*4,(j+1)*4,N) + np.random.randn(N)*0.2 # theta X[ix] = np.c_[r*np.sin(t), r*np.cos(t)] y[ix] = jplt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)D=2K=3W = 0.01 * np.random.randn(D,K)b = np.zeros((1,K))# some hyperparametersstep_size = 1e-0reg = 1e-3 # regularization strength# gradient descent loopnum_examples = X.shape[0]for i in xrange(200): # evaluate class scores, [N x K] scores = np.dot(X, W) + b # compute the class probabilities exp_scores = np.exp(scores) probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) # [N x K] # compute the loss: average cross-entropy loss and regularization corect_logprobs = -np.log(probs[range(num_examples),y]) data_loss = np.sum(corect_logprobs)/num_examples reg_loss = 0.5*reg*np.sum(W*W) loss = data_loss + reg_loss if i % 10 == 0: print "iteration %d: loss %f" % (i, loss) # compute the gradient on scores dscores = probs dscores[range(num_examples),y] -= 1 dscores /= num_examples # backpropate the gradient to the parameters (W,b) dW = np.dot(X.T, dscores) db = np.sum(dscores, axis=0, keepdims=True) dW += reg*W # regularization gradient # perform a parameter update W += -step_size * dW b += -step_size * dbscores = np.dot(X, W) + bpredicted_class = np.argmax(scores, axis=1)print Wprint 'training accuracy: %.2f' % (np.mean(predicted_class == y))plt.show()
以下是Desicion Boundary的图,但是我不知道怎么画Desicion Bounday,有知道的朋友欢迎指导
关于本文涉及的更详细的SoftMax原理可参阅这里
- 搭建一个简单的Softmax分类器(基于CS231n)
- cs231n assignment(1.3):softmax分类器
- 训练一个简单的神经网络(基于CS231n)
- CS231n课程笔记3.1:线性分类器(SVM,softmax)的误差函数、正则化
- cs231n-(2)线性分类器:SVM和Softmax
- 20161206#cs231n#2.线性分类器 Assignment1--SVM&Softmax
- cs231n的第一次作业Softmax
- cs231n一次课程实践,python实现softmax线性分类器和二层神经网络
- 【Python 代码】CS231n中Softmax线性分类器、非线性分类器对比举例(含python绘图显示结果)
- 基于DL的计算机视觉(3)-- SVM和Softmax分类器
- 深度学习-基于softmax神经网络分类的源码实现
- softmax的多分类
- cs231n-线性分类器
- 基于lamp搭建一个简单的论坛
- softmax分类器
- Softmax分类回归器
- softmax分类器推导
- softmax分类器
- BZOJ2434 NOI2011 洛谷2414 阿狸的打字机
- MySQL自带的database
- hihocoder#1062 : 最近公共祖先·一
- ajax简单版
- ccf 推荐会议和期刊
- 搭建一个简单的Softmax分类器(基于CS231n)
- 探索 Android Studio
- 《深入理解Java虚拟机之栈帧的结构》
- 无源无汇上下界网络流(循环流) ZOJ 2314 Reactor Cooling
- js表单提交
- 哈哈日语初学需掌握会话
- Android中的Ajax
- Viewpager无限轮播加小圆点
- 数据库主从配置