支持向量机与逻辑回归的区别及 SVM 在图像分类中的应用

支持向量机与逻辑回归的区别及 SVM 在图像分类中的应用

在机器学习的多元算法领域中,支持向量机(SVM)和逻辑回归(LR)作为两种经典的监督学习算法,被广泛应用于各类分类任务。尽管它们有着相似的目标,但在原理、特性和应用场景上存在显著差异。同时,SVM 在图像分类领域也展现出强大的能力,接下来我们将深入探讨这些内容。

一、SVM 算法的优缺点

SVM 算法凭借其严格的数学理论基础,在集成学习和神经网络尚未崭露头角之前,长期占据分类模型的主导地位。即便在大数据时代,虽然面对大样本数据时,SVM 因计算量巨大导致热度有所减退,但它依然是机器学习领域中不可或缺的常用算法。

SVM 算法具有诸多显著优点。其一,在处理高维特征的分类和回归问题时表现卓越,当特征维度大于样本数量时,依然能够保持良好的效果;其二,SVM 在决策过程中仅依赖部分支持向量来确定超平面,无需利用全部数据,这大大降低了计算复杂度;其三,丰富多样的核函数为 SVM 提供了强大的灵活性,使其能够有效解决各类非线性分类和回归问题;其四,在样本量适中的情况下,SVM 模型具有较高的分类准确率和出色的泛化能力。

然而,SVM 算法也存在一些局限性。当特征维度远大于样本数量时,SVM 的性能表现一般;在处理海量样本数据,且核函数映射维度极高的场景下,计算量会急剧增加,导致算法效率低下,不适用于此类场景;此外,在处理非线性问题时,由于缺乏通用的选择标准,选择合适的核函数成为一项具有挑战性的任务;SVM 对缺失数据较为敏感,并且超参数 C 和 gamma 的值需要通过交叉验证仔细调整,这增加了模型调优的难度。

二、SVM 与 LR 的联系与区别

线性回归主要用于预测连续型变量,属于回归模型;而逻辑回归和 SVM 则专注于分类任务,属于分类模型。从模型性质来看,线性回归和逻辑回归属于线性模型,SVM 根据所选用的核函数不同,既可以是线性模型,也可以是非线性模型。值得一提的是,这三种算法均属于有监督学习算法。

在数据敏感性方面,SVM 只关注位于分界面上的支持向量,因此不受数据整体分布的影响,但对异常值较为敏感;而逻辑回归受数据分布的影响较大,在处理数据集不均衡问题时需要特殊处理,不过相对而言不易受异常值干扰 。

在损失函数和决策机制上,LR 采用交叉熵(cross entropy)作为损失函数,通过 sigmoid 函数计算样本属于某一类别的概率,并利用极大似然估计方法来确定参数值;SVM 则基于间隔最大化原理,以最大化几何间隔的分类面作为最优分类面,其损失函数旨在最大化间隔距离。

从输出结果来看,LR 的输出直接表示样本属于某一类别的概率;而 SVM 不能直接输出概率,而是直接给出样本的类别。

在计算效率上,SVM 的核函数特性使其在分类时仅需计算与少数支持向量的距离,尤其是在使用复杂核函数时,能够显著简化模型和计算过程;相比之下,LR 需要对所有样本点进行计算,在处理大规模数据时计算量巨大。

在实际应用中,对于小规模数据集,SVM 通常能够取得比 LR 更好的效果;但在大数据场景下,由于 SVM 的计算复杂度较高,而 LR 训练过程简单,且支持在线训练,因此 LR 在大数据分类任务中更为常用。

三、SVM 在图像分类中的应用

(一)SVM 图像分类概述

SVM 作为一种强大的监督学习算法,在图像分类、文本分类和数据挖掘等众多领域都有着广泛的应用。在图像分类任务中,使用 SVM 作为分类器,首先需要收集并准备图像数据集,将每幅图像转换为特征向量。常用的特征提取方法包括 HOG(方向梯度直方图)和 CNN(卷积神经网络)等。提取到的特征作为输入用于训练 SVM 模型,随后使用测试数据集对模型性能进行评估,常见的评估指标有准确度、精确度、召回率和 F1 分数等。此外,通过调整超参数(如正则化参数 C、核函数参数等),可以进一步优化模型性能。SVM 图像分类技术已成功应用于人脸识别、物体检测、手写数字识别、医学图像分析等多个领域。

(二)图像数据读取

在某图像分类项目中,提供了包含 10 类图像的数据集,分别为 'beach'(海滩)、'build'(建筑)、'bus'(公交车)、'dinosaur'(恐龙)、'elephant'(大象)、'food'(食物)、'horse'(马)、'mountain'(山脉)、'people'(人)、'rose'(玫瑰) ,每类图像包含 100 张。首先,需要获取每个图片文件的名称作为对应的图像分类标签。通过导入相关 Python 包,使用以下代码获取文件夹名称:

 

import os

import cv2

import numpy as np

from sklearn.model_selection import train_test_split

from sklearn.metrics import confusion_matrix, classification_report

from sklearn.svm import SVC

import matplotlib.pyplot as plt

import matplotlib as mpl

import glob

mpl.rcParams['font.sans-serif'] = ['KaiTi']

mpl.rcParams['font.serif'] = ['KaiTi']

class_names = [name[9:] for name in glob.glob('./photo2/*')]

print(class_names)

运行上述代码后,可输出每个文件夹的名字。接着,通过遍历文件夹,获取每张图片的路径以及对应的分类标签:

 

X = []

Y = []

Z = []

for i in range(0, 10):

for f in os.listdir("photo2/%s" % class_names[i]):

X.append("photo2//" + class_names[i] + "//" + str(f))

Y.append(i)

运行完成后,X 保存了图片的路径信息,Y 保存了对应图片的标签值。最后,使用train_test_split函数将数据集拆分为训练集和测试集:

 

X = np.array(X)

Y = np.array(Y)

X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=1)

print(len(X_train), len(X_test), len(y_train), len(y_test))

(三)生成图像的直方图

图像直方图是一种用于展示图像数据分布情况的二维统计图表,横坐标表示图像中各个像素点的灰度级,纵坐标表示具有该灰度级的像素个数,它能够直观地反映图像中亮度的分布情况。通过观察直方图,可以了解图像的亮度特征,为后续的图像处理和分析提供依据。

使用 OpenCV 库可以方便地绘制图像直方图,以绘制一张海滩图片的直方图为例:

 

import cv2

import matplotlib.pyplot as plt

img = cv2.imread('photo2//beach//126.jpg')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

b,g,r = cv2.split(img)

img2 = cv2.merge([r,g,b])

fig = plt.figure(figsize=(15,8))

fig1=plt.subplot(121)

hist = cv2.calcHist([img], [0], None, [256], [0, 256])

plt.plot(hist)

fig2=plt.subplot(122)

plt.imshow(img2)

plt.show()

运行上述代码后,将输出图像的直方图和原始图像。为了将图像特征用于 SVM 模型训练,需要遍历训练集和测试集文件夹,获取每类图像的直方图,并进行标准化操作:

 

# 训练集

XX_train = []

for i in X_train:

image = cv2.imdecode(np.fromfile(i, dtype=np.uint8), cv2.IMREAD_COLOR)

img = cv2.resize(image, (256, 256), interpolation=cv2.INTER_CUBIC)

hist = cv2.calcHist([img], [0, 1], None, [256, 256], [0.0, 255.0, 0.0, 255.0])

XX_train.append(((hist / 255).flatten()))

# 测试集

XX_test = []

for i in X_test:

image = cv2.imdecode(np.fromfile(i, dtype=np.uint8), cv2.IMREAD_COLOR)

img = cv2.resize(image, (256, 256), interpolation=cv2.INTER_CUBIC)

hist = cv2.calcHist([img], [0, 1], None, [256, 256], [0.0, 255.0, 0.0, 255.0])

XX_test.append(((hist / 255).flatten()))

(四)SVM 图像分类模型搭建与训练

为了找到最优的 SVM 模型参数,使用GridSearchCV进行网格搜索:

 

from sklearn.model_selection import GridSearchCV

param_test1 = {'C': np.arange(0.01, 1.0001, 0.01)}

gsearch1 = GridSearchCV(estimator = SVC(kernel='linear',class_weight='balanced',probability=True),

param_grid = param_test1, scoring ="accuracy",cv=5,n_jobs=5,verbose=2)

gsearch1.fit(XX_train, y_train)

print(gsearch1.best_params_)

print(gsearch1.best_score_)

print(gsearch1.best_estimator_)

上述代码设置了 SVM 模型惩罚系数 C 的搜索范围为 0.01 - 1,步长为 0.01,并指定使用线性核函数。搜索完成后,使用最优参数构建 SVM 模型并进行训练:

 

from sklearn.metrics import roc_auc_score,roc_curve,auc,accuracy_score,classification_report,confusion_matrix,f1_score

import sklearn

svm_t = sklearn.svm.SVC(C=0.38, break_ties=False, cache_size=200,

class_weight='balanced', coef0=0.0, decision_function_shape='ovr', degree=3,

gamma='scale', kernel='linear', max_iter=-1, probability=True,

random_state=None, shrinking=True, tol=0.001, verbose=False)

svm_t.fit(XX_train, y_train)

predict_t=svm_t.predict(XX_test)

print('准确率是:%s'%(accuracy_score(y_test,predict_t)))

print(classification_report(y_test,predict_t))

print(confusion_matrix(y_test,predict_t))

通过accuracy_score计算模型准确率,使用confusion_matrix计算多分类的混淆矩阵,并输出包括召回率(recall)、F1 值等评估指标。

(五)调用模型识别图片

模型训练完成后,使用joblib库将模型保存到文件:

 

import joblib

model_filename ='svm_model.pkl'

joblib.dump(svm_t, model_filename)

保存后,可使用以下代码加载模型:

 

loaded_model = joblib.load(model_filename)

为了验证模型的实际效果,从网上下载 9 张照片作为验证集。首先获取验证集图片路径,读取图片并提取直方图数据,进行归一化处理后添加到验证集数据中:

 

X_pre=[]

name=[]

k = 0

while k < 9:

name1="./test/"+str(k)+".jpg"

image = cv2.imdecode(np.fromfile(name1, dtype=np.uint8), cv2.IMREAD_COLOR)

img = cv2.resize(image, (256, 256),interpolation=cv2.INTER_CUBIC)

hist = cv2.calcHist([img], [0, 1], None,[256, 256], [0.0, 255.0, 0.0, 255.0])

X_pre.append(((hist / 255).flatten()))

name.append(name1)

k=k+1

将验证集数据转换为np.array格式后,输入到加载的模型中进行预测:

 

X_pre=np.array(X_pre)

y=loaded_model.predict(X_pre)

最后,通过定义函数将验证集图片可视化输出,并显示预测结果:

 

import cv2

import matplotlib.pyplot as plt

def readImage(path):

img = cv2.imread(path)

b,g,r = cv2.split(img)

img2 = cv2.merge([r,g,b])

return img2

plt.figure(figsize=(10,10))

for i in range(3):

plt.subplot(3,3,i*3+1),plt.imshow(readImage(name[i*3+0]))

plt.title(class_names[y[i*3]]),plt.xticks([]), plt.yticks([])

plt.subplot(3,3,i*3+2),plt.imshow(readImage(name[i*3+1]))

plt.title(class_names[y[i*3+1]]),plt.xticks([]), plt.yticks([])

plt.subplot(3,3,i*3+3),plt.imshow(readImage(name[i*3+2]))

plt.title(class_names[y[i*3+2]]),plt.xticks([]), plt.yticks([])

plt.show()

综上所述,SVM 和逻辑回归在机器学习中各有优劣,适用于不同的应用场景。同时,SVM 在图像分类领域通过一系列严谨的数据处理和模型训练过程,展现出强大的分类能力,为图像识别技术的发展提供了重要支持。在实际应用中,我们需要根据具体问题和数据特点,合理选择算法和模型,以达到最佳的处理效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万能小贤哥

感谢大捞

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值