KNN SVM Softmax 在 CIFAR-10上的图像识别

本文基于CIFAR-10数据集,探讨KNN、SVM和Softmax在图像识别中的应用。通过预处理、训练和优化,比较了三者在识别效率和准确率上的表现。KNN算法实现简单但计算量大,最终准确率为28%;SVM与Softmax采用不同的损失函数,经过优化后,SVM达到36.9%的准确率,Softmax达到35.5%。
摘要由CSDN通过智能技术生成

概述

这篇博客以CIFAR-10数据集为基础,从对图像识别基础的预处理部分分析其背后理论,到讲述对KNN SVM Softmax的具体实现,并通过验证集进行参数调优,最后展开结果性分析,介绍基本的图像识别应用,材料部分来自于Stanford CS231n 的notes和assignments(project)。

CIFAR-10介绍

该数据集共有60000张彩色图像,每张图像是32*32*3的像素,相对较小且不需要分割提取的过程,可以直接进行处理,分为10个类,每类6000张图。这里面有50000张用于训练,构成了5个训练批,每一批10000张图;另外10000用于测试,单独构成一批。测试批的数据里,取自10类中的每一类,每一类随机取1000张。抽剩下的就随机排列组成了训练批。

如果是从CS231n提供的框架中下载的数据集,在Linux环境下只需要运行get_datasets.sh,为方便处理文件是以16进制存储的

这里对图像的提取不做赘述

上面就是从数据集中抽取的部分图片,可以看出就算一个类别内但彼此的差异性还是比较大的。抽取部分图片并展示的代码:

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()

KNN进行图像识别

应该说,KNN是最为直观的识别算法,也易于实现,值得一提的是,我记得上次有同学在课程上尝试用《机器学习实战》书上的代码进行手写字识别,但是运行时间实在太长,其实虽然KNN是一种很耗费计算资源且如果数据维数变高后会变得十分恐怖的算法,但在面对大量数据时依旧可以通过矩阵化的计算极大地优化计算。

首先,对图像进行预处理,将我们32*32*3的每个图像化成一行,并且由于KNN并不是我们今天的主角且耗时较大,我们没有用全部的数据集进行训练,抽取了5000张数据集和500张测试集进行实验,目的是为了与SVM Softmax进行比较。

下面提供KNN代码,用类封装:

 
import numpy as np
class KNearestNeighbor(object):

  def __init__(self):
    pass
  def train(self, X, y):
    self.X_train = X
    self.y_train = y
   
  def predict(self, X, k=1, num_loops=0):
    if num_loops == 0:
      dists = self.compute_distances_no_loops(X)
    elif num_loops == 1:
      dists = self.compute_distances_one_loop(X)
    elif num_loops == 2:
      dists = self.compute_distances_two_loops(X)
    else:
      raise ValueError('Invalid value %d for num_loops' % num_loops)

    return self.predict_labels(dists, k=k)

  def compute_distances_two_loops(self, X):
    num_test = X.shape[0]
    num_train = self.X_train.shape[0]
    dists = np.zeros((num
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值