CS231n knn.ipynb作业

CS231n assignment1

KNN分类器

第一个作业的第一个问题,写KNN分类器,KNN的原理本身描述起来还是比较简单

这里再啰嗦两句,对KNN分类器的一些描述

KNN算法,只找最相近的那1个图片的标签,我们找最相似的k个图片的标签,然后让他们针对测试图片进行投票,最后把票数最高的标签作为对测试图片的预测。所以当k=1的时候,k-Nearest
Neighbor分类器就是Nearest
Neighbor分类器。从直观感受上就可以看到,更高的k值可以让分类的效果更平滑,使得分类器对于异常值更有抵抗力。

在完成knn.ipynb作业

一、在KNN中 对数据集可视化部分 用到的一些函数:

  1. idxs = np.flatnonzero(y_train == y)
    这部分使用到了numpy.flatnonzero(),这个该函数输入一个矩阵,返回扁平化后矩阵中非零元素的位置(index)

    在作业中,是用来返回特定元素的位置,如果y_train 图的标签和当前y指向的classes是同一个类别的,则位置赋给idxs

  2. plt.subplot(samples_per_class, num_classes, plt_idx)
    这部分使用了matplotlib.pyplot.subplot(XXX):前两个数表示子图组成的矩阵的行列数,第三个数表示画第X个图。

    在作业中 说明要画的子图的编号

    # Visualize some examples from the dataset.
    # We show a few examples of training images from each class.
    classes = [‘plane‘, ‘car‘, ‘bird‘, ‘cat‘, ‘deer‘, ‘dog‘, ‘frog‘, ‘horse‘, ‘ship‘, ‘truck‘]    #分出类别的列表classes
    num_classes = len(classes) #类别数目
    samples_per_class = 7 # 每个类别采样个数
    for y, cls in enumerate(classes): # 对列表的元素位置和元素进行循环,y表示元素位置(0,num_class),cls元素本身‘plane‘等
        idxs = np.flatnonzero(y_train == y)  #找出标签中y类的位置
        idxs = np.random.choice(idxs, samples_per_class, replace=False) #从中选出我们所需的7个样本
        for i, idx in enumerate(idxs): #对所选的样本的位置和样本所对应的图片在训练集中的位置进行循环
            plt_idx = i * num_classes + y + 1 # 在子图中所占位置的计算
            plt.subplot(samples_per_class, num_classes, plt_idx) # 说明要画的子图的编号
            plt.imshow(X_train[idx].astype(‘uint8‘)) # 画图
            plt.axis(‘off‘)
            if i == 0:
                plt.title(cls) # 写上标题,也就是类别名
    plt.show() # 显示图片

二 、转到k_nearest_neighbor.py文件进行编辑,完善代码

  • 两层循环
    训练集维度 (5000, 3072)
    测试集维度(500, 3072)
    那么dists就是一个(500,5000)的维度
    由L2-Distance的公式
    很快就能写出两层循环时的dists

      dists[i,j]=np.sqrt(np.sum(np.square(X[i,:]-self.X_train[j,:])))
    
  • 一层循环
    只有一层循环 而dists的维度仍然是(500,5000),因此需要把一个的维度变化,因为循环的是num_test,因此把X[i , : ]的0维变为1
    CS231n knn.ipynb作业_第1张图片
    dists如下:

      dists[i, :] = np.sqrt(np.sum(np.square(self.X_train - X[i, :]), axis=1))
    
  • 零层循环

    需要将L2-D的函数形式进行变换,开平方
    变为(x-y)^2 = x^2 + y^2 - 2xy

      dists = np.sqrt(np.sum(X**2, axis=1, keepdims=True) + (-2 * np.dot(X, self.X_train.T)) + np.sum(self.X_train**2, axis=1))
    
  • 修改predict_labels

    按照给的提示,使用argout函数,通过argsort可以返回数组当中的从小到大的索引数组!

        # y_train shape(5000,)
        def predict_labels(self, dists, k=1):
            num_test = dists.shape[0]
            y_pred = np.zeros(num_test)
            # 上面两层循环的得出dists shape(500,5000)
            # 下面通过循环来得出测试图片500张与训练图片5000张距离最近的前k个
            for i in range(num_test):
            	closest_y = []
                # 目的是得出测试图片500张与训练图片5000张距离最近的前k个
            	closest_y = self.y_train[np.argsort(dists[i,:])[:k]]
                # 投票得出预测值
                y_pred[i] = np.argmax(np.bincount(closest_y))
           	return y_pred
    

    在对k个图片投票时候,得票数最多的就是预测值,那么这里运用了,numpy的argmax与bincount,首先通过bincount计算出数组中索引出现的次数,为什么要这么取?

因为我们在预测后,会有很多个label,而当我们取出距离前k个label,只需要统计在这k个label中计算每个label的次数,然后直接再通过argmax取出出现次数最多的就是最后的预测结果!

到这里k_nearest_neighbor.py文件修改结束。

三 、非常重要的一点,就是colab对goole driver的授权

  1. 方法一
!apt-get install opam
!opam init
!opam update
!opam install depext
!opam depext google-drive-ocamlfuse
!opam install google-drive-ocamlfuse
#进行授权操作
from google.colab import auth
auth.authenticate_user()
from oauth2client.client import GoogleCredentials
creds = GoogleCredentials.get_application_default()
import getpass
!/root/.opam/system/bin/google-drive-ocamlfuse -headless -id={creds.client_id} -secret={creds.client_secret} < /dev/null 2>&1 | grep URL
vcode = getpass.getpass()
!echo {vcode} | /root/.opam/system/bin/google-drive-ocamlfuse -headless -id={creds.client_id} -secret={creds.client_secret}
#!!!注意,里面的/root/.opam/system/bin/google-drive-ocamlfuse换成你自己的路径,一般来说你也会得到和我一样的结果
#指定Google Drive云端硬盘的根目录,名为drive
!mkdir -p drive
!/root/.opam/system/bin/google-drive-ocamlfuse drive
  1. 方法二
!apt-get install -y -qq software-properties-common python-software-properties module-init-tools
!wget https://launchpad.net/~alessandro-strada/+archive/ubuntu/google-drive-ocamlfuse-beta/+build/15740102/+files/google-drive-ocamlfuse_0.7.1-0ubuntu3_amd64.deb
!dpkg -i google-drive-ocamlfuse_0.7.1-0ubuntu3_amd64.deb
!apt-get install -f
!apt-get -y install -qq fuse
from google.colab import auth
auth.authenticate_user()
from oauth2client.client import GoogleCredentials
creds = GoogleCredentials.get_application_default()
import getpass
!google-drive-ocamlfuse -headless -id={creds.client_id} -secret={creds.client_secret} < /dev/null 2>&1 | grep URL
vcode = getpass.getpass()
!echo {vcode} | google-drive-ocamlfuse -headless -id={creds.client_id} -secret={creds.client_secret}

# 指定Google Drive云端硬盘的根目录,名为drive
!mkdir -p drive
!google-drive-ocamlfuse drive
  1. 方法三
from google.colab import drive

# This will prompt for authorization.
drive.mount('/content/drive')

cd /content/drive/My Drive/drive/assignment1

你可能感兴趣的:(cs231n)