一些准备工作
- python环境
- 官方课程给出的源文件在这里
根据文件里的指导一步步编写答案就可。第一个实现KNN分类器。
- 如果是windows环境,需要首先下载数据集。The CIFAR-10 dataset官网
官网上也有关于本数据集的说明
往下翻到下载,选择python版本的下载即可。如果用的是Unix系统可以用斯坦福课程给出的方式进行数据集的获取。
inline question的分析
//to do
knn.ipynb
首先打开spring1819_assignment1\assignment1文件夹下面的knn.ipynb。
我是用的anaconda 用jupyter notebook打开这个文件。
from spring1819_assignment1.k_nearest_neighbor import KNearestNeighbor
KNearestNeighbor是要我们自己写的一个类,在spring1819_assignment1\assignment1\cs231n\classifiers里的k_nearest_neighbor.py文件中。
第一次做作业可以先用别的写的k_nearest_neighbor.py运行一遍knn.ipynb,然后再自己写这个分类器。
先试试这个自定义的类能不能导入,我在__init__函数里加了一个打印语句。
knn=KNearestNeighbor()
This is KNN2 classifier by wzd
import random
import numpy as np
from cs231n.data_utils import load_CIFAR10
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (10.0, 8.0) # set default size of plots
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'
# coding:utf-8
导入数据,课程示例给出的方法不适合Windows系统,需要手动下载数据集,然后用绝对路径加载
cifar10_dir = 'D:\CIFAR10'#data_path
X_train, y_train, X_test, y_test = load_CIFAR10(cifar10_dir)
training data里有五万个数据,但是本作业只会选取一部分使用
print ('Training data shape: ', X_train.shape)
print ('Training labels shape: ', y_train.shape)
print ('Test data shape: ', X_test.shape)
print ('Test labels shape: ', y_test.shape)
Training data shape: (50000, 32, 32, 3)
Training labels shape: (50000,)
Test data shape: (10000, 32, 32, 3)
Test labels shape: (10000,)
把数据集里的例子可视化,展示一些训练集里面的样本样本
classes = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
num_classes = len(classes)
samples_per_class = 7
for y, cls in enumerate(classes):
idxs = np.flatnonzero(y_train == y)
idxs = np.random.choice(idxs, samples_per_class, replace=False)
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()
在本练习中,为了更有效地执行代码,对数据进行了细分
num_training = 5000
mask = list(range(num_training)) #机产生训练样本的位置
X_train = X_train[mask] #选择训练样本
y_train = y_train[mask] #确定训练样本标签
num_test = 500
mask = list(range(num_test))
X_test = X_test[mask]
y_test = y_test[mask]
这里是把(50000, 32, 32, 3)变成 (5000, 3072)。一个图片用一个32323的一行来表示,相当于把一个图片拉成一个行向量。
# Reshape the image data into rows
X_train = np.reshape(X_train, (X_train.shape[0], -1))
X_test = np.reshape(X_test, (X_test.shape[0], -1))
print(X_train.shape, X_test.shape)
(5000, 3072) (500, 3072)
用KNN分类器进行训练
classifier = KNearestNeighbor()
classifier.train(X_train, y_train)
This is KNN2 classifier by wzd
KNN分类器是要把预测的样本与训练集比较,找到离训练集最近的。所以train()的作用是把训练集X_train绑定到类KNearestNeighbor的属性self.X_train
dists = classifier.compute_distances_two_loops(X_test)
print(dists.shape)
(500, 5000)
dists 表示的是test集与training data的距离,dists[i, j] 表示的是test的第i个与training data的第j个的距离。
# We can visualize the distance matrix: each row is a single test example and
# its distances to training examples
plt.imshow(dists, interpolation='none')
plt.show()
这里有问题要回答,关于这个图的理解
得到了dists以后,就可以预测test data里的图片的分类。dists的第i行表示,test的第i个样本与5000个训练集数据的距离,找到距离最小的K个训练集图片,他们的图片类型就是我们预测的结果y_test_pred。
这里指定了k=1,在classifier.predict_labels函数中就只会找到距离最小的一个图片,他的类别就是对test预测的类别。
# Now implement the function predict_labels and run the code below:
# We use k = 1 (which is Nearest Neighbor).
y_test_pred = classifier.predict_labels(dists, k=1)
# Compute and print the fraction of correctly predicted examples
num_correct = np.sum(y_test_pred