2020版的斯坦福CS231n深度学习与计算机视觉的课程作业1,这里只是简单做了下代码实现,并没有完全按照作业要求来。
1 k-Nearest Neighbor classifier
使用KNN分类器分类Cifar-10数据集中的图片,这里使用Pytorch的张量广播和一些常用运算快速实现一下,并没有考虑效率。基本操作和numpy大同小异。
from collections import Counter
def knn(X,y,X_unknown,k=1):
# 3通道图像展平成1维向量
X = X.reshape(X.size(0),-1)
X_unknown = X_unknown.reshape(X_unknown.size(0),-1)
num_classes = y.max()+1
y_pred = []
for x in X_unknown:
# 计算x到数据集X各样本的平均绝对值距离
L1_dist = torch.abs(X-x).sum(dim=1)
# 选择距离最小的k个样本
near_indices = torch.argsort(L1_dist)[:k]
near_labels = y[near_indices]
counter = Counter(near_labels.numpy())
max_count_label = max(counter,key=lambda x:counter[x])
y_pred.append(max_count_label)
return y_pred
sampled_images = X_test[:16]
fig, ax = plt.subplots(4, 4, figsize=(15, 15))
class_names = ['airplane','moblie car','bird','cat','deer','dog','frog','horse','ship','truck']
y_pred = knn(X_train,y_train,sampled_images,k=50)
for i,img in enumerate(sampled_images):
ax[i//4][i%4].imshow(img)
ax[i//4][i%4].set_title('prediction:'+class_names[y_pred[i]])
KNN的每张图片都需要遍历训练集的50000张图片才能找到解,所以只采样200张测试集图片估算正确率
from sklearn.metrics import accuracy_score
images_test = X_test[:200]
labels_test = y_test[:200]
labels_pred = knn(X_train,y_train,images_test,k=50)
print(accuracy_score(labels_test,labels_pred))
0.355
很显然,KNN不需要训练就能取得比瞎猜好一些的正确率,但是想进一步寻求提升则并不那么简单。最重要的,KNN的每次查询都要遍历数据集,这是非常巨大的时间开销。
2 Training a Support Vector Machine
实现多分类线性支持向量机分类cifar-10。在传统机器学习的二分类SVM中,我们构造约束优化问题,并借助序列最小优化算法快速求解SVM。同时,SVM也有无约束优化的版本,使用hinge loss和正则化实现。这里的多分类SVM和二分类SVM略有区别,但其损失函数都是hinge loss
l o s s ( x , y ) = 1 N ∑ i = 0 N − 1 ( m a x ( 0 , m a r g i n − x [ y ] + x [ i ] ) ) loss(x, y) = \frac{1}{N}\sum_{i=0}^{N-1}(max(0, margin - x[y] + x[i])) loss(x,y)=N1