基于SVM的图像二分类算法
本实验是用的python代码实现图像的二分类问题,我是在eclipse中搭建python环境。
一、数据集处理
我采用的是甜椒叶数据集(我忘了下载地址在哪里,我只用了一部分数据集),其中健康叶片有375张,病害叶片有313张,分别存放于两个文件夹中。如下图所示:
由于代码的原因,需要将文件夹的名称改为0和1,同时之后的处理会更加方便。0表示健康叶片,1表示病害叶片。
二、图片预处理
1、首先需要读入训练数据,同时重置图片大小,代码如下:
X = []
Y = []for i in range(0, 2):#遍历文件夹,读取图片for f in os.listdir("G:/Download_Data_bishe/leaf_data/pepper_bellSmall/%s" % i):#打开一张图片并灰度化Images = cv2.imread("G:/Download_Data_bishe/leaf_data/pepper_bellSmall/%s/%s" % (i, f)) image=cv2.resize(Images,(256,256),interpolation=cv2.INTER_CUBIC)hist = cv2.calcHist([image], [0,1], None, [256,256], [0.0,255.0,0.0,255.0]) X.append(((hist/255).flatten()))Y.append(i)
X = np.array(X)
Y = np.array(Y)
2、调用自动调参函数GridSearchCV(网格搜索)对SVC()中的几个重要参数进行调参,注意,GridSearchCV函数要求的数据集很小,否则调参时间会很长,甚至调不出来,具体代码如下:
#自动调参函数
tuned_parameters = [{'kernel': ['rbf'], 'gamma': [1e-3, 1e-4],'C': [1, 10, 100, 1000]},{'kernel': ['linear'], 'C': [1, 10, 100, 1000]}]
scores = ['precision', 'recall']
for score in scores:print("# Tuning hyper-parameters for %s" % score)print()# 调用 GridSearchCV,将 SVC(), tuned_parameters, cv=5, 还有 scoring 传递进去,clf = ms.GridSearchCV(svm.SVC(), tuned_parameters, cv=10,scoring='%s_macro' % score) #cv为迭代次数。#基于交叉验证的网格搜索,cv:确定交叉验证拆分策略。# 用训练集训练这个学习器 clfclf.fit(X_train, y_train)print("Best parameters set found on development set:")print()# 再调用 clf.best_params_ 就能直接得到最好的参数搭配结果print(clf.best_params_)print()print("Grid scores on development set:")print()means = clf.cv_results_['mean_test_score']stds = clf.cv_results_['std_test_score']# 看一下具体的参数间不同数值的组合后得到的分数是多少for mean, std, params in zip(means, stds, clf.cv_results_['params']):print("%0.3f (+/-%0.03f) for %r"% (mean, std * 2, params))print()print("Detailed classification report:")print()print("The model is trained on the full development set.")print("The scores are computed on the full evaluation set.")print()y_true, y_pred = y_test, clf.predict(X_test)# 打印在测试集上的预测结果与真实值的分数print(classification_report(y_true, y_pred))print()
以上代码可以得出最优的参数组合,
3、训练模型
我用的是sklearn包中封装好的SVC()算法,利用了10折交叉检验和ROC曲线来评价模型,代码如下:
#交叉验证+roc曲线
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import StratifiedKFold#交叉验证
cv = StratifiedKFold(n_splits=10) #导入该模型,后面将数据划分6份
classifier = svm.SVC(kernel='rbf',gamma=0.0001,C=1000, probability=True,random_state=0) # SVC模型 可以换作AdaBoost模型试试# 画平均ROC曲线的两个参数
mean_tpr = 0.0 # 用来记录画平均ROC曲线的信息
mean_fpr = np.linspace(0, 1, 100)
cnt = 0
for i, (train, test) in enumerate(cv.split(X,Y)): #利用模型划分数据集和目标变量 为一一对应的下标cnt +=1probas_ = classifier.fit(X[train], Y[train]).predict_proba(X[test]) # 训练模型后预测每条样本得到两种结果的概率fpr, tpr, thresholds = roc_curve(Y[test], probas_[:, 1]) # 该函数得到伪正例、真正例、阈值,这里只使用前两个mean_tpr += np.interp(mean_fpr, fpr, tpr) # 插值函数 interp(x坐标,每次x增加距离,y坐标) 累计每次循环的总值后面求平均值mean_tpr[0] = 0.0 # 将第一个真正例=0 以0为起点roc_auc = auc(fpr, tpr) # 求auc面积plt.plot(fpr, tpr, lw=1, label='ROC fold {0:.2f} (area = {1:.2f})'.format(i, roc_auc)) # 画出当前分割数据的ROC曲线plt.plot([0, 1], [0, 1], '--', color=(0.6, 0.6, 0.6), label='Luck') # 画对角线mean_tpr /= cnt # 求数组的平均值
mean_tpr[-1] = 1.0 # 坐标最后一个点为(1,1) 以1为终点
mean_auc = auc(mean_fpr, mean_tpr)plt.plot(mean_fpr, mean_tpr, 'k--',label='Mean ROC (area = {0:.2f})'.format(mean_auc), lw=2)plt.xlim([-0.05, 1.05]) # 设置x、y轴的上下限,设置宽一点,以免和边缘重合,可以更好的观察图像的整体
plt.ylim([-0.05, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate') # 可以使用中文,但需要导入一些库即字体
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()
4、模型保存
如果想要将训练好的模型保存下来,可以用以下代码:
#保存模型
from sklearn.externals import joblib
os.chdir("G:/Download_Data_bishe/save_model")
joblib.dump(classifier,"train_model.m")
其实我还是很疑惑10折交叉检验到底是用来评价模型的还是用来选择最优模型的???
最后,放一张结果图
SVM的识别效果还是可以的,不过也可能我的数据集不大的原因。
三、完整代码如下:
#SVM算法import datetime
starttime = datetime.datetime.now()import numpy as np
import os
import cv2
import sklearn.model_selection as ms
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, classification_reportX = []
Y = []for i in range(0, 2):#遍历文件夹,读取图片for f in os.listdir("G:/Download_Data_bishe/leaf_data/pepper_bellSmall/%s" % i):#打开一张图片并灰度化Images = cv2.imread("G:/Download_Data_bishe/leaf_data/pepper_bellSmall/%s/%s" % (i, f)) image=cv2.resize(Images,(256,256),interpolation=cv2.INTER_CUBIC)hist = cv2.calcHist([image], [0,1], None, [256,256], [0.0,255.0,0.0,255.0]) X.append(((hist/255).flatten()))Y.append(i)
X = np.array(X)
Y = np.array(Y)#切分训练集和测试集
#X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=1)
#随机率为100%选取其中的30%作为测试集#交叉验证+roc曲线
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import StratifiedKFold#交叉验证
cv = StratifiedKFold(n_splits=10) #导入该模型,后面将数据划分6份
classifier = svm.SVC(kernel='rbf',gamma=0.0001,C=1000, probability=True,random_state=0) # SVC模型 可以换作AdaBoost模型试试# 画平均ROC曲线的两个参数
mean_tpr = 0.0 # 用来记录画平均ROC曲线的信息
mean_fpr = np.linspace(0, 1, 100)
cnt = 0
for i, (train, test) in enumerate(cv.split(X,Y)): #利用模型划分数据集和目标变量 为一一对应的下标cnt +=1probas_ = classifier.fit(X[train], Y[train]).predict_proba(X[test]) # 训练模型后预测每条样本得到两种结果的概率fpr, tpr, thresholds = roc_curve(Y[test], probas_[:, 1]) # 该函数得到伪正例、真正例、阈值,这里只使用前两个mean_tpr += np.interp(mean_fpr, fpr, tpr) # 插值函数 interp(x坐标,每次x增加距离,y坐标) 累计每次循环的总值后面求平均值mean_tpr[0] = 0.0 # 将第一个真正例=0 以0为起点roc_auc = auc(fpr, tpr) # 求auc面积plt.plot(fpr, tpr, lw=1, label='ROC fold {0:.2f} (area = {1:.2f})'.format(i, roc_auc)) # 画出当前分割数据的ROC曲线plt.plot([0, 1], [0, 1], '--', color=(0.6, 0.6, 0.6), label='Luck') # 画对角线mean_tpr /= cnt # 求数组的平均值
mean_tpr[-1] = 1.0 # 坐标最后一个点为(1,1) 以1为终点
mean_auc = auc(mean_fpr, mean_tpr)plt.plot(mean_fpr, mean_tpr, 'k--',label='Mean ROC (area = {0:.2f})'.format(mean_auc), lw=2)plt.xlim([-0.05, 1.05]) # 设置x、y轴的上下限,设置宽一点,以免和边缘重合,可以更好的观察图像的整体
plt.ylim([-0.05, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate') # 可以使用中文,但需要导入一些库即字体
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()#保存模型
from sklearn.externals import joblib
os.chdir("G:/Download_Data_bishe/save_model")
joblib.dump(classifier,"train_model.m")# #只有交叉验证
# clf = SVC(kernel='rbf',gamma=0.001,C=100)
# scores = cross_val_score(clf, X , Y , cv=5) #cv为迭代次数。
# print(scores) # 打印输出每次迭代的度量值(准确度)
# print(scores.mean())
# print()#普通的一次性模型训练预测
#clf = SVC(kernel='rbf',gamma=0.001,C=100)
# clf.fit(X_train, y_train)#训练
# predictions0 = clf.predict(X_test)
# #predictions0=pred_test_y
# print(confusion_matrix(y_test, predictions0))
# print (classification_report(y_test, predictions0))
# endtime = datetime.datetime.now()
# print (endtime - starttime)# #自动调参函数
# tuned_parameters = [{'kernel': ['rbf'], 'gamma': [1e-3, 1e-4],
# 'C': [1, 10, 100, 1000]},
# {'kernel': ['linear'], 'C': [1, 10, 100, 1000]}]
# scores = ['precision', 'recall']
# for score in scores:
# print("# Tuning hyper-parameters for %s" % score)
# print()
#
# # 调用 GridSearchCV,将 SVC(), tuned_parameters, cv=5, 还有 scoring 传递进去,
# clf = ms.GridSearchCV(svm.SVC(), tuned_parameters, cv=10,
# scoring='%s_macro' % score) #cv为迭代次数。#基于交叉验证的网格搜索,cv:确定交叉验证拆分策略。
# # 用训练集训练这个学习器 clf
# clf.fit(X_train, y_train)
#
# print("Best parameters set found on development set:")
# print()
#
# # 再调用 clf.best_params_ 就能直接得到最好的参数搭配结果
# print(clf.best_params_)
#
# print()
# print("Grid scores on development set:")
# print()
# means = clf.cv_results_['mean_test_score']
# stds = clf.cv_results_['std_test_score']
#
# # 看一下具体的参数间不同数值的组合后得到的分数是多少
# for mean, std, params in zip(means, stds, clf.cv_results_['params']):
# print("%0.3f (+/-%0.03f) for %r"
# % (mean, std * 2, params))
#
# print()
#
# print("Detailed classification report:")
# print()
# print("The model is trained on the full development set.")
# print("The scores are computed on the full evaluation set.")
# print()
# y_true, y_pred = y_test, clf.predict(X_test)
#
# # 打印在测试集上的预测结果与真实值的分数
# print(classification_report(y_true, y_pred))
#
# print()
基于SVM的图像二分类算法相关推荐
- 基于cnn的图像二分类算法(一)
本算法是基于tensorflow,使用python语言进行的一种图像分类算法,参考于谷歌的mnist手写识别,包括以下几个模块:图像读取,图像处理,图像增强.卷积神经网络部分包括:卷积层1,汇合层1( ...
- matlab图像分类器,Matlab 基于svm的图像物体分类
Matlab 基于svm的图像物体分类 发布时间:2018-05-16 20:27, 浏览次数:1623 , 标签: Matlab svm 本周工作日志,老师布置了一个小作业,让我们使用matlab实 ...
- Matlab 基于svm的图像物体分类
matlab 图像分类 本周工作日志,老师布置了一个小作业,让我们使用matlab实现图像物体分类 目录 文章目录 matlab 图像分类 目录 1分类原理 2程序流程 补充 1分类原理 基于一个很朴 ...
- 基于CNN的海面舰船图像二分类
基于CNN的海面舰船图像二分类 1. 模型依赖的环境和硬件配置 Python3.8 Pillow==8.2.0 torch-1.5.1(cuda9.2) torchfile==0.1.0 torchv ...
- 基于deap脑电数据集的脑电情绪识别二分类算法(附代码)
想尝试一下脑电情绪识别的各个二分类算法. 代码主要分为三部分:快速傅里叶变换处理(fft).数据预处理.以及各个模型处理. 采用的模型包括:决策树.SVM.KNN三个模型(模型采用的比较简单,可以直接 ...
- 基于机器学习的车牌识别系统(Python实现基于SVM支持向量机的车牌分类)
基于机器学习的车牌识别系统(Python实现基于SVM支持向量机的车牌分类) 一.数据集说明 训练样本来自于github上的EasyPR的c++版本,包含一万三千多张数字及大写字母的图片以及三千多张中 ...
- 支持向量机的近邻理解:图像二分类为例(1)
前言: 机器学习在是否保留原始样本的层面划分为两类:参数学习和非参数学习.参数学习使用相对固定框架,把样本分布通过训练的方式回归到一个使用参数描述的数学模型里面,最终使用的是归纳方法:非参数模型保留了 ...
- 【Basic】SVM(支持向量机)分类算法
支持向量机(Support Vector Machine,SVM)算法兼具形式优美和高效好用,难得地受到了跨学术界和工业界的好评. 一.SVM 算法介绍 在支持向量机中有三个重要概念,也是组成支持向量 ...
- 基于SVM的乳腺癌数据集分类
目录 1.作者介绍 2.SVM算法介绍 2.1 SVM算法 2.2 SVM算法理解与分析 3.乳腺癌数据集介绍 4.基于SVM的乳腺癌数据集分类实验 4.1 导入所需要的包 4.2 导入乳腺癌数据集 ...
最新文章
- 7-2 然后是几点 (C语言)
- 腾讯首次发布 AI 白皮书讲了什么?
- Java集合的使用:List与Map
- unity update 协程_Unity协程,停止协程及yield return使用_019
- [android] 百度地图开发 (二).定位城市位置和城市POI搜索
- java锁方法和锁代码块_java的同步方法和同步代码块,对象锁,类锁区别
- 虚拟搭建局域网模拟器_巧用虚拟局域网,快速搭建私有云,一步就能搞定
- bettertouchtool闪退_BetterTouchTool for Mac 3.238 无闪退 触控板增强工具
- 北京师大网络教育计算机离线作一,2015北师大网络教育《计算机应用基础》离线作业2精选.doc...
- [云计算] 001.云计算简介
- python 对 list[list] 矩阵进行逆时针旋转90度 matrix = list(map(list, zip(*matrix)))[::-1]
- Nginx(1)— Nginx工作原理
- 微信公众号运营都有哪些渠道,来提升公众号的粉丝量
- 杭电ACM-LCY算法进阶培训班-专题训练(Hash及其应用)
- 下载python开发环境
- 英特尔cpu发布时间表_英特尔延长CPU发布周期:摩尔定律终结
- 西南民族大学第十届校赛 题解
- OpenCV之findContours获取轮廓(Python版)
- 历史库存sap_SAP 常用的库存表
- qdialog 圆角_QT 使用QSS实现圆角对话框