KNN图像分类完整版(从制作数据集到完成分类)

版权声明:本文为博主原创文章,转载请注明作者和出处。https://blog.csdn.net/xq920831/article/details/83892585

 

这篇主要为记录帖,整理一下这几天的工作。

进入正题!

一、制作数据集

网上大多数为cifar-10数据集上训练,那么如果我们有自己的数据,怎么将自己的数据做成数据集将是开始的关键一步。

这里给出制作pkl数据的方法

注:pkl单次只能处理4GB一下的数据量,如果数据量很大,则手动分块处理,dump多次。我自己对比了一下pickle和joblib,感觉没什么区别(可能是我的数据集太大的缘故),二者都不能一次处理完。

我自己的数据集:一个测试集,九个训练集(手动分)。

由于我的彩色原图太多,且分辨率比较高,为了考虑整体的训练效果,这里把图片统一reshape为100*100的。

代码如下:

# -*- coding:utf-8 -*-
# Author: Agent Xu

from skimage import io,transform
import numpy as np
import random
import pickle
import os
import joblib

w = 100
h = 100

#函数调用:生成数据集
def initPKL(img_arr , train_or_test):
    labels = []
    img_arr1 = np.zeros((len(img_arr),30000))
    if train_or_test == 'train':
        set_name = 'trainSet_9.pkl'
    else:
        set_name = 'testSet.pkl'
    k = 0
    for i in img_arr:
        # imgSet.append(i)
        i[0] = i[0].flatten()
        img_arr1[k][:] = i[0]
        k +=1
        labels.append(i[1])

    img_arr1 = np.array(img_arr1)
    labels = np.array(labels)
    arr = (img_arr1,labels)

    #写入文件
    data = (arr[0],arr[1])
    output = open(set_name, 'wb')
    pickle.dump(data, output)
    output.close()

def initArr(folders_path):

    i = 0

    imgSet = []
    folders = os.listdir(folders_path)

    for folder in folders:
        #类别个数,几个0代表几类
        label = [0,0,0,0,0]
        files = os.listdir(folders_path + folder)
        label[i] = 1
        for file in files:
            #读取图片
            img = io.imread(folders_path + folder + '/' + file)
            img = transform.resize(img,(w,h))
            img_arr = np.array(img,dtype='float64') / 256
            imgSet.append((img_arr,label))
        i += 1
    return imgSet

#将图片转换成数组
#train_folders_path = 'D:/GJAI_data/tupian/train_9/'
test_folders_path = 'D:/GJAI_data/tupian/validation/'

#train_imgSet = initArr(train_folders_path)
test_imgSet = initArr(test_folders_path)

#打乱顺序
#random.shuffle(train_imgSet)
random.shuffle(test_imgSet)

#train_set_shuffle = np.array(train_imgSet)
test_set_shuffle = np.array(test_imgSet)

# 分别生成训练集和测试集
#initPKL(train_set_shuffle, 'train')
initPKL(test_set_shuffle, 'test')

# #测试生成的数据集
# f = open('./trainSet_1.pkl', 'rb')
# x, y = pickle.load(f)
# f.close()
#
# print(np.shape(x[3]), y[3])

训练集和测试集可分开,注释掉相应代码即可(上面的代码为生成测试集的pkl文件)。

如有疑问,欢迎留言。

 

二、KNN训练分类

# -*- coding:utf-8 -*-
# Author: Agent Xu

import numpy as np
import os
import pickle

class kNearestNeighbor:
    def __init__(self):
        pass

    def train(self, X, y):
        self.Xtr = X
        self.ytr = y

    def predict(self, X, k=1):
        num_test = X.shape[0]
        Ypred = np.zeros(num_test, dtype = self.ytr.dtype)
        for i in range(num_test):
            distances = np.sum(np.abs(self.Xtr - X[i,:]), axis = 1)
            closest_y = y_train[np.argsort(distances)[:k]]
            u, indices = np.unique(closest_y, return_inverse=True)
            Ypred[i] = u[np.argmax(np.bincount(indices))]
        return Ypred


def load_data_batch(filename):
    """ load single batch of cifar """
    with open(filename, 'rb') as f:
        X,Y = pickle.load(f,encoding='latin1')
        Y = Y.tolist()
        for w in range(len(Y)):
            Y[w] = Y[w].index(1)
        X = X.reshape(len(Y), 3, 100, 100).transpose(0,2,3,1).astype("float")
        Y = np.array(Y)
        return X, Y


def load_data(ROOT):
    """ load all of cifar """
    xs = []
    ys = []
    for b in range(1,10):
        f = os.path.join(ROOT, 'trainSet_%d.pkl' %(b))
        X, Y = load_data_batch(f)
        xs.append(X)
        ys.append(Y)
    Xtr = np.concatenate(xs) #使变成行向量
    Ytr = np.concatenate(ys)
    del X,Y
    Xte, Yte = load_data_batch(os.path.join(ROOT, 'testSet.pkl'))
    return Xtr, Ytr, Xte, Yte


Xtr, Ytr, Xte, Yte = load_data('D:/GJAI_data/tupian')
Xtr_rows = Xtr.reshape(Xtr.shape[0], 100 * 100 * 3)
Xte_rows = Xte.reshape(Xte.shape[0], 100 * 100 * 3)


num_training = 16000
num_test = 1900
x_train = Xtr_rows[:num_training, :]
y_train = Ytr[:num_training]

x_test = Xte_rows[:num_test, :]
y_test = Yte[:num_test]

knn = kNearestNeighbor()
knn.train(x_train, y_train)
y_predict = knn.predict(x_test, k=7)
acc = np.mean(y_predict == y_test)
print('accuracy : %f' %(acc))

代码参考:https://blog.csdn.net/zhousishuo/article/details/78877466

根据自己的数据情况稍作改动。

原文还有K交叉验证的内容,自行参考。

 

  • 1
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 好的,我们需要做一些准备工作,首先我们要准备好cifar10数据集并导入相关的库。 ```python import numpy as np from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier # 导入数据 cifar10 = datasets.load_cifar10() X = cifar10.data y = cifar10.target # 将数据集为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 创建k-NN分类knn = KNeighborsClassifier(n_neighbors=5) # 训练模型 knn.fit(X_train, y_train) # 评估模型 accuracy = knn.score(X_test, y_test) print('Accuracy:', accuracy) ``` 上面的代码展示了如何使用k-NN算法进行分类的基本流程。首先,我们导入了需要使用的库,包括`numpy`和`sklearn`中的`datasets`和`model_selection`模块。然后,我们使用`load_cifar10`函数导入了cifar10数据集,并将数据和标签存储在`X`和`y`变量中。接着,我们使用`train_test_split`函数将数据集为训练集和测试集。然后,我们创建了一个k-NN分类器,并使用`fit`方法训练模型。最后,我们使用`score`方法来评估模型的准确率。 希望这个代码能帮到你! ### 回答2: CIFAR-10 数据集是一个常用的计算机视觉数据集,包含了来自10个不同类别的60000张32x32彩色图像。每个类别有6000张图像。其中50000张用于训练集,另外10000张用于测试集。 KNN(K-Nearest Neighbors)算法是一种简单而有效的分类算法。它通过计算该样本与训练集中的每个样本之间的距离,然后选取距离最近的k个训练样本中出现频率最高的类别作为预测结果。 要使用KNN算法完成对CIFAR-10数据集分类,可以按照以下步骤进行: 1. 加载数据集: 首先,需要将CIFAR-10数据集导入到代码中。可以使用现有的库(如TensorFlow)来加载和处理数据集。 2. 数据预处理: 对于KNN算法,需要将图像数据转换为一维向量。可以将每个图像的RGB通道连接在一起,并将像素值归一化到0到1之间。 3. 计算距离: 在KNN算法中,常用的距离度量方式是欧氏距离。对于测试样本,需要计算它与训练集中每个样本的距离。 4. 选择最近的k个邻居: 根据计算的距离,选择与测试样本距离最近的k个训练样本。 5. 进行分类: 统计这k个最近邻居中每个类别的出现次数,并选择出现频率最高的类别作为预测结果。 6. 评估分类性能: 使用测试集对分类器进行评估,计算准确率或其他性能指标。 需要注意的是,KNN算法在处理大规模数据集时可能会比较缓慢,尤其是当特征维度较高时。因此,在实际应用中,可能需要采用一些优化措施,如使用KD树等数据结构来加速计算。 以上是使用KNN算法完成对CIFAR-10数据集分类代码的基本思路。根据具体的编程语言和库的选择,实际的代码实现可能会有所不同。 ### 回答3: K最近邻算法(K-Nearest Neighbors,KNN)是一种常用的监督学习算法,它根据样本间的距离来进行分类。下面是使用KNN算法对CIFAR-10数据集进行分类的代码。 首先,我们需要导入所需的库和模块。我们可以使用Python的机器学习库sklearn来实现KNN算法。代码如下所示: ```python import numpy as np from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split # 载入CIFAR-10数据集 cifar = load_cifar() # 拆数据集为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(cifar.data, cifar.target, test_size=0.2, random_state=42) # 创建并训练KNN模型 k = 5 knn = KNeighborsClassifier(n_neighbors=k) knn.fit(X_train, y_train) # 在测试集上进行预测 y_pred = knn.predict(X_test) # 计算准确率 accuracy = accuracy_score(y_test, y_pred) print("准确率: ", accuracy) ``` 在代码中,我们首先导入了所需的库和模块,包括numpy、sklearn中的KNeighborsClassifier类和accuracy_score函数,以及load_cifar函数和train_test_split函数。 接下来,我们使用load_cifar函数加载CIFAR-10数据集。然后,我们使用train_test_split函数将数据集为训练集和测试集,其中测试集占总样本的20%。 然后,我们创建了一个KNN模型,其中k=5表示我们选择的邻居数。接着,我们使用fit函数对训练集进行训练。 在训练完成后,我们使用predict函数对测试集进行预测,得到预测结果y_pred。 最后,我们使用accuracy_score函数计算准确率,将预测的结果y_pred与实际标签y_test进行比较。准确率越高,说明模型的分类效果越好。 以上就是使用KNN算法对CIFAR-10数据集进行分类的代码汇总。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值