cs231n训练营学习笔记(3)

 

1. f(x,w)线性分类器与knn区别

knn直接用图像的像素距离做分类,线性分类器是用特征的线性组合来分类

knn直接把所有图像像素存下来作为训练结果来与测试图像比对,

线性分类器会得到W,b,也就是训练得到的权重和偏差参数,f(x,w)=Wx+b这种得到的特征的线性组合就是模板,可以说是一种全局特征,然后用训练得到的模板和测试图像比对

b这个偏差是当数据集不平衡时候,为了训练效果更好而存在的,如果数据集里猫的图片比狗多很多,那b里对应猫的值就比狗大

b是不与训练数据交互的,值更大说明由于图片比较多,所有是这个类的可能性也更高一点

线性分类器会作为基本的小单元组成神经网络,f(x,w)可以有不同的样子,Wx+b是最简单的形式

2. 线性分类器为什么可以看成一种模板匹配方法

W的每一行单独拿出来看,比如第一行,这个行向量和图片拉成的列向量相乘,向量相乘是衡量距离的,两个向量越相似,结果越大(因为夹角小,a·b=|a||b|cosθ),所以得到结果的第一个数字对应这个类的得分。W的每一行就是一个该类的模板。训练线性分类器就是为了学习得到W,也就是得到每个类的模板,预测的时候用模板去匹配(也就是,同样向量相乘)得到每个类的匹配度。

对于线性分类器两种说法的总结:

线性分类器可以解释成每个类的学习模板

W中的每一项,对应输入图片中的某一个像素值,告诉我们这个像素值对于分类有多少影响

这说明W中的每一行都对应一个分类模板

还有一种对线性分类器的解释是,learning linear decision boundaries between pixels in some high dimensional space where the dimensions of the space correspond to the values of the pixels intensity values of the image

学习像素在高维空间的一个线性决策边界,其中高维空间就对应了图片中的像素值

3. 线性分类器的缺点也就是存在的问题

(1)如果类别增多,那么需要的模板就多,W就多一行,整个模型需要重新训练

(2)每个类别只能学习一个模板,这个模板很可能并不能很好的代表这个类,更复杂的神经网络可以解决这个问题

(3)只能用于线性可分的情况,线性不可分的情况比如下面的奇偶数分类,或者多模态数据(向左看的马和向右看的马,这和第二点是同样的)

最左边的图,数据集里有两类,蓝色和红色,如果图像像素都是奇数就是蓝色,图像像素都是偶数就是红色

没法画一条线把两类分开。

这里的坐标轴没法有具体的意义,因为是高维空间压缩成二维的示意图

4. knn代码

for y, cls in enumerate(classes):

对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值,classes前面设成list,这句的意思是y是类的索引,cls是具体的类的名字

idxs = np.flatnonzero(y_train == y)

返回y_train里面值为y的索引,其中y_train是NumPy Ndarray 对象,是N 维数组对象,存放同类型元素的多维数组

idxs = np.random.choice(idxs, samples_per_class, replace=False)

从idxs里随机抽取数字,组成samples_per_class大小的数组,replace=False表示不可以取相同的数字

 plt.subplot(samples_per_class, num_classes, plt_idx)

设置子图的位置 ,参数是行数、列数和索引值,子图将分布在行列的索引位置上。索引从1开始,从左上角增加到右下角。

这是cifar10数据可视化的结果

程序下一步的操作是取了训练集5万里的前5千,取了测试集1万里的前5百

X_train = np.reshape(X_train, (X_train.shape[0], -1))

把图片拉伸成一列,方便作为分类器的输入,(X_train.shape[0], -1)是newshape,其中-1表示Numpy会根据剩下的维度计算出数组的另外一个属性值。

导入KNearestNeighbor分类器的时候,报错

----> 2 from past.builtins import xrange
ModuleNotFoundError: No module named 'past'

解决办法不是下载past包,而是下future包……这是什么哲学问题吗

这是可视化的L2距离计算结果,越白代表距离越远

What in the data is the cause behind the distinctly bright rows?

明显很亮的行代表某个测试数据距离每个训练数据都很远,它可能并不属于十个类里任何一个

What causes the columns?

明显很亮的列代表某个训练数据与每个测试数据都距离很远,可能训练数据不好

用k=1预测得到0.274的准确率

k!=1的时候,用到了个很好用的np函数,np.argpartition(arr, k),返回索引,其中前k个是最小的k个,并不在意内部的大小顺序。

np.argpartition可能比np.argsort效率更高点

def predict_labels(self, dists, k=1):
    num_test = dists.shape[0]
    y_pred = np.zeros(num_test)
    for i in xrange(num_test):
        closest_y = []
        idxs = np.argsort(dists[i])[0:k + 1]

        for idx in idxs:
            closest_y.append(self.y_train[idx])

        bin = np.bincount(closest_y)
        where = np.where(bin == max(bin))
        y_pred[i] = where[0][0]    
    return y_pred

k=5的时候稍微准确率高一点,0.282

最后两步麻烦了,用np.argmax就行了

为了提高计算距离的效率,把之前的两层循环变成一层循环,就是利用向量

dists[i, :] = np.sqrt(np.sum(((self.X_train - X[i])**2), axis = 1))

其中,X[i]按照self.X_train的格式braodcast了

把一层循环也去掉,就是所有的训练集和测试集一起上,同时向量

利用的是的原理

用到np.repeat和np.reshape以及np.diag

接下来交叉验证

for k in k_choices:
    accuracies = []
    for i in range(num_folds):
        X_val_train = np.vstack(X_train_folds[0:i] + X_train_folds[i+1:])
        y_val_train = np.hstack(y_train_folds[0:i] + y_train_folds[i+1:])
        X_test_sub = X_train_folds[i]
        y_test_sub = y_train_folds[i]
        X_val_train = np.reshape(X_val_train, (X_val_train.shape[0], -1))
        X_test_sub = np.reshape(X_test_sub, (X_test_sub.shape[0], -1))
        classifier.train(X_val_train, y_val_train)
        y_pred = classifier.predict(X_test_sub, k)
        num_correct = np.sum(y_pred == y_test_sub)
        num_test = len(y_test_sub)
        accuracy = float(num_correct) / num_test
        accuracies.append(accuracy)
    k_to_accuracies[k] = accuracies

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值