cs231n学习之路:2. 线性分类器

最简单的线性分类器:
f ( x , W , b ) = W x + b f(x, W,b)= Wx + b f(x,W,b)=Wx+b
W和b是训练参数。x是输入数据。在公式中,x和b是向量,x是单个样本reshape之后的向量,b的长度和类别数目一致,W是矩阵。所以我们想将线性分类器应用到图像上,就必须先将图像reshape为一个向量。

W的含义

W的shape是[out_dims,in_dims]

  • out_dims:一共有几个类别
  • in_dims,把输入图像reshape成向量的长度。

对线性分类器可以是如下理解:

在深度学习尤其是识别分类任务中,常常会用到内积相似性,即两个向量相乘的积越大,这两个向量在特征空间的余弦( cos )距离越小。而W和x相乘,就是计算样本和每一个类别的表征向量的相似性。W如果按照行抽取出来,我们可以获得in_dims个向量,向量的长度是输入图像的reshape之后的长度。

当模型训练完毕,我们得到了较好的W参数之后,就按照行抽取出来in_dims个向量,把这些向量reshape为图像大小,然后imshow出来,就是课程上的这幅图。
在这里插入图片描述
每一类都有自己的一个表征。这个表征可以被视作代表了这个类别的大致图像,如果输入图像和某个类的表征的乘积很大,则说明这个图像属于这个类的概率很大。
这就是线性分类器的大致思想。

code

import numpy as np

class LinearClassifier(object):
    def __init__(self):
        self.W = None

    def train(self,x,y,learning_rate=1e-3,reg=1e-5,num_iters=100,
              batch_size=200):
        # 训练样本数目, 一个样本的向量长度
        num_train, dim = x.shape
        num_classes = np.max(y) + 1 # 假设y在[0 - k-1]之间, 我们需要的是那个k,所以这里加1
        if self.W == None:
            self.W = 0.001 * np.random.randn(dim, num_classes)
        loss_history = []
        for it in range(num_iters):
            # 为当前迭代 随机挑选出 训练集
            random_index = np.random.choice(len(x),batch_size,replace=True)
            x_batch = x[random_index]
            y_batch = y[random_index]

            loss, grad = self.loss(x_batch,y_batch,reg)
            loss_history.append(loss)

            # 更新参数W
            self.W -= learning_rate*grad


    def loss(self,x,y,reg):
        dw = np.zeros_like(self.W)
        num_classes = self.W.shaoe[1]
        batch_size = x.shape[0]

        scores = x.dot(self.W)  # x * w
        # the shape of scores is [ batch_size. num_classes ]
        exp_scores = np.exp(scores)
        softmax_scores = exp_scores / np.sum(exp_scores,axis=1)
        exp_corrent_class_scores = softmax_scores[np.arange(batch_size), y]

        loss = - np.log(exp_corrent_class_scores).mean()
        loss += 0.5*reg*np.dot(self.W,self.W)  # 正则化

        # 求导
        # softmax的求导是经过softmax得到的矩阵,在每个正例位置减一
        # z = x*w +b
        # a = softmax(z)
        # loss = -y*log(a)
        grad_z = softmax_scores
        grad_z[np.arange(batch_size),y] -= 1
        grad_w = x.T.dot(grad_z)
        grad_w /= batch_size # 梯度求平均
        grad_w += reg*self.W
        return loss, grad_w
        

代码解释

使用的是随机梯度下降法,代码整体结构简单,思路清晰。读者们不懂的地方可能就是求导那里是怎么来的了。
这就涉及到了softmax的求导,以及矩阵求导的知识了,我将在下一篇博客专门介绍。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值