图像分类与支持向量机(SVM)

在21世纪,机器学习领域中最酷的话题之一就是图像分类。图像分类的目标是将图像正确地分类到相应的标签。可以通过卷积神经网络(CNN)来实现图像分类,而且这并不难。只需要学习一些库,比如TensorFlow、Keras和PyTorch。但在面试中,可能会面临这样的问题:如何使用支持向量机(SVM)解决图像分类问题?本文将讨论这个问题。

目录:

  • 1.SVM是什么?
  • 2. 导入必要的库
  • 3. 数据增强
  • 4. 模型创建
  • 5. 编译模型
  • 6. 将CNN转换为SVM图像分类
  • 7. 模型训练

SVM是什么? 通常,支持向量机(SVM)被认为是一种分类方法,但它也可以用于回归问题。SVM能够轻松处理多个连续和分类变量。SVM在多维空间中构建一个超平面来分隔不同的类别。SVM以迭代的方式生成最优超平面,用于最小化错误。SVM的核心思想是找到一个最大边际超平面(MMH),最佳地将数据集划分为类别。

SVM是一种非常好的分类算法。它是一种监督学习算法,主要用于将数据分类到不同的类别。SVM在一组标记数据上进行训练。SVM的主要优势在于它可以用于分类和回归问题。SVM绘制一个决策边界,这是一个超平面,用于分隔任何两个类别以对它们进行分类。SVM也用于目标检测和图像分类

在这里,将使用猫和狗的数据集来进行SVM分类。可以从这里收集数据集。这是一个二元分类问题,但支持向量机也可用于多类分类问题。

支持向量 支持向量是距离超平面最近的一组数据点。这些点通过计算边际来更好地定义分隔线。这些点对于分类器的构建更为相关。

超平面 超平面是一个决策平面,用于分隔具有不同类别成员资格的一组对象。

边际 边际是两个最近类别点之间的间隙。这被计算为从线到支持向量或最近点的垂直距离。如果类别之间的边际更大,则被认为是一个好的边际;较小的边际是一个坏的边际。

SVM如何工作? 主要目标是以最佳可能的方式分隔给定的数据集。任一最近点之间的距离被称为边际。目标是选择一个在给定数据集中具有最大可能边际的支持向量之间的超平面。SVM按照以下步骤搜索最大边际超平面:

生成以最佳方式分隔类别的超平面。左侧图显示了三个超平面:黑色、蓝色和橙色。在这里,蓝色和橙色的分类错误率更高,但黑色正确地分隔了两个类别。

从任一最近的最近数据点中选择具有最大分离度的正确超平面,如右侧图所示。

现在,让导入必要的库:

import numpy as np import pandas as pd import tensorflow as tf from tensorflow.keras.preprocessing.image import ImageDataGenerator from tensorflow.keras import Sequential from tensorflow.keras.layers import Conv2D, Dense, MaxPool2D, Flatten from tensorflow.keras.regularizers import l2

将在这里进行数据增强:

train_dir = "dataset/training_set/" test_dir = "dataset/test_set/" train_datagen = ImageDataGenerator(rescale=(1/255.), shear_range=0.2, zoom_range=0.2, horizontal_flip=True) training_set = train_datagen.flow_from_directory(directory=train_dir, target_size=(64,64), batch_size=32, class_mode="binary") test_datagen = ImageDataGenerator(rescale=(1/255.)) test_set = test_datagen.flow_from_directory(directory=test_dir, target_size=(64,64), batch_size=32, class_mode="binary")

在这里进行数据增强,以便在内存中创建额外的数据。

模型创建:

model = Sequential() model.add(Conv2D(filters=32, padding="same", activation="relu", kernel_size=3, strides=2, input_shape=(64,64,3))) model.add(MaxPool2D(pool_size=(2,2), strides=2)) model.add(Conv2D(filters=32, padding="same", activation="relu", kernel_size=3)) model.add(MaxPool2D(pool_size=(2,2), strides=2)) model.add(Flatten()) model.add(Dense(128, activation="relu")) # 输出层 model.add(Dense(1, kernel_regularizer=l2(0.01), activation="linear"))

在正常的CNN中,会在输出层写:

model.add(Dense(1, activation="sigmoid"))

但如果想将其转换为SVM,会在“kernel_regularizer”参数中使用l1或l2范数,这里使用了l2范数,并传递了“linear”作为激活函数,这正是在模型创建部分的最终输出层所做的。因为当使用支持向量机进行二元分类时,使用所谓的LinearSVM。

Linear SVM意味着将尝试在它们之间画一条线,将尝试找出其他边际线,然后将尝试划分特定的类别。对于多类分类,必须使用“softmax”作为SVM的激活函数。

编译:在编译过程中,必须使用“hinge”作为损失函数。

model.compile(optimizer='adam', loss="hinge", metrics=['accuracy'])

如果问题是一个多类分类问题,那么必须在SVM的编译过程中使用“squared_hinge”作为损失函数,并使用“softmax”作为激活函数。像这样:

model.add(Dense(number_of_classes, kernel_regularizers=l2(0.01), activation="softmax")) model.compile(optimizer="adam", loss="squared_hinge", metrics=['accuracy'])

将CNN转换为SVM图像分类器需要做什么?所以,要使用SVM进行图像分类,需要进行2个更改:

  • i. 对于二元分类应用损失函数“hinge”和多类分类应用“squared_hinge”。
  • ii. 在最终输出层应用正则化器,并对于二元分类应用激活函数“linear”和多类分类应用“softmax”。

现在,让训练模型:

history = model.fit(x=training_set, validation_data=test_set, epochs=15)
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485