CS231N课程作业

一. assignment1

1. Q1:k-Nearest Neighbor classifier(20 points)

The IPython Notebook knn.ipynb will walk you through implementing the kNN classifier.

(1)在做第一部分K-NN内容的时候 第一块代码块运行时报错ImportError: cannot import name ‘imread’ from ‘scipy.misc’ (/Users/ligang/opt/anaconda3/envs/cs231n/lib/python3.7/site-packages/scipy/misc/init.py)
导入包报错
大概意思就是scipy.misc不支持imread的导入,查看了好多论坛博客说的应该是新版本Scipy不再支持了,具体没去寻求细节 这里给出一个解决方案
在/cs231n/data_utils.py中修改其中的导入
将原来from scipy.misc import imread
改为from imageio import imread
在这里插入图片描述
修改后运行正常
在这里插入图片描述
(2)报错“ModuleNotFoundError: No module named ‘past’”在这里插入图片描述
运行pip3 install future后解决 past模块叫做future???
(3)open cs231n/classifiers/k_nearest_neighbor.py and implement the function compute_distances_two_loops that uses a (very inefficient) double loop over all pairs of (test, train) examples and computes the distance matrix one element at a time.
在相应位置填入代码计算两个矩阵相应行的L2距离。

dists[i,j]=np.sqrt(np.sum(np.square(X[i,:]-self.X_train[j,:])))

运行结果如下:
在这里插入图片描述
(4)实现k-nearest_neighbor.py文件中predict_labels的函数
第一部分插入如下代码片段:

closest_y = self.y_train[np.argsort(dists[i])[0:k]]

其中dists[i]是取出dists矩阵中的第i行,np.argsort()函数是输出其向量从大到小的索引下标(每个图片在训练数据中得分从大到小的排列的图片下标),然后[0:k]是取出前k个其下标,然后通过self.y_train[]获取k个最有可能类别的图片对应的标示(0-9),最后将其赋给closest_y。
第二部分插入如下代码片段

y_pred[i] = np.argmax(np.bincount(closest_y))

np.bincount()函数用来计数每个数字(该数字作为数组索引)出现的个数(感觉像是桶排序),然后通过np.argmax()函数求数组中元素最大的索引,即为数组中出现个数最多的那个元素,也就是kNN投票选出来的预测分类标示(0-9)。
在knn.ipynb中的运行结果如下:
在这里插入图片描述
(5)实现k_nearest_neighbor.py文件中compute_distances_one_loop()函数,补全代码

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

self.X_train-X[i] (矩阵-向量),这里用到了numpy中的broadcast。然后np.square()对其逐元素求平方,np.sum(,1)对矩阵进行按行求和,这里有一个迷惑的地方,numpy按行输出的是行向量,可能主观上会觉得是列向量。然后np.sqrt()对行向量求开方运算,并将其行向量赋给dists矩阵中的相应行。
运行过程中jupyter会显示为In[*],耐心等待运行结果即可。
运行结果:在这里插入图片描述
这里是算了两个矩阵是否相同,其中一个方法就是对比两个矩阵相减后矩阵的2模(2模即矩阵中各元素求和,如果两个矩阵相减后的矩阵的2模小于一个足够小的数就能证明这两个矩阵相同),numpy中有相应的函数np.linalg.norm(Matrix, ord=“fro”),ord对应的参数可以求1模、2模、无穷模等。
(6)实现k_nearest_neighbor.py文件中compute_distances_no_loops()函数,补全代码

dists += np.sum(np.square(X), 1).reshape(num_test, 1)
dists += np.sum(np.square(self.X_train), 1).reshape(1, num_train)
dists -= 2*np.dot(X, self.X_train.T)
dists = np.sqrt(dists)

相当于把每一个元素(Xi-X_trainj)的平方拆成了Xi的平方+X_trainj的平方-2XiX_trainj.这个应该叫做平方差公式吧
然后将拆解项中的每一项用numpy中的相应函数求解,如利用了两次broadcast.将行向量平铺赋给矩阵和将列向量平铺赋给矩阵,然后利用矩阵相乘求每一个Xi*X_trainj的值
最后做开方运算即得到距离矩阵。
执行结果如下:
在这里插入图片描述
(7)对比三种函数的计算效率
在这里插入图片描述
从运行结果看向量化计算比循环语句来说提升效率还是挺大的。从执行速度体验也能感受到,向量化计算比着循环简直快的不要不要的。
(6)交叉验证
将训练数据划分为5份,其中一份作为验证数据用来测试超参数选择的优劣,其余四份合在一起作为训练数据。

X_train_folds = np.array_split(X_train, num_folds)  # 划分为长度为5的列表。每个列表存一个矩阵
y_train_folds = np.array_split(y_train, num_folds)

对五份数据集进行划分、训练、预测和求准确率

train_x = np.row_stack(X_train_folds[0:4])
train_y = np.array(y_train_folds[0:4]).flatten().transpose()
val_x = X_train_folds[4]
val_y = y_train_folds[4]
classifier.train(train_x, train_y) #前四块当成训练集,后一部分当成验证集
dists = classifier.compute_distances_no_loops(val_x)
for i in k_choices:
    val_y_pred = classifier.predict_labels(dists, k=i)
    num_correct = np.sum(val_y_pred == val_y)
    accuracy = float(num_correct) / (val_y.shape[0])
    k_to_accuracies[i] = [accuracy]

运行结果如下:
ing

2. Q2: Training a Support Vector Machine (25 points)

The IPython Notebook svm.ipynb will walk you through implementing the SVM classifier.

(1)在图片数据预处理中出现如下语句

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

在这里插入图片描述
reshape函数是变换维度(总的元素个数不变),这个-1是将前面那个参数作为矩阵的行数,然后将其他维度变成一个维度,即将多维的数据变成了两维度,这里是将49000x32x32x3的数据维度变为49000x3072。
另一种解释:
reshape函数是对narray的数据结构进行维度变换,由于变换遵循对象元素个数不变,在进行变换时,假设一个数据对象narray的总元素个数为N,如果我们给出一个维度为(m,-1)时,我们就理解为将对象变换为一个二维矩阵,矩阵的第一维度大小为m,第二维度大小为N/m。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值