本文共享自华为云社区《[Python图画处理] 二十六.图画分类原理及依据KNN、朴素贝叶斯算法的图画分类事例丨【百变AI秀】》,作者:eastmount 。

一.图画分类

图画分类(Image Classification)是对图画内容进行分类的问题,它运用核算机对图画进行定量剖析,把图画或图画中的区域区分为若干个类别,以代替人的视觉判别。图画分类的传统办法是特征描述及检测,这类传统办法或许关于一些简单的图画分类是有用的,但由于实践状况十分杂乱,传统的分类办法不堪重负。现在,广泛运用机器学习和深度学习的办法来处理图画分类问题,其首要任务是给定一堆输入图片,将其指派到一个已知的混合类别中的某个标签。

鄙人图中,图画分类模型将获取单个图画,并将为4个标签{cat,dog,hat,mug},别离对应概率{0.6, 0.3, 0.05, 0.05},其间0.6表明图画标签为猫的概率,其他类比。该图画被表明为一个三维数组。在这个比方中,猫的图画宽度为248像素,高度为400像素,并具有红绿蓝三个颜色通道(通常称为RGB)。因而,图画由2484003个数字组成或总共297600个数字,每个数字是一个从0(黑色)到255(白色)的整数。图画分类的任务是将这挨近30万个数字变成一个单一的标签,如“猫(cat)”。

跟我学Python图像处理丨图像分类原理与案例

那么,如何编写一个图画分类的算法呢?又怎样从众多图画中识别出猫呢?这里所采纳的办法和教育小孩看图识物类似,给出许多图画数据,让模型不断去学习每个类的特征。在练习之前,首要需求对练习集的图画进行分类标注,如图所示,包含cat、dog、mug和hat四类。在实践工程中,或许有成千上万类别的物体,每个类别都会有上百万张图画。

跟我学Python图像处理丨图像分类原理与案例

图画分类是输入一堆图画的像素值数组,然后给它分配一个分类标签,经过练习学习来树立算法模型,接着运用该模型进行图画分类猜测,具体流程如下:

  • 输入: 输入包含N个图画的调集,每个图画的标签是K种分类标签中的一种,这个调集称为练习集。
  • 学习: 第二步任务是运用练习集来学习每个类的特征,构建练习分类器或许分类模型。
  • 点评: 经过分类器来猜测新输入图画的分类标签,并以此来点评分类器的质量。经过分类器猜测的标签和图画真正的分类标签比照,然后点评分类算法的好坏。假如分类器猜测的分类标签和图画真正的分类标签共同,表明猜测正确,否则猜测过错。

二.常见分类算法

常见的分类算法包含朴素贝叶斯分类器、决策树、K最近邻分类算法、支撑向量机、神经网络和依据规则的分类算法等,一起还有用于组合单一类办法的集成学习算法,如Bagging和Boosting等。

1.朴素贝叶斯分类算法

朴素贝叶斯分类(Naive Bayes Classifier)发源于古典数学理论,运用Bayes定理来猜测一个未知类别的样本归于各个类别的或许性,挑选其间或许性最大的一个类别作为该样本的终究类别。在朴素贝叶斯分类模型中,它将为每一个类别的特征向量树立服从正态散布的函数,给定练习数据,算法将会估计每一个类别的向量均值和方差矩阵,然后依据这些进行猜测。

朴素贝叶斯分类模型的正式界说如下:

跟我学Python图像处理丨图像分类原理与案例

该算法的特色为:假如没有许多数据,该模型会比许多杂乱的模型取得更好的性能,由于杂乱的模型用了太多假定,致使发生欠拟合。

2.KNN分类算法

K最近邻分类(K-Nearest Neighbor Classifier)算法是一种依据实例的分类办法,是数据发掘分类技术中最简单常用的办法之一。该算法的中心思维如下:一个样本x与样本会集的k个最相邻的样本中的大多数归于某一个类别yLabel,那么该样本x也归于类别yLabel,并具有这个类别样本的特性。

简而言之,一个样本与数据会集的k个最相邻样本中的大多数的类别相同。由其思维能够看出,KNN是经过丈量不同特征值之间的间隔进行分类,并且在决策样本类别时,只参考样本周围k个“街坊”样本的所属类别。因而比较适宜处理样本集存在较多堆叠的场景,首要用于猜测剖析、文本分类、降维等处理。

该算法在树立练习集时,就要确认练习数据及其对应的类别标签;然后把待分类的测验数据与练习集数据依次进行特征比较,从练习会集挑选出最相近的k个数据,这k个数据中投票最多的分类,即为新样本的类别。KNN分类算法的流程描述为如下图所示。

跟我学Python图像处理丨图像分类原理与案例

该算法的特色为:简单有用,但由于需求存储一切的练习集,占用很大内存,速度相对较慢,运用该办法前通常练习集需求进行降维处理。

3.SVM分类算法

支撑向量机(Support Vector Machine)是数学家Vapnik等人依据统计学习理论提出的一种新的学习办法,其根本模型界说为特征空间上间隔最大的线性分类器,其学习战略是间隔最大化,终究转换为一个凸二次规划问题的求解。SVM分类算法依据核函数把特征向量映射到高维空间,树立一个线性判别函数,解最优在某种意义上是两类中间隔切割面最近的特征向量和切割面的间隔最大化。离切割面最近的特征向量被称为“支撑向量”,即其它向量不影响切割面。图画分类中的SVM如下图所示,将图画区分为不同类别。

跟我学Python图像处理丨图像分类原理与案例

下面的比方能够让读者对SVM快速树立一个认知。给定练习样本,支撑向量机树立一个超平面作为决策曲面,使得正例和反例的隔离鸿沟最大化。决策曲面的构建进程如下所示:

  • 鄙人图中,想象红球和蓝球为球台上的桌球,首要需求找到一条曲线将蓝球和红球分开,所以得到一条黑色的曲线。

跟我学Python图像处理丨图像分类原理与案例

  • 为了使黑色曲线离恣意的蓝球和红球间隔最大化,咱们需求找到一条最优的曲线,如下图所示。

跟我学Python图像处理丨图像分类原理与案例

  • 假定这些球不是在球桌上,而是抛在空中,但仍然需求将红球和蓝球分开,这时就需求一个曲面,并且该曲面仍然满足一切恣意红球和蓝球的间距最大化,如图16-7所示。离这个曲面最近的红色球和蓝色球就被称为“支撑向量(Support Vector)”。

跟我学Python图像处理丨图像分类原理与案例

该算法的特色为:当数据集比较小的时候,支撑向量机的效果十分好。一起,SVM分类算法较好地解决了非线性、高维数、部分极小点等问题,维数大于样本数时仍然有用。

4.随机森林分类算法

随机森林(Random Forest)是用随机的办法树立一个森林,在森林里有许多决策树的组成,并且每一棵决策树之间是没有相关的。当有一个新样本出现的时候,经过森林中的每一棵决策树别离进行判别,看看这个样本归于哪一类,然后用投票的办法,决定哪一类被挑选的多,并作为终究的分类成果。

随机森林中的每一个决策树“种植”和“生长”首要包含以下四个进程:

  • 假定练习会集的样本个数为N,经过有重置的重复屡次抽样获取这N个样本,抽样成果将作为生成决策树的练习集;
  • 假如有M个输入变量,每个节点都将随机挑选m(m<M)个特定的变量,然后运用这m个变量来确认最佳的分裂点。在决策树的生成进程中,m值是坚持不变的;
  • 每棵决策树都最大或许地进行生长而不进行剪枝;
  • 经过对一切的决策树进行加来猜测新的数据(在分类时选用多数投票,在回归时选用均匀)。

该算法的特色为:在分类和回归剖析中都体现杰出;对高维数据的处理能力强,能够处理成千上万的输入变量,也是一个十分不错的降维办法;能够输出特征的重要程度,能有用地处理缺省值。

5.神经网络分类算法

神经网络(Neural Network)是对非线性可分数据的分类办法,通常包含输入层、躲藏层和输出层。其间,与输入直接相连的称为躲藏层(Hidden Layer),与输出直接相连的称为输出层(Output Layer)。神经网络算法的特色是有比较多的部分最优值,可经过屡次随机设定初始值并运行梯度下降算法取得最优值。图画分类中运用最广泛的是BP神经网络和CNN神经网络。

BP神经网络

BP神经网络是一种多层的前馈神经网络,其首要的特色为:信号是前向传达的,而误差是反向传达的。BP神经网络的进程首要分为两个阶段,第一阶段是信号的前向传达,从输入层经过隐含层,最终抵达输出层;第二阶段是误差的反向传达,从输出层到隐含层,最终到输入层,依次调节隐含层到输出层的权重和偏置,输入层到隐含层的权重和偏置,具体结构如下图所示。

跟我学Python图像处理丨图像分类原理与案例

神经网络的根本组成单元是神经元。神经元的通用模型如图所示,其间常用的激活函数有阈值函数、Sigmoid函数和双曲正切函数等。

跟我学Python图像处理丨图像分类原理与案例

CNN卷积神经网络

卷积神经网络(Convolutional Neural Networks)是一类包含卷积核算且具有深度结构的前馈神经网络,是深度学习的代表算法之一。卷积神经网络的研究始于二十世纪80至90年代,时间延迟网络和LeNet-5是最早出现的卷积神经网络。在二十一世纪后,跟着深度学习理论的提出和数值核算设备的改进,卷积神经网络得到了快速开展,并被大量应用于核算机视觉、自然语言处理等领域。

三.依据KNN算法的图画分类

1.KNN算法

K最近邻分类(K-Nearest Neighbor Classifier)算法是一种依据实例的分类办法,是数据发掘分类技术中最简单常用的办法之一。该算法的中心思维是从练习样本中寻觅一切练习样本X中与测验样本间隔(欧氏间隔)最近的前K个样本(作为类似度),再挑选与待分类样本间隔最小的K个样本作为X的K个最邻近,并检测这K个样本大部分归于哪一类样本,则认为这个测验样本类别归于这一类样本。

假定现在需求判别下图中的圆形图画归于三角形还是正方形类别,选用KNN算法剖析如下:

跟我学Python图像处理丨图像分类原理与案例

  • 当K=3时,图中第一个圈包含了三个图形,其间三角形2个,正方形一个,该圆的则分类成果为三角形。
  • 当K=5时,第二个圈中包含了5个图形,三角形2个,正方形3个,则以3:2的投票成果猜测圆为正方形类标。设置不同的K值,或许猜测得到不同的成果。

简而言之,一个样本与数据会集的k个最相邻样本中的大多数的类别相同。由其思维能够看出,KNN是经过丈量不同特征值之间的间隔进行分类,并且在决策样本类别时,只参考样本周围k个“街坊”样本的所属类别。因而比较适宜处理样本集存在较多堆叠的场景,首要用于猜测剖析、文本分类、降维等处理。

KNN在Sklearn机器学习包中,完成的类是neighbors.KNeighborsClassifier,简称KNN算法。构造办法为:

KNeighborsClassifier(algorithm='ball_tree',
    leaf_size=30, 
    metric='minkowski',
    metric_params=None, 
    n_jobs=1, 
    n_neighbors=3, 
    p=2, 
    weights='uniform')

KNeighborsClassifier能够设置3种算法:brute、kd_tree、ball_tree,设置K值参数为n_neighbors=3。调用办法如下:

  • from sklearn.neighbors import KNeighborsClassifier
  • knn = KNeighborsClassifier(n_neighbors=3, algorithm=“ball_tree”)

它包含两个进程:

  • 练习:nbrs.fit(data, target)
  • 猜测:pre = clf.predict(data)

2.数据集

该部分首要运用Scikit-Learn包进行Python图画分类处理。Scikit-Learn扩展包是用于Python数据发掘和数据剖析的经典、实用扩展包,通常缩写为Sklearn。Scikit-Learn中的机器学习模型是十分丰富的,包含线性回归、决策树、SVM、KMeans、KNN、PCA等等,用户能够依据具体剖析问题的类型挑选该扩展包的适宜模型,然后进行数据剖析,其装置进程首要经过“pip install scikit-learn”完成。

试验所选用的数据集为Sort_1000pics数据集,该数据集包含了1000张图片,总共分为10大类,别离是人(第0类)、沙滩(第1类)、修建(第2类)、大卡车(第3类)、恐龙(第4类)、大象(第5类)、花朵(第6类)、马(第7类)、山峰(第8类)和食物(第9类),每类100张。如图所示。

跟我学Python图像处理丨图像分类原理与案例

接着将一切各类图画依照对应的类标区分至“0”至“9”命名的文件夹中,如图所示,每个文件夹中均包含了100张图画,对应同一类别。

跟我学Python图像处理丨图像分类原理与案例

比方,文件夹称号为“6”中包含了100张花的图画,如下图所示。

跟我学Python图像处理丨图像分类原理与案例

3.KNN图画分类

下面是调用KNN算法进行图画分类的完整代码,它将1000张图画依照练习集为70%,测验集为30%的份额随机区分,再获取每张图画的像素直方图,依据像素的特征散布状况进行图画分类剖析。KNeighborsClassifier()中心代码如下:

  • from sklearn.neighbors import KNeighborsClassifier
  • clf = KNeighborsClassifier(n_neighbors=11).fit(XX_train, y_train)
  • predictions_labels = clf.predict(XX_test)

完整代码及注释如下:

# -*- coding: utf-8 -*-
import os
import cv2
import numpy as np
from sklearn.cross_validation import train_test_split
from sklearn.metrics import confusion_matrix, classification_report
#----------------------------------------------------------------------------------
# 第一步 切分练习集和测验集
#----------------------------------------------------------------------------------
X = [] #界说图画称号
Y = [] #界说图画分类类标
Z = [] #界说图画像素
for i in range(0, 10):
    #遍历文件夹,读取图片
    for f in os.listdir("photo/%s" % i):
        #获取图画称号
        X.append("photo//" +str(i) + "//" + str(f))
        #获取图画类标即为文件夹称号
        Y.append(i)
X = np.array(X)
Y = np.array(Y)
#随机率为100% 选取其间的30%作为测验集
X_train, X_test, y_train, y_test = train_test_split(X, Y,
                                                    test_size=0.3, random_state=1)
print len(X_train), len(X_test), len(y_train), len(y_test)
#----------------------------------------------------------------------------------
# 第二步 图画读取及转换为像素直方图
#----------------------------------------------------------------------------------
#练习集
XX_train = []
for i in X_train:
    #读取图画
    #print i
    image = cv2.imread(i)
    #图画像素大小共同
    img = cv2.resize(image, (256,256),
                     interpolation=cv2.INTER_CUBIC)
    #核算图画直方图并存储至X数组
    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:
    #读取图画
    #print i
    image = cv2.imread(i)
    #图画像素大小共同
    img = cv2.resize(image, (256,256),
                     interpolation=cv2.INTER_CUBIC)
    #核算图画直方图并存储至X数组
    hist = cv2.calcHist([img], [0,1], None,
                            [256,256], [0.0,255.0,0.0,255.0])
    XX_test.append(((hist/255).flatten()))
#----------------------------------------------------------------------------------
# 第三步 依据KNN的图画分类处理
#----------------------------------------------------------------------------------
from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors=11).fit(XX_train, y_train)
predictions_labels = clf.predict(XX_test)
print u'猜测成果:'
print predictions_labels
print u'算法点评:'
print (classification_report(y_test, predictions_labels))
#输出前10张图片及猜测成果
k = 0
while k<10:
    #读取图画
    print X_test[k]
    image = cv2.imread(X_test[k])
    print predictions_labels[k]
    #显现图画
    cv2.imshow("img", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    k = k + 1

代码中对猜测集的前十张图画进行了显现,其间“818.jpg”图画如图所示,其分类猜测的类标成果为“8”,表明第8类山峰,猜测成果正确。

跟我学Python图像处理丨图像分类原理与案例

下图展示了“452.jpg”图画,其分类猜测的类标成果为“4”,表明第4类恐龙,猜测成果正确。

跟我学Python图像处理丨图像分类原理与案例

下图展示了“507.jpg”图画,其分类猜测的类标成果为“7”,过错地猜测为第7类恐龙,其实在成果应该是第5类大象。

跟我学Python图像处理丨图像分类原理与案例

运用KNN算法进行图画分类试验,最终算法点评的准确率(Precision)、召回率(Recall)和F值(F1-score)如图所示,其间均匀准确率为0.64,均匀召回率为0.55,均匀F值为0.50,其成果不是十分理想。那么,假如选用CNN卷积神经网络进行分类,经过不断学习细节是否能进步准确度呢?

跟我学Python图像处理丨图像分类原理与案例

四.依据朴素贝叶斯算法的图画分类

下面是调用朴素贝叶斯算法进行图画分类的完整代码,调用sklearn.naive_bayes中的BernoulliNB()函数进行试验。它将1000张图画依照练习集为70%,测验集为30%的份额随机区分,再获取每张图画的像素直方图,依据像素的特征散布状况进行图画分类剖析。

# -*- coding: utf-8 -*-
import os
import cv2
import numpy as np
from sklearn.cross_validation import train_test_split
from sklearn.metrics import confusion_matrix, classification_report
#----------------------------------------------------------------------------------
# 第一步 切分练习集和测验集
#----------------------------------------------------------------------------------
X = [] #界说图画称号
Y = [] #界说图画分类类标
Z = [] #界说图画像素
for i in range(0, 10):
    #遍历文件夹,读取图片
    for f in os.listdir("photo/%s" % i):
        #获取图画称号
        X.append("photo//" +str(i) + "//" + str(f))
        #获取图画类标即为文件夹称号
        Y.append(i)
X = np.array(X)
Y = np.array(Y)
#随机率为100% 选取其间的30%作为测验集
X_train, X_test, y_train, y_test = train_test_split(X, Y,                                                   
test_size=0.3, random_state=1)
print len(X_train), len(X_test), len(y_train), len(y_test)
#----------------------------------------------------------------------------------
# 第二步 图画读取及转换为像素直方图
#----------------------------------------------------------------------------------
#练习集
XX_train = []
for i in X_train:
    #读取图画
    #print i
    image = cv2.imread(i)
    #图画像素大小共同
    img = cv2.resize(image, (256,256),
                     interpolation=cv2.INTER_CUBIC)
    #核算图画直方图并存储至X数组
    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:
    #读取图画
    #print i
    image = cv2.imread(i)
    #图画像素大小共同
    img = cv2.resize(image, (256,256),
                     interpolation=cv2.INTER_CUBIC)
    #核算图画直方图并存储至X数组
    hist = cv2.calcHist([img], [0,1], None,
                            [256,256], [0.0,255.0,0.0,255.0])
    XX_test.append(((hist/255).flatten()))
#----------------------------------------------------------------------------------
# 第三步 依据朴素贝叶斯的图画分类处理
#----------------------------------------------------------------------------------
from sklearn.naive_bayes import BernoulliNB
clf = BernoulliNB().fit(XX_train, y_train)
predictions_labels = clf.predict(XX_test)
print u'猜测成果:'
print predictions_labels
print u'算法点评:'
print (classification_report(y_test, predictions_labels))
#输出前10张图片及猜测成果
k = 0
while k<10:
    #读取图画
    print X_test[k]
    image = cv2.imread(X_test[k])
    print predictions_labels[k]
    #显现图画
    cv2.imshow("img", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    k = k + 1

代码中对猜测集的前十张图画进行了显现,其间“368.jpg”图画如下图所示,其分类猜测的类标成果为“3”,表明第3类大卡车,猜测成果正确。

跟我学Python图像处理丨图像分类原理与案例

下图展示了“452.jpg”图画,其分类猜测的类标成果为“4”,表明第4类恐龙,猜测成果正确。

跟我学Python图像处理丨图像分类原理与案例

运用朴素贝叶斯算法进行图画分类试验,最终猜测的成果及算法点评准确率(Precision)、召回率(Recall)和F值(F1-score)如图所示。

跟我学Python图像处理丨图像分类原理与案例

五.总结

本篇文章首要讲解Python环境下的图画分类算法,首要遍及了常见的分类算法,包含朴素贝叶斯、KNN、SVM、随机森林、神经网络等,接着经过朴素贝叶斯和KNN别离完成了1000张图画的图画分类试验,期望对读者有必定协助,也期望这些知识点为读者从事Python图画处理相关项目实践或科学研究提供必定根底。

参考文献:
[1]冈萨雷斯著. 数字图画处理(第3版)[M]. 北京:电子工业出版社,2013.
[2]杨秀璋, 颜娜. Python网络数据爬取及剖析从入门到精通(剖析篇)[M]. 北京:北京航天航空大学出版社, 2018.
[3]gzq0723. 干货——图画分类(上)[EB/OL]. (2018-08-28). blog.csdn.net/gzq0723/
[4]article/details/82185832.
[5]sinat_34430765. OpenCV分类器学习心得[EB/OL]. (2016-08-03). blog.csdn.net/sinat_34430….
[6]baidu_28342107. 机器学习之贝叶斯算法图画分类[EB/OL]. (2018-10-10). blog.csdn.net/baidu_28342….
[7]baidu_28342107. 机器学习之KNN算法完成图画分类[EB/OL]. (2018-09-28). blog.csdn.net/baidu_28342….
[8]normol. svm完成图片分类(python)[EB/OL]. (2018-11-19). blog.csdn.net/normol/arti….
[9]wfjiang. SVM-支撑向量机原理详解与实践[EB/OL]. (2017-03-14). www.cnblogs.com/spoorer/p/6….
[10]快乐的小飞熊. 随机森林原理[EB/OL]. (2017-03-05). www.jianshu.com/p/57e862d69….
[11]烨枫_邱. 深化了解BP神经网络[EB/OL]. (2018-06-01). www.jianshu.com/p/6ab6f5387….
[12]smilejiasmile. 卷积神经网络(CNN)及其实践[EB/OL]. (2018-06-20). blog.csdn.net/smilejiasmi….
[13] 誓天断发. 机器学习之BP神经网络算法完成图画分类[EB/OL]. (2018-10-23). blog.csdn.net/baidu_28342….
[14] 杨秀璋. [Python人工智能] 十.Tensorflow+Opencv完成CNN自界说图画分类事例及与机器学习KNN图画分类算法比照[EB/OL]. blog.csdn.net/Eastmount/a….

点击关注,第一时间了解华为云新鲜技术~