• KNN 和 SVM 图片分类 任务 代码及细节分享


    使用KNN (K-最近邻) 方法进行图像分类也是一个常见的选择。以下是

    使用sklearnKNeighborsClassifier进行图像分类的Python脚本:

    1. import os
    2. import cv2
    3. import numpy as np
    4. import logging
    5. from sklearn.neighbors import KNeighborsClassifier
    6. from sklearn.metrics import accuracy_score, confusion_matrix
    7. # 设置日志
    8. logging.basicConfig(filename='training_log.txt', level=logging.INFO, format='%(asctime)s - %(message)s')
    9. # 读取图像数据和标签
    10. def load_images_from_folder(folder):
    11. images = []
    12. labels = []
    13. label = 0
    14. for subdir in os.listdir(folder):
    15. subpath = os.path.join(folder, subdir)
    16. if os.path.isdir(subpath):
    17. for filename in os.listdir(subpath):
    18. if filename.endswith(".jpg"):
    19. img_path = os.path.join(subpath, filename)
    20. img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    21. img_normalized = cv2.resize(img, (256, 256)) # 归一化图像大小为256x256
    22. images.append(img_normalized.flatten())
    23. labels.append(label)
    24. label += 1
    25. return images, labels
    26. # 主函数
    27. def main():
    28. # train_folder = "YOUR_TRAIN_DATASET_FOLDER_PATH" # 替换为你的训练集文件夹路径
    29. # test_folder = "YOUR_TEST_DATASET_FOLDER_PATH" # 替换为你的测试集文件夹路径
    30. logging.info("Loading training data from %s", train_folder)
    31. X_train, y_train = load_images_from_folder(train_folder)
    32. logging.info("Loaded %d training samples", len(X_train))
    33. logging.info("Loading test data from %s", test_folder)
    34. X_test, y_test = load_images_from_folder(test_folder)
    35. logging.info("Loaded %d test samples", len(X_test))
    36. logging.info("Training KNeighborsClassifier...")
    37. knn = KNeighborsClassifier(n_neighbors=3) # 使用3个邻居
    38. knn.fit(X_train, y_train)
    39. logging.info("Training completed.")
    40. y_pred = knn.predict(X_test)
    41. accuracy = accuracy_score(y_test, y_pred)
    42. logging.info("Test Accuracy: %f", accuracy)
    43. cm = confusion_matrix(y_test, y_pred)
    44. cm_normalized = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
    45. logging.info("Normalized Confusion Matrix:")
    46. for row in cm_normalized:
    47. logging.info(" - ".join(map(lambda x: "{:.2f}".format(x), row)))
    48. if __name__ == "__main__":
    49. main()

    KNeighborsClassifier来进行训练和预测。默认情况下,我设置了n_neighbors=3,这意味着使用3个最近的邻居进行投票。你可以根据需要调整这个参数。

    选择合适的n_neighbors值是很重要的。一个较小的值(如1或3)可能会使模型对噪声更敏感,而一个较大的值可能会使模型更加平滑。通常,选择一个奇数的值可以避免在投票中出现平局的情况。

    为了确定最佳的n_neighbors值,你可以使用交叉验证来评估不同值的性能,然后选择性能最好的那个值。

    对于多类分类问题,选择合适的n_neighbors值是很重要的。以下是一些建议:

    1. 避免平局:为了避免在投票中出现平局的情况,通常建议选择一个奇数的n_neighbors值。但是,由于你有21个类,这个规则不再适用,因为即使是偶数的邻居数也不太可能导致平局。

    2. 默认值KNeighborsClassifier的默认n_neighbors值是5。这是一个常用的起始值,但可能不是最优的。

    3. 根据类别数量:一个常见的策略是选择一个接近总类别数量的n_neighbors值。在你的情况下,你有21个类,所以你可以考虑从这个数字开始,然后向上或向下调整。

    4. 交叉验证:最佳的方法是使用交叉验证来确定最佳的n_neighbors值。这意味着你会尝试多个不同的n_neighbors值,然后选择在验证集上性能最好的那个。

    使用支持向量机(SVM)进行图像分类是一个强大的方法。sklearn提供了SVC(支持向量分类)类来实现SVM。

    以下是使用sklearnSVC进行图像分类的Python脚本:

    1. import os
    2. import cv2
    3. import numpy as np
    4. import logging
    5. from sklearn.svm import SVC
    6. from sklearn.metrics import accuracy_score, confusion_matrix
    7. # 设置日志
    8. logging.basicConfig(filename='training_log_svm.txt', level=logging.INFO, format='%(asctime)s - %(message)s')
    9. # 读取图像数据和标签
    10. def load_images_from_folder(folder):
    11. images = []
    12. labels = []
    13. label = 0
    14. for subdir in os.listdir(folder):
    15. subpath = os.path.join(folder, subdir)
    16. if os.path.isdir(subpath):
    17. for filename in os.listdir(subpath):
    18. if filename.endswith(".jpg"):
    19. img_path = os.path.join(subpath, filename)
    20. img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    21. img_normalized = cv2.resize(img, (256, 256)) # 归一化图像大小为256x256
    22. images.append(img_normalized.flatten())
    23. labels.append(label)
    24. label += 1
    25. return images, labels
    26. # 主函数
    27. def main():
    28. # train_folder = "YOUR_TRAIN_DATASET_FOLDER_PATH" # 替换为你的训练集文件夹路径
    29. # test_folder = "YOUR_TEST_DATASET_FOLDER_PATH" # 替换为你的测试集文件夹路径
    30. logging.info("Loading training data from %s", train_folder)
    31. X_train, y_train = load_images_from_folder(train_folder)
    32. logging.info("Loaded %d training samples", len(X_train))
    33. logging.info("Loading test data from %s", test_folder)
    34. X_test, y_test = load_images_from_folder(test_folder)
    35. logging.info("Loaded %d test samples", len(X_test))
    36. logging.info("Training SVM...")
    37. svm = SVC(kernel='linear', C=1) # 使用线性核和C=1
    38. svm.fit(X_train, y_train)
    39. logging.info("Training completed.")
    40. y_pred = svm.predict(X_test)
    41. accuracy = accuracy_score(y_test, y_pred)
    42. logging.info("Test Accuracy: %f", accuracy)
    43. cm = confusion_matrix(y_test, y_pred)
    44. cm_normalized = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
    45. logging.info("Normalized Confusion Matrix:")
    46. for row in cm_normalized:
    47. logging.info(" - ".join(map(lambda x: "{:.2f}".format(x), row)))
    48. if __name__ == "__main__":
    49. main()

    使用了SVC类来进行训练和预测。我选择了线性核(kernel='linear')和正则化参数C=1(C=1)。这些参数可能需要根据你的数据进行调整。

    SVM有许多可调参数,如核函数、C值和其他参数。

    科学地调整SVM的参数:

    1. 交叉验证:使用交叉验证是评估不同参数组合性能的关键。例如,你可以使用sklearnGridSearchCV来自动进行参数搜索和交叉验证。

    2. 核函数选择

      • 线性核:当特征数量很大或数据线性可分时使用。
      • RBF核:当数据有非线性边界时使用。它有一个参数gamma需要调整。
      • 多项式核:当数据的边界是多项式形式时使用。它有degreecoef0两个参数需要调整。
      • Sigmoid核:在某些特定的数据集上可能有效,但不常用。
    3. C值:C是SVM的正则化参数。较小的C值会导致较大的间隔,但可能允许一些误分类。较大的C值会尝试最大化训练数据的正确分类,但可能导致过拟合。

    4. gamma值:仅对RBF核和多项式核有效。它定义了单个训练样本的影响范围。较小的值意味着更大的影响范围,较大的值意味着更小的影响范围。

    5. 使用GridSearchCV:这是一个自动化的参数搜索方法,它会尝试所有给定的参数组合,并使用交叉验证来评估每种组合的性能。

    1. from sklearn.model_selection import GridSearchCV
    2. from sklearn.svm import SVC
    3. # 定义参数网格
    4. param_grid = {
    5. 'C': [0.1, 1, 10, 100],
    6. 'gamma': [1, 0.1, 0.01, 0.001],
    7. 'kernel': ['linear', 'rbf', 'poly', 'sigmoid']
    8. }
    9. # 使用GridSearchCV进行参数搜索
    10. grid_search = GridSearchCV(SVC(), param_grid, refit=True, verbose=3, cv=5)
    11. grid_search.fit(X_train, y_train)
    12. # 打印最佳参数
    13. print("Best parameters found: ", grid_search.best_params_)
    1. 考虑数据的规模和分布:如果数据集很大,可能需要使用随机样本或考虑使用LinearSVC,它是专门为大数据集优化的。

    2. 特征缩放:确保所有特征都在相同的尺度上。SVM对特征的尺度非常敏感,所以通常使用StandardScaler来缩放数据。

    3. 评估指标:确保你使用了合适的评估指标来评估模型的性能。例如,对于不平衡的数据集,考虑使用F1分数或AUC-ROC曲线,而不仅仅是准确性。

  • 相关阅读:
    大数据毕业设计选题推荐-污水处理大数据平台-Hadoop-Spark-Hive
    7个新的ES2022 JavaScript 功能,你千万不要错过了
    【SpringCloud微服务】- Eureka服务注册与服务发现Discovery
    软件测试知识储备:关于「登录安全」的基础知识,你了解多少?
    【GD32F310开发板试用】Keil编程环境配置、避坑
    Windows与网络基础-25-二进制基础
    【JS】【掘金】获取关注了里不在关注者里的人
    jQuery源码
    Java开发实习面试总结(49分钟)
    JAVA程序员和C程序员的差距在哪里?
  • 原文地址:https://blog.csdn.net/qq_68308828/article/details/134004654