精华内容
下载资源
问答
  • 机器学习之KNN最邻近分类算法

    万次阅读 多人点赞 2018-09-15 13:13:33
    KNN(K-Nearest Neighbor)最邻近分类算法是数据挖掘分类(classification)技术中最简单的算法之一,其指导思想是”近朱者赤,近墨者黑“,即由你的邻居来推断出你的类别。 KNN最邻近分类算法的实现原理:为了...

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程

    KNN算法简介

    KNN(K-Nearest Neighbor)最邻近分类算法是数据挖掘分类(classification)技术中最简单的算法之一,其指导思想是”近朱者赤,近墨者黑“,即由你的邻居来推断出你的类别。

    KNN最邻近分类算法的实现原理:为了判断未知样本的类别,以所有已知类别的样本作为参照,计算未知样本与所有已知样本的距离,从中选取与未知样本距离最近的K个已知样本,根据少数服从多数的投票法则(majority-voting),将未知样本与K个最邻近样本中所属类别占比较多的归为一类。

              以上就是KNN算法在分类任务中的基本原理,实际上K这个字母的含义就是要选取的最邻近样本实例的个数,在 scikit-learn 中 KNN算法的 K 值是通过 n_neighbors 参数来调节的,默认值是 5。

              如下图所示,如何判断绿色圆应该属于哪一类,是属于红色三角形还是属于蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被判定为属于红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆将被判定为属于蓝色四方形类。

    由于KNN最邻近分类算法在分类决策时只依据最邻近的一个或者几个样本的类别来决定待分类样本所属的类别,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

               KNN算法的关键:

               (1) 样本的所有特征都要做可比较的量化

               若是样本特征中存在非数值的类型,必须采取手段将其量化为数值。例如样本特征中包含颜色,可通过将颜色转换为灰度值来实现距离计算。

               (2) 样本特征要做归一化处理

               样本有多个参数,每一个参数都有自己的定义域和取值范围,他们对距离计算的影响不一样,如取值较大的影响力会盖过取值较小的参数。所以样本参数必须做一些 scale 处理,最简单的方式就是所有特征的数值都采取归一化处置。

               (3) 需要一个距离函数以计算两个样本之间的距离

               通常使用的距离函数有:欧氏距离、余弦距离、汉明距离、曼哈顿距离等,一般选欧氏距离作为距离度量,但是这是只适用于连续变量。在文本分类这种非连续变量情况下,汉明距离可以用来作为度量。通常情况下,如果运用一些特殊的算法来计算度量的话,K近邻分类精度可显著提高,如运用大边缘最近邻法或者近邻成分分析法。

    以计算二维空间中的A(x1,y1)、B(x2,y2)两点之间的距离为例,欧氏距离和曼哈顿距离的计算方法如下图所示:

    (4) 确定K的值

               K值选的太大易引起欠拟合,太小容易过拟合,需交叉验证确定K值。

    KNN算法的优点:

               1.简单,易于理解,易于实现,无需估计参数,无需训练;

               2. 适合对稀有事件进行分类;

               3.特别适合于多分类问题(multi-modal,对象具有多个类别标签), kNN比SVM的表现要好。

    KNN算法的缺点:

               KNN算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数,如下图所示。该算法只计算最近的邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。

    该方法的另一个不足之处是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。

    可理解性差,无法给出像决策树那样的规则。

    KNN算法实现

    要自己动手实现KNN算法其实不难,主要有以下三个步骤:

               算距离:给定待分类样本,计算它与已分类样本中的每个样本的距离;

               找邻居:圈定与待分类样本距离最近的K个已分类样本,作为待分类样本的近邻;

               做分类:根据这K个近邻中的大部分样本所属的类别来决定待分类样本该属于哪个分类;

    以下是使用Python实现KNN算法的简单示例:

    import math
    import csv
    import operator
    import random
    import numpy as np
    from sklearn.datasets import make_blobs
    
    #Python version 3.6.5
    
    # 生成样本数据集 samples(样本数量) features(特征向量的维度) centers(类别个数)
    def createDataSet(samples=100, features=2, centers=2):
        return make_blobs(n_samples=samples, n_features=features, centers=centers, cluster_std=1.0, random_state=8)
    
    # 加载鸢尾花卉数据集 filename(数据集文件存放路径)
    def loadIrisDataset(filename):
        with open(filename, 'rt') as csvfile:
            lines = csv.reader(csvfile)
            dataset = list(lines)
            for x in range(len(dataset)):
                for y in range(4):
                    dataset[x][y] = float(dataset[x][y])
            return dataset
        
    # 拆分数据集 dataset(要拆分的数据集) split(训练集所占比例) trainingSet(训练集) testSet(测试集)
    def splitDataSet(dataSet, split, trainingSet=[], testSet=[]):
        for x in range(len(dataSet)):
            if random.random() <= split:
                trainingSet.append(dataSet[x])
            else:
                testSet.append(dataSet[x])
    # 计算欧氏距离 
    def euclideanDistance(instance1, instance2, length):
        distance = 0
        for x in range(length):
            distance += pow((instance1[x] - instance2[x]), 2)
        return math.sqrt(distance)
    
    # 选取距离最近的K个实例
    def getNeighbors(trainingSet, testInstance, k):
        distances = []
        length = len(testInstance) - 1
        for x in range(len(trainingSet)):
            dist = euclideanDistance(testInstance, trainingSet[x], length)
            distances.append((trainingSet[x], dist))
        distances.sort(key=operator.itemgetter(1))
        
        neighbors = []
        for x in range(k):
            neighbors.append(distances[x][0])
        return neighbors
    
    #  获取距离最近的K个实例中占比例较大的分类
    def getResponse(neighbors):
        classVotes = {}
        for x in range(len(neighbors)):
            response = neighbors[x][-1]
            if response in classVotes:
                classVotes[response] += 1
            else:
                classVotes[response] = 1
        sortedVotes = sorted(classVotes.items(), key=operator.itemgetter(1), reverse=True)
        return sortedVotes[0][0]
    
    # 计算准确率
    def getAccuracy(testSet, predictions):
        correct = 0
        for x in range(len(testSet)):
            if testSet[x][-1] == predictions[x]:
                correct += 1
        return (correct / float(len(testSet))) * 100.0
    
    
    def main():
        # 使用自定义创建的数据集进行分类
        # x,y = createDataSet(features=2)
        # dataSet= np.c_[x,y]
        
        # 使用鸢尾花卉数据集进行分类
        dataSet = loadIrisDataset(r'C:\DevTolls\eclipse-pureh2b\python\DeepLearning\KNN\iris_dataset.txt')
            
        print(dataSet)
        trainingSet = []
        testSet = []
        splitDataSet(dataSet, 0.75, trainingSet, testSet)
        print('Train set:' + repr(len(trainingSet)))
        print('Test set:' + repr(len(testSet)))
        predictions = []
        k = 7
        for x in range(len(testSet)):
            neighbors = getNeighbors(trainingSet, testSet[x], k)
            result = getResponse(neighbors)
            predictions.append(result)
            print('>predicted=' + repr(result) + ',actual=' + repr(testSet[x][-1]))
        accuracy = getAccuracy(testSet, predictions)
        print('Accuracy: ' + repr(accuracy) + '%')
    main()
        
    

    尾花卉数据文件百度网盘下载链接:https://pan.baidu.com/s/10vI5p_QuM7esc-jkar2zdQ 密码:4und

    KNN算法应用

    使用KNN算法处理简单分类任务

    在scikit-learn中,内置了若干个玩具数据集(Toy Datasets),还有一些API让我们可以自己动手生成一些数据集。接下来我们将使用scikit-learn的make_blobs函数来生成一个样本数量为200,分类数量为2的数据集,并使用KNN算法来对其进行分类。

    # 导入画图工具
    import matplotlib.pyplot as plt
    # 导入数组工具
    import numpy as np
    # 导入数据集生成器
    from sklearn.datasets import make_blobs
    # 导入KNN 分类器
    from sklearn.neighbors import KNeighborsClassifier
    # 导入数据集拆分工具
    from sklearn.model_selection import train_test_split
    
    # 生成样本数为200,分类数为2的数据集
    data=make_blobs(n_samples=200, n_features=2,centers=2, cluster_std=1.0, random_state=8)
    X,Y=data
    
    # 将生成的数据集进行可视化
    # plt.scatter(X[:,0], X[:,1],s=80, c=Y,  cmap=plt.cm.spring, edgecolors='k')
    # plt.show()
    
    clf = KNeighborsClassifier()
    clf.fit(X,Y)
    
    # 绘制图形
    x_min,x_max=X[:,0].min()-1,X[:,0].max()+1
    y_min,y_max=X[:,1].min()-1,X[:,1].max()+1
    xx,yy=np.meshgrid(np.arange(x_min,x_max,.02),np.arange(y_min,y_max,.02))
    z=clf.predict(np.c_[xx.ravel(),yy.ravel()])
    
    z=z.reshape(xx.shape)
    plt.pcolormesh(xx,yy,z,cmap=plt.cm.Pastel1)
    plt.scatter(X[:,0], X[:,1],s=80, c=Y,  cmap=plt.cm.spring, edgecolors='k')
    plt.xlim(xx.min(),xx.max())
    plt.ylim(yy.min(),yy.max())
    plt.title("Classifier:KNN")
    
    # 把待分类的数据点用五星表示出来
    plt.scatter(6.75,4.82,marker='*',c='red',s=200)
    
    # 对待分类的数据点的分类进行判断
    res = clf.predict([[6.75,4.82]])
    plt.text(6.9,4.5,'Classification flag: '+str(res))
    
    plt.show()

     程序执行后得到结果如下图所示:

    使用KNN算法处理多元分类任务

    接下来,我们再使用scikit-learn的make_blobs函数来生成一个样本数量为500,分类数量为5的数据集,并使用KNN算法来对其进行分类。

    # 导入画图工具
    import matplotlib.pyplot as plt
    # 导入数组工具
    import numpy as np
    # 导入数据集生成器
    from sklearn.datasets import make_blobs
    # 导入KNN 分类器
    from sklearn.neighbors import KNeighborsClassifier
    # 导入数据集拆分工具
    from sklearn.model_selection import train_test_split
    
    # 生成样本数为500,分类数为5的数据集
    data=make_blobs(n_samples=500, n_features=2,centers=5, cluster_std=1.0, random_state=8)
    X,Y=data
    
    # 将生成的数据集进行可视化
    # plt.scatter(X[:,0], X[:,1],s=80, c=Y,  cmap=plt.cm.spring, edgecolors='k')
    # plt.show()
    
    clf = KNeighborsClassifier()
    clf.fit(X,Y)
    
    # 绘制图形
    x_min,x_max=X[:,0].min()-1,X[:,0].max()+1
    y_min,y_max=X[:,1].min()-1,X[:,1].max()+1
    xx,yy=np.meshgrid(np.arange(x_min,x_max,.02),np.arange(y_min,y_max,.02))
    z=clf.predict(np.c_[xx.ravel(),yy.ravel()])
    
    z=z.reshape(xx.shape)
    plt.pcolormesh(xx,yy,z,cmap=plt.cm.Pastel1)
    plt.scatter(X[:,0], X[:,1],s=80, c=Y,  cmap=plt.cm.spring, edgecolors='k')
    plt.xlim(xx.min(),xx.max())
    plt.ylim(yy.min(),yy.max())
    plt.title("Classifier:KNN")
    
    # 把待分类的数据点用五星表示出来
    plt.scatter(0,5,marker='*',c='red',s=200)
    
    # 对待分类的数据点的分类进行判断
    res = clf.predict([[0,5]])
    plt.text(0.2,4.6,'Classification flag: '+str(res))
    plt.text(3.75,-13,'Model accuracy: {:.2f}'.format(clf.score(X, Y)))
    
    plt.show()

     程序执行后得到结果如下图所示:

    使用KNN算法进行回归分析

    这里我们使用scikit-learn的make_regression生成数据集来进行实验,演示KNN算法在回归分析中的表现。

    # 导入画图工具
    import matplotlib.pyplot as plt
    # 导入数组工具
    import numpy as np
    
    # 导入用于回归分析的KNN模型
    from sklearn.neighbors import KNeighborsRegressor
    # 导入数据集拆分工具
    from sklearn.model_selection import train_test_split
    # 导入数据集生成器
    from sklearn.datasets.samples_generator import make_regression
    from docutils.utils.math.math2html import LineWriter
    
    # 生成样本数为200,分类数为2的数据集
    X,Y=make_regression(n_samples=100,n_features=1,n_informative=1,noise=50,random_state=8)
    
    # 将生成的数据集进行可视化
    # plt.scatter(X,Y,s=80, c='orange',  cmap=plt.cm.spring, edgecolors='k')
    # plt.show()
    reg = KNeighborsRegressor(n_neighbors=5)
    
    reg.fit(X,Y)
    
    # 将预测结果用图像进行可视化
    z = np.linspace(-3,3,200).reshape(-1,1)
    plt.scatter(X,Y,c='orange',edgecolor='k')
    plt.plot(z,reg.predict(z),c='k',Linewidth=3)
    #
    plt.title("KNN Regressor")
    
    plt.show()

      程序执行后得到结果如下图所示:

    KNN算法项目实战----酒的分类

    from sklearn.datasets.base import load_wine
    from sklearn.model_selection import train_test_split
    from sklearn.neighbors import KNeighborsClassifier
    import numpy as np
    
    # 从 sklearn的datasets模块载入数据集加载酒的数据集
    wineDataSet=load_wine()
    print(wineDataSet)
    print("红酒数据集中的键:\n{}".format(wineDataSet.keys()))
    print("数据概况:\n{}".format(wineDataSet['data'].shape))
    print(wineDataSet['DESCR'])
    
    # 将数据集拆分为训练数据集和测试数据集
    X_train,X_test,y_train,y_test=train_test_split(wineDataSet['data'],wineDataSet['target'],random_state=0)
    print("X_train shape:{}".format(X_train.shape))
    print("X_test shape:{}".format(X_test.shape))
    print("y_train shape:{}".format(y_train.shape))
    print("y_test shape:{}".format(y_test.shape))
    
    knn = KNeighborsClassifier(n_neighbors=1)
    knn.fit(X_train,y_train)
    print(knn)
    
    # 评估模型的准确率
    print('测试数据集得分:{:.2f}'.format(knn.score(X_test,y_test)))
    
    # 使用建好的模型对新酒进行分类预测
    X_new = np.array([[13.2,2.77,2.51,18.5,96.6,1.04,2.55,0.57,1.47,6.2,1.05,3.33,820]])
    prediction = knn.predict(X_new)
    print("预测新酒的分类为:{}".format(wineDataSet['target_names'][prediction]))

     执行程序后打印如下结果:

    X_train shape:(133, 13)
    X_test shape:(45, 13)
    y_train shape:(133,)
    y_test shape:(45,)
    KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
               metric_params=None, n_jobs=1, n_neighbors=1, p=2,
               weights='uniform')
    测试数据集得分:0.76
    预测新酒的分类为:['class_2']

    参考书籍:《深入浅出 Python 机器学习》 作者:段小手

    展开全文
  • 基于支持向量机的图像分类(下篇:MATLAB实现)

    万次阅读 多人点赞 2018-04-11 00:19:20
    摘要:本文通过图文详细介绍如何利用支持向量机对图像进行分类,经过上篇文章对原理的介绍,这里介绍利用MATLAB编程实现。后续章节将介绍的主要部分有: 图片数据集整理 特征提取 SVM训练与测试 分类结果...

    摘要:本文通过图文详细介绍如何利用支持向量机对图像进行分类,经过上篇文章对原理的介绍,这里介绍利用MATLAB编程实现。更多相关资源详解也可参考博主最新博文基于支持向量机的手写数字识别详解(MATLAB GUI代码,提供手写板)。本文后续章节将介绍的主要部分有:

    • 图片数据集整理
    • 特征提取
    • SVM训练与测试
    • 分类结果评价
    • 结果显示

    点我下载:SVM图像分类的MATLAB完整程序及图片集文件


    1. 前言

    机器学习是人工智能研究发展到一定阶段的必然产物。二十世纪八十年代是机器学习成为一个独立学科的学科领域、各种机器学习技术百花绽放的时期。支持向量机于1995年正式发表[Cortes and Vapnik,1995],由于在文本分类任务中的卓越性能[Joachims,1998],很快成为机器学习的主流技术,并直接掀起了“统计学习”(statistical learning)在2000年前后的高潮。——《机器学习》 周志华

    2010年前后,随着计算能力的迅猛提升和大数据的涌现,神经网络研究在“深度学习”的名义下又重新崛起,并迎来又一次发展高潮。近年研究SVM的论文少了很多,SVM的风头很多时候确实已被强势崛起的深度学习浪潮所淹没,95年的SVM比我们年龄还大,有点仿佛英雄迟暮的感觉。不过在我看来,实现简单而且非常强大的分类算法SVM仍然有其研究价值,与神经网络相比SVM亦有过人之处,如特征维数多于样本数的情况,而小样本学习至今仍是深度学习的一大难题。

    当浅层神经网络效果不佳时,人们将目光转向支持向量机,而支持向量机亦不负众望,以不错的成绩让人们对机器学习重拾信心。感谢支持向量机,感谢在神经网络几经起落的时候,支持向量机继往开来、自成一脉,填补了机器学习的一段空窗期,让这条曲折向上的研究之路绵延至今迎来了现在人工智能百花齐放的时代!

    接下来就通过简单的图片分类问题,通过MATLAB程序理解认识一下这一简单而强大的分类算法——支持向量机.


    2. 图片数据集整理

    首先需要准备好分类的数据集,数据的整理是机器学习中的重要一环。这里我们自行整理一个用于分类的图片集,图片集有四类图片,分别为车、猫、花、鱼。从百度上下载这四种图片,并分别存放在四个文件夹中,如下图所示

    70

    四类图片每类分别下载100张左右的图片,这四百张图片作为分类的数据集,以7:3的比例将其分为训练图片集和测试图片集,分别放到picturestestPictures两个文件夹中。这两个文件夹下同上图一样都有car、cat、flw、fsh四个文件夹,值得注意的是测试样本的图片应可能不出现在训练集图片库中。做好以上工作,用于分类的图片集就准备完毕了。

    (当然用于分类的图片集常用的是cafir10图片集,这个数据集是写论文或研究时普遍用到的,可能会在后面的文章中介绍其用法,这里就暂时不使用cafir了。)

    为了便于后面的特征提取等对每张图片进行的操作,这里在程序中有必要将图片文件的存储位置、数量、类别等信息整理到一个数据结构中,新建一个m文件,程序代码如下

    dir=('D:\pictures');
    testdir=('D:\testPictures\test');
    trainingSet = imageSet(dir,'recursive');
    testSet = imageSet(testdir,'recursive');
    

    以上代码中用到imageSet( )函数是一个图片集整理的函数(MATLAB R2016b及以上版本支持),返回的是dir文件路径下文件夹内的文件信息。例如得到的trainingSet为一个1*4的imageSet变量,每个imageSet变量由Description、ImageLocation、Count三个属性组成,分别代表对子文件的描述、文件存储位置和图片数量。如下图所示是testSet(1)内部情况

    70

    3. 主要步骤

    和深度学习的算法相比,传统的机器学习在进行图片分类时输入的不是原始图片而是先进行一个特征提取的步骤。在上篇中已经介绍了特征提取的相关内容,这里用的是方向梯度直方图(HOG)以及灰度共生矩阵(GLCM)。

    70

    3.1 GLCM提取

    MATLAB中灰度共生矩阵的提取可以调用graycomatrix( )函数,不过这里为了取不同方向(0、45、90、135度)的灰度共生矩阵,通过循环计算各个方向的灰度共生矩阵并进行归一化处理(计算对比度、逆差距、熵、自相关),然后取平均值和方差作为最终提取的特征。

    新建一个m文件并命名为getGLCMFeatures,输入以下代码

    function [features] = getGLCMFeatures(image)
    features_all  = [];
    for i = 1:10
        glcm = graycomatrix(image, 'Offset', [0,i]);
        stats = graycoprops(glcm);
        
        glcm45 = graycomatrix(image, 'Offset', [-i,i]);
        stats45 = graycoprops(glcm45);
        
        glcm90 = graycomatrix(image, 'Offset', [-i,0]);
        stats90 = graycoprops(glcm90);
        
        glcm135 = graycomatrix(image, 'Offset', [-i,-i]);
        stats135 = graycoprops(glcm135);
        
        stats7x4 = [stats.Contrast stats.Correlation stats.Energy stats.Homogeneity;
            stats45.Contrast stats45.Correlation stats45.Energy stats45.Homogeneity;
            stats90.Contrast stats90.Correlation stats90.Energy stats90.Homogeneity;
            stats135.Contrast stats135.Correlation stats135.Energy stats135.Homogeneity];
        features_all = [features_all mean(stats7x4,1) std(stats7x4,0,1)];
    end
    features = features_all;
    

    新建的getGLCMFeatures函数输入为彩色图像转换后的灰度图像矩阵,输出为提取后的灰度共生矩阵特征。

    3.2 合并特征

    自己编写一个提取特征的函数命名为extractFeature,这个函数输入为整理过的训练集和测试集,输出为训练集的特征、标签和测试集的特征、标签。这个函数的功能是将HOG特征和前面提取的GLCM特征合并。

    代码第2到13行是为了确定每张图片提取特征后得到的矩阵大小,以方便后面的操作同时也是为了预分配空间以提高代码效率。首先取第一张图片进行灰度化以及阈值分割,将图片大小调整在256*256的范围(统一大小)分别进行HOG和GLCM的特征提取,分别得到两种特征向量,取两个向量的长度之和就是一张图片特征提取后的总长度了。

    function [trainingFeatures,trainingLabels,testFeatures,testLabels]=extractFeature(trainingSet,testSet)
    %% 确定特征向量尺寸
    img = read(trainingSet(1), 1);
    %转化为灰度图像
    img=rgb2gray(img);
    %转化为2值图像
    lvl = graythresh(img);
    img = im2bw(img, lvl);
    img=imresize(img,[256 256]);
    cellSize = [4 4];
    [hog_feature, vis_hog] = extractHOGFeatures(img,'CellSize',cellSize);
    glcm_feature = getGLCMFeatures(img);
    SizeOfFeature = length(hog_feature)+ length(glcm_feature);
    
    %% 构建训练样本特征向量和训练样本标签
    trainingFeatures = [];
    trainingLabels   = [];
    for digit = 1:numel(trainingSet)       
        numImages = trainingSet(digit).Count;
        features  = zeros(numImages, SizeOfFeature, 'single');%初始化特征向量
        % 遍历每张图片
        for i = 1:numImages
            img = read(trainingSet(digit), i);% 取出第i张图片
            
            img=rgb2gray(img);                % 转化为灰度图像
            glcm_feature = getGLCMFeatures(img);  % 提取GLCM特征
           
            lvl = graythresh(img);            % 阈值化
            img = im2bw(img, lvl);            % 转化为2值图像
            img=imresize(img,[256 256]);
            % 提取HOG特征
            [hog_feature, vis_hog] = extractHOGFeatures(img,'CellSize',cellSize);
            % 合并两个特征
            features(i, :) = [hog_feature glcm_feature];
        end
        % 使用图像描述作为训练标签
        labels = repmat(trainingSet(digit).Description, numImages, 1);  
        % 逐个添加每张训练图片的特征和标签
        trainingFeatures = [trainingFeatures; features];
        trainingLabels   = [trainingLabels; labels];       
    end
    
    
    %% 提取测试图片集的特征向量
    testFeatures = [];
    testLabels   = [];
    for digit = 1:numel(testSet)
               
        numImages = testSet(digit).Count;
        %初始化特征向量
        features  = zeros(numImages, SizeOfFeature, 'single');
        
        for i = 1:numImages
            
            img = read(testSet(digit), i);
            %转化为灰度图像
            img=rgb2gray(img);
            glcm_feature = getGLCMFeatures(img);
            %转化为2值图像
            lvl = graythresh(img);
            img = im2bw(img, lvl);
            img=imresize(img,[256 256]);
            [hog_4x4, vis4x4] = extractHOGFeatures(img,'CellSize',cellSize);
            features(i, :) = [hog_4x4 glcm_feature];
        end
        
        % 使用图像描述作为训练标签
        labels = repmat(testSet(digit).Description, numImages, 1);
            
        testFeatures = [testFeatures; features];
        testLabels=[testLabels; labels];
            
    end
    end
    

    代码18-41行是构建训练样本特征向量和训练样本标签,与前面步骤相似,只不过现在是遍历训练集每一张图片,对其进行灰度化、阈值化、调整大小,然后进行特征提取,将HOG特征和GLCM特征合并成一个向量作为特征矩阵的一行即一张图片的特征向量。样本的标签构建则将每张图片所处的文件夹的名字作为该图片的标签,并与特征向量顺序相对应。

    第47-73行是构建测试样本特征向量和训练样本标签,这里将图片集换成了测试集,而步骤与训练集是一致的。

    3.3 SVM训练与测试

    调用前面的特征提取函数得到训练和测试用的特征向量与对应的标签,便可以进行SVM的训练和测试。MATLAB自带的训练svm函数可以用fitcecoc函数,测试可以用predict函数预测结果,训练和测试的代码如下

    % 训练一个svm分类器
    % fitcecoc 使用11的方案
    classifier = fitcecoc(trainingFeatures, trainingLabels);
    save classifier.mat classifier;
    
    % 使用测试图像的特征向量预测样本标签
    predictedLabels = predict(classifier, testFeatures);
    

    代码中classifier为训练得到的SVM分类器,利用该分类器以及测试集特征向量预测测试集的标签predictLabels。后面可以将predictLabels与实际的测试标签进行对比即可评估分类好坏。

    3.4 分类结果评价

    在上一篇文章中提到过了,为了评价分类的好坏可以通过混淆矩阵,通过计算混淆矩阵对角线上的值占每行总数的比值得出分类正确率,其实现代码如下

    %% 评估分类器
    % 使用没有标签的图像数据进行测试,生成一个混淆矩阵表明分类效果
    confMat=confusionmat(testLabels, predictedLabels)
    accuracy=(confMat(1,1)/sum(confMat(1,:))+confMat(2,2)/sum(confMat(2,:))+...
        confMat(3,3)/sum(confMat(3,:))+confMat(4,4)/sum(confMat(4,:)))/4
    

    其结果如下图所示

    70

    3.5 结果显示

    尽管以上代码能得到分类正确率,但我们希望更直观的看到输入一张图片后SVM分类器的分类结果,这里编写一个函数通过图形窗口显示预测结果。新建一个m文件命名为Predict,输入如下代码

    function [] = Predict(imageurl)
    load classifier.mat;
    figure;
    img = imread(imageurl);
    imshow(img);
    
    %提取图像的特征向量
    %转化为灰度图像
    img=rgb2gray(img);
    glcm_feature = getGLCMFeatures(img);
    %转化为2值图像
    lvl = graythresh(img);
    img = im2bw(img, lvl);
    
    % imshow(img);
    % figure
    img=imresize(img,[256 256]);
    [hog_4x4, ~] = extractHOGFeatures(img,'CellSize',[4 4]);
    testFeature = [hog_4x4 glcm_feature];
    
    
    % 使用测试图像的特征向量预测样本标签
    predictedLabel = predict(classifier, testFeature);
    
    str = ['分类结果:' predictedLabel];
    dim = [0.25 0.0004 0.2 0.2];
    annotation('textbox', dim, 'string', str, 'fontsize', 20, 'color', 'g','edgecolor', 'none');
    

    函数输入为图片的存储路径,调用函数则会通过图形窗口显示图片及分类结果,如在命令窗口输入如下代码

    Predict('D:\testPictures\test\car\car9.jpg');
    

    输出结果如下图

    70

    4. 完整代码

    为了方便使用这里贴出完整代码

    主函数:

    clear;
    dir=('D:\pictures');
    testdir=('D:\testPictures\test');
    trainingSet = imageSet(dir,'recursive');
    testSet = imageSet(testdir,'recursive');
    
    [trainingFeatures,trainingLabels,testFeatures,testLabels]=extractFeature(trainingSet,testSet);
    %% 
    %训练一个svm分类器
    %fitcecoc 使用11的方案
    classifier = fitcecoc(trainingFeatures, trainingLabels);
    save classifier.mat classifier;
    
    % 使用测试图像的特征向量预测样本标签
    predictedLabels = predict(classifier, testFeatures);
    
    %% 评估分类器
    %使用没有标签的图像数据进行测试,生成一个混淆矩阵表明分类效果
    confMat=confusionmat(testLabels, predictedLabels)
    accuracy=(confMat(1,1)/sum(confMat(1,:))+confMat(2,2)/sum(confMat(2,:))+...
        confMat(3,3)/sum(confMat(3,:))+confMat(4,4)/sum(confMat(4,:)))/4
    
    Predict('D:\testPictures\test\car\car9.jpg');
    

    getGLCMFeatures.m:

    function [features] = getGLCMFeatures(image)
    features_all  = [];
    for i = 1:10
        glcm = graycomatrix(image, 'Offset', [0,i]);
        stats = graycoprops(glcm);
        
        glcm45 = graycomatrix(image, 'Offset', [-i,i]);
        stats45 = graycoprops(glcm45);
        
        glcm90 = graycomatrix(image, 'Offset', [-i,0]);
        stats90 = graycoprops(glcm90);
        
        glcm135 = graycomatrix(image, 'Offset', [-i,-i]);
        stats135 = graycoprops(glcm135);
        
        stats7x4 = [stats.Contrast stats.Correlation stats.Energy stats.Homogeneity;
            stats45.Contrast stats45.Correlation stats45.Energy stats45.Homogeneity;
            stats90.Contrast stats90.Correlation stats90.Energy stats90.Homogeneity;
            stats135.Contrast stats135.Correlation stats135.Energy stats135.Homogeneity];
        features_all = [features_all mean(stats7x4,1) std(stats7x4,0,1)];
    end
    features = features_all;
    

    extractFeature.m:

    function [trainingFeatures,trainingLabels,testFeatures,testLabels]=extractFeature(trainingSet,testSet)
    %% 确定特征向量尺寸
    img = read(trainingSet(1), 1);
    %转化为灰度图像
    img=rgb2gray(img);
    %转化为2值图像
    lvl = graythresh(img);
    img = im2bw(img, lvl);
    img=imresize(img,[256 256]);
    cellSize = [4 4];
    [hog_feature, vis_hog] = extractHOGFeatures(img,'CellSize',cellSize);
    glcm_feature = getGLCMFeatures(img);
    SizeOfFeature = length(hog_feature)+ length(glcm_feature);
    
    %% 构建训练样本特征向量和训练样本标签
    trainingFeatures = [];
    trainingLabels   = [];
    for digit = 1:numel(trainingSet)       
        numImages = trainingSet(digit).Count;
        features  = zeros(numImages, SizeOfFeature, 'single');%初始化特征向量
        % 遍历每张图片
        for i = 1:numImages
            img = read(trainingSet(digit), i);% 取出第i张图片
            
            img=rgb2gray(img);                % 转化为灰度图像
            glcm_feature = getGLCMFeatures(img);  % 提取GLCM特征
           
            lvl = graythresh(img);            % 阈值化
            img = im2bw(img, lvl);            % 转化为2值图像
            img=imresize(img,[256 256]);
            % 提取HOG特征
            [hog_feature, vis_hog] = extractHOGFeatures(img,'CellSize',cellSize);
            % 合并两个特征
            features(i, :) = [hog_feature glcm_feature];
        end
        % 使用图像描述作为训练标签
        labels = repmat(trainingSet(digit).Description, numImages, 1);  
        % 逐个添加每张训练图片的特征和标签
        trainingFeatures = [trainingFeatures; features];
        trainingLabels   = [trainingLabels; labels];       
    end
    
    
    %% 提取测试图片集的特征向量
    testFeatures = [];
    testLabels   = [];
    for digit = 1:numel(testSet)
               
        numImages = testSet(digit).Count;
        %初始化特征向量
        features  = zeros(numImages, SizeOfFeature, 'single');
        
        for i = 1:numImages
            
            img = read(testSet(digit), i);
            %转化为灰度图像
            img=rgb2gray(img);
            glcm_feature = getGLCMFeatures(img);
            %转化为2值图像
            lvl = graythresh(img);
            img = im2bw(img, lvl);
            img=imresize(img,[256 256]);
            [hog_4x4, vis4x4] = extractHOGFeatures(img,'CellSize',cellSize);
            features(i, :) = [hog_4x4 glcm_feature];
        end
        
        % 使用图像描述作为训练标签
        labels = repmat(testSet(digit).Description, numImages, 1);
            
        testFeatures = [testFeatures; features];
        testLabels=[testLabels; labels];
            
    end
    end
    

    Predict.m:

    function [] = Predict(imageurl)
    load classifier.mat;
    figure;
    img = imread(imageurl);
    imshow(img);
    
    %提取图像的特征向量
    %转化为灰度图像
    img=rgb2gray(img);
    glcm_feature = getGLCMFeatures(img);
    %转化为2值图像
    lvl = graythresh(img);
    img = im2bw(img, lvl);
    
    % imshow(img);
    % figure
    img=imresize(img,[256 256]);
    [hog_4x4, ~] = extractHOGFeatures(img,'CellSize',[4 4]);
    testFeature = [hog_4x4 glcm_feature];
    
    
    % 使用测试图像的特征向量预测样本标签
    predictedLabel = predict(classifier, testFeature);
    
    str = ['分类结果:' predictedLabel];
    dim = [0.25 0.0004 0.2 0.2];
    annotation('textbox', dim, 'string', str, 'fontsize', 20, 'color', 'g','edgecolor', 'none');
    

    5. 结束语

    本博文的完整MATLAB程序文件与图片集文件已经上传,下载即可运行(注意根据实际修改程序中的图片路径哦)下载地址如下

    点我下载:SVM的图像分类MATLAB完整程序及图片集文件

    更多相关资源详解也可参考博主最新博文基于支持向量机的手写数字识别详解(MATLAB GUI代码,提供手写板)

    公众号获取
        本人微信公众号已创建,扫描以下二维码并关注公众号“AI技术研究与分享”,后台回复“SV20180411”即可获取全部资源文件信息。

    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyODkyMzgz,size_16,color_FFFFFF,t_70

    由于编者能力有限,代码即使经过了多次校对,也难免会有疏漏之处。希望您能热心指出其中的错误,以便下次修改时能以一个更完美更严谨的样子,呈现在大家面前。同时如果有更好的实现方法也请您不吝赐教。

    展开全文
  • 带你搞懂朴素贝叶斯分类算法

    万次阅读 多人点赞 2017-04-14 16:19:33
    贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。而朴素朴素贝叶斯分类是贝叶斯分类中最简单,也是常见的一种分类方法。这篇文章我尽可能用直白的话语总结一下我们学习会上讲到...

    最新人工智能论文:http://paperreading.club

    带你搞懂朴素贝叶斯分类算

    贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。而朴素朴素贝叶斯分类是贝叶斯分类中最简单,也是常见的一种分类方法。这篇文章我尽可能用直白的话语总结一下我们学习会上讲到的朴素贝叶斯分类算法,希望有利于他人理解。

     

    1  分类问题综述

     对于分类问题,其实谁都不会陌生,日常生活中我们每天都进行着分类过程。例如,当你看到一个人,你的脑子下意识判断他是学生还是社会上的人;你可能经常会走在路上对身旁的朋友说“这个人一看就很有钱”之类的话,其实这就是一种分类操作。

     

    既然是贝叶斯分类算法,那么分类的数学描述又是什么呢?

     

    从数学角度来说,分类问题可做如下定义:已知集合,确定映射规则y = f(x),使得任意有且仅有一个,使得成立。

     

    其中C叫做类别集合,其中每一个元素是一个类别,而I叫做项集合(特征集合),其中每一个元素是一个待分类项,f叫做分类器。分类算法的任务就是构造分类器f。

     

    分类算法的内容是要求给定特征,让我们得出类别,这也是所有分类问题的关键。那么如何由指定特征,得到我们最终的类别,也是我们下面要讲的,每一个不同的分类算法,对应着不同的核心思想。

     

    本篇文章,我会用一个具体实例,对朴素贝叶斯算法几乎所有的重要知识点进行讲解。

     

    2  朴素贝叶斯分类

    那么既然是朴素贝叶斯分类算法,它的核心算法又是什么呢?

    是下面这个贝叶斯公式:

     

     

    换个表达形式就会明朗很多,如下:

     

     

    我们最终求的p(类别|特征)即可!就相当于完成了我们的任务。

     

    3  例题分析

    下面我先给出例子问题。

     

    给定数据如下:

     

     

    现在给我们的问题是,如果一对男女朋友,男生想女生求婚,男生的四个特点分别是不帅,性格不好,身高矮,不上进,请你判断一下女生是还是不嫁

     

    这是一个典型的分类问题,转为数学问题就是比较p(嫁|(不帅、性格不好、身高矮、不上进))与p(不嫁|(不帅、性格不好、身高矮、不上进))的概率,谁的概率大,我就能给出嫁或者不嫁的答案!

    这里我们联系到朴素贝叶斯公式:

     

     

    我们需要求p(嫁|(不帅、性格不好、身高矮、不上进),这是我们不知道的,但是通过朴素贝叶斯公式可以转化为好求的三个量.

     

    p(不帅、性格不好、身高矮、不上进|嫁)、p(不帅、性格不好、身高矮、不上进)、p(嫁)(至于为什么能求,后面会讲,那么就太好了,将待求的量转化为其它可求的值,这就相当于解决了我们的问题!

     

    4  朴素贝叶斯算法的朴素一词解释

    那么这三个量是如何求得?

     

    是根据已知训练数据统计得来,下面详细给出该例子的求解过程。

    回忆一下我们要求的公式如下:

     

     

    那么我只要求得p(不帅、性格不好、身高矮、不上进|嫁)、p(不帅、性格不好、身高矮、不上进)、p(嫁)即可,好的,下面我分别求出这几个概率,最后一比,就得到最终结果。

     

    p(不帅、性格不好、身高矮、不上进|嫁) = p(不帅|嫁)*p(性格不好|嫁)*p(身高矮|嫁)*p(不上进|嫁),那么我就要分别统计后面几个概率,也就得到了左边的概率!

     

    等等,为什么这个成立呢?学过概率论的同学可能有感觉了,这个等式成立的条件需要特征之间相互独立吧!

     

    对的!这也就是为什么朴素贝叶斯分类有朴素一词的来源,朴素贝叶斯算法是假设各个特征之间相互独立,那么这个等式就成立了!

     

    但是为什么需要假设特征之间相互独立呢?

     

     

    1、我们这么想,假如没有这个假设,那么我们对右边这些概率的估计其实是不可做的,这么说,我们这个例子有4个特征,其中帅包括{帅,不帅},性格包括{不好,好,爆好},身高包括{高,矮,中},上进包括{不上进,上进},那么四个特征的联合概率分布总共是4维空间,总个数为2*3*3*2=36个。

     

    36个,计算机扫描统计还可以,但是现实生活中,往往有非常多的特征,每一个特征的取值也是非常之多,那么通过统计来估计后面概率的值,变得几乎不可做,这也是为什么需要假设特征之间独立的原因。

     

    2、假如我们没有假设特征之间相互独立,那么我们统计的时候,就需要在整个特征空间中去找,比如统计p(不帅、性格不好、身高矮、不上进|嫁),

     

    我们就需要在嫁的条件下,去找四种特征全满足分别是不帅,性格不好,身高矮,不上进的人的个数,这样的话,由于数据的稀疏性,很容易统计到0的情况。 这样是不合适的。

     

    根据上面俩个原因,朴素贝叶斯法对条件概率分布做了条件独立性的假设,由于这是一个较强的假设,朴素贝叶斯也由此得名!这一假设使得朴素贝叶斯法变得简单,但有时会牺牲一定的分类准确率。

     

    好的,上面我解释了为什么可以拆成分开连乘形式。那么下面我们就开始求解!

     

    我们将上面公式整理一下如下:

     

     

    下面我将一个一个的进行统计计算(在数据量很大的时候,根据中心极限定理,频率是等于概率的,这里只是一个例子,所以我就进行统计即可)。

     

    p(嫁)=?

    首先我们整理训练数据中,嫁的样本数如下:

     

    则 p(嫁) = 6/12(总样本数) = 1/2

     

    p(不帅|嫁)=?统计满足样本数如下:

     

    则p(不帅|嫁) = 3/6 = 1/2 在嫁的条件下,看不帅有多少

     

    p(性格不好|嫁)= ?统计满足样本数如下:

     

    则p(性格不好|嫁)= 1/6

     

    p(矮|嫁) = ?统计满足样本数如下:

     

    则p(矮|嫁) = 1/6

     

    p(不上进|嫁) = ?统计满足样本数如下:

     

    则p(不上进|嫁) = 1/6

     

    下面开始求分母,p(不帅),p(性格不好),p(矮),p(不上进)

    统计样本如下:

     

     

    不帅统计如上红色所示,占4个,那么p(不帅) = 4/12 = 1/3

     

     

    性格不好统计如上红色所示,占4个,那么p(性格不好) = 4/12 = 1/3

     

     

    身高矮统计如上红色所示,占7个,那么p(身高矮) = 7/12

     

     

    不上进统计如上红色所示,占4个,那么p(不上进) = 4/12 = 1/3

     

    到这里,要求p(不帅、性格不好、身高矮、不上进|嫁)的所需项全部求出来了,下面我带入进去即可,

     

    = (1/2*1/6*1/6*1/6*1/2)/(1/3*1/3*7/12*1/3)

     

    下面我们根据同样的方法来求p(不嫁|不帅,性格不好,身高矮,不上进),完全一样的做法,为了方便理解,我这里也走一遍帮助理解。首先公式如下:

     

     

    下面我也一个一个来进行统计计算,这里与上面公式中,分母是一样的,于是我们分母不需要重新统计计算!

     

    p(不嫁)=?根据统计计算如下(红色为满足条件):

     

     

    则p(不嫁)=6/12 = 1/2

     

    p(不帅|不嫁) = ?统计满足条件的样本如下(红色为满足条件):

     

     

    则p(不帅|不嫁) = 1/6

     

    p(性格不好|不嫁) = ?据统计计算如下(红色为满足条件):


    则p(性格不好|不嫁) =3/6 = 1/2

     

    p(矮|不嫁) = ?据统计计算如下(红色为满足条件):

     

    则p(矮|不嫁) = 6/6 = 1

     

    p(不上进|不嫁) = ?据统计计算如下(红色为满足条件):

    则p(不上进|不嫁) = 3/6 = 1/2

     

    那么根据公式:

     

    p (不嫁|不帅、性格不好、身高矮、不上进) = ((1/6*1/2*1*1/2)*1/2)/(1/3*1/3*7/12*1/3)

    很显然(1/6*1/2*1*1/2) > (1/2*1/6*1/6*1/6*1/2)

     

    于是有p (不嫁|不帅、性格不好、身高矮、不上进)>p (嫁|不帅、性格不好、身高矮、不上进)

     

    所以我们根据朴素贝叶斯算法可以给这个女生答案,是不嫁!!!!

     

    5  朴素贝叶斯分类的优缺点

    优点:

    (1) 算法逻辑简单,易于实现(算法思路很简单,只要使用贝叶斯公式转化医学即可!

    (2)分类过程中时空开销小(假设特征相互独立,只会涉及到二维存储

     

    缺点:

     

    理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。

     

    而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。

     

    整个例子详细的讲解了朴素贝叶斯算法的分类过程,希望对大家的理解有帮助~

     

    参考:李航博士《统计学习方法》

    算法杂货铺--分类算法之朴素贝叶斯分类(Naive Bayesian classification)

     

    致谢:德川,皓宇,继豪,施琦


    原文地址:https://mp.weixin.qq.com/s?__biz=MzI4MDYzNzg4Mw==&mid=2247483819&idx=1&sn=7f1859c0a00248a4c658fa65f846f341&chksm=ebb4397fdcc3b06933816770b928355eb9119c4c80a1148b92a42dc3c08de5098fd6f278e61e#rd

    展开全文
  • 基于CNN的垃圾分类模型

    万次阅读 多人点赞 2018-01-10 15:44:21
    基于TensorFlow和Keras的垃圾分类模型 本篇博客主要介绍基于TensorFlow和Keras实现垃圾分类模型,目前是一篇占坑的博客,由于该项目目前用于参加比赛,因此暂时不能提供代码,感兴趣的可以私信我一起交流,识别...

    数据集代码下载地址:https://download.csdn.net/download/github_39611196/13103484

    前言

    识别结果如下所示:
    在这里插入图片描述

    国家大力推行垃圾分类可以实现环境保护,但是也对很多不熟悉垃圾分类的人造成了困扰,需要一种自动化的垃圾分类方法,以实现更加便捷的垃圾分类。
    在这里插入图片描述
    本文提出了基于卷积神经网络(Convolutional Neural Network,CNN)的垃圾分类方法,主要实现对6类生活垃圾进行分类,包括可回收垃圾(5类:硬纸板、铜制品、塑料瓶、玻璃瓶和废弃纸张)和不可回收垃圾。

    准备数据

    首先爬取图片数据,并从中每类挑选400张可用的图片,并将数据集按照9:1的比例划分为训练集和测试集。

    硬纸板
    在这里插入图片描述
    玻璃瓶
    在这里插入图片描述
    铜制品
    在这里插入图片描述
    废弃纸张
    在这里插入图片描述
    塑料瓶
    在这里插入图片描述
    不可回收垃圾
    在这里插入图片描述

    数据地址(个人整理的数据集,需要的可自行下载):

    https://www.kaggle.com/asdasdasasdas/garbage-classification

    搭建网络

    在准备完数据后,搭建6层CNN网络对数据集进行训练,最后进行测试,测试准确率为0.85。其中CNN网络包括4个卷积层、4个最大池化层和2个全连接层,前5层使用了ReLU激活函数,最后一层使用了SoftMax激活函数。

    训练和测试

    根据搭建的CNN网络对数据进行训练和测试。
    在这里插入图片描述

    完整代码

    prepare_image.py:用于对输入图像做预处理

    # encoding:utf-8
    '''
    对需要进行预测的图片进行预处理
    '''
    from keras.preprocessing.image import ImageDataGenerator
    from keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array
    from keras.applications.imagenet_utils import preprocess_input
    import numpy as np
    
    
    def prepare_image(img_path, model):
        # 加载图像
        img = load_img(img_path, target_size=(512, 384))        # x = np.array(img, dtype='float32')test
        # 图像预处理
        x = img_to_array(img)
        x = np.expand_dims(x, axis=0)
        x = preprocess_input(x)
        results = model.predict(x)
        print(results)
        return results
    

    train.py:用于训练垃圾分类模型

    # encoding:utf-8
    '''
    用于训练垃圾分类模型
    '''
    from keras.preprocessing.image import ImageDataGenerator
    from keras.models import Sequential
    from keras.layers import Conv2D, MaxPooling2D
    from keras.layers import Activation, Dropout, Flatten, Dense
    from keras.callbacks import ModelCheckpoint
    from keras import backend as K
    
    # dimensions of our images.
    img_width, img_height = 512, 384
    
    train_data_dir = 'data/train'
    validation_data_dir = 'data/validation'
    nb_train_samples = 2357
    nb_validation_samples = 170
    epochs = 30
    batch_size = 20
    
    if K.image_data_format() == 'channels_first':
        input_shape = (3, img_width, img_height)
    else:
        input_shape = (img_width, img_height, 3)
    
    model = Sequential()
    model.add(Conv2D(32, (3, 3), input_shape=input_shape))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    
    model.add(Conv2D(32, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    
    model.add(Conv2D(64, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    
    model.add(Flatten())
    model.add(Dense(64))
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    model.add(Dense(6))  # 6分类
    model.add(Activation('softmax'))  # 采用Softmax
    
    model.compile(loss='categorical_crossentropy',  # 多分类
                  optimizer='rmsprop',
                  metrics=['accuracy'])
    
    # this is the augmentation configuration we will use for training
    train_datagen = ImageDataGenerator(
        rescale=1. / 255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)
    
    # this is the augmentation configuration we will use for testing:
    # only rescaling
    test_datagen = ImageDataGenerator(rescale=1. / 255)
    
    train_generator = train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode='categorical')  # 多分类
    
    validation_generator = test_datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode='categorical')  # 多分类
    
    filepath="weights-improvement-{epoch:02d}-{val_acc:.2f}.h5"
    checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=0, save_best_only=False, save_weights_only=False, mode='auto', period=1)
    callbacks_list = [checkpoint]
    
    model.fit_generator(
        train_generator,
        steps_per_epoch=nb_train_samples // batch_size,
        epochs=epochs,
        callbacks=callbacks_list,
        validation_data=validation_generator,
        validation_steps=nb_validation_samples // batch_size)
    

    plot.py:用于显示图片预测结果

    # encoding:utf-8
    '''
    用于对预测结果图片进行显示
    '''
    import cv2
    import numpy as np
    
    # 根据预测结果显示对应的文字label
    classes_types = ['cardboard', 'glass', 'trash']
    
    
    def generate_result(result):
        for i in range(3):
            if(result[0][i] == 1):
                print(i)
                return classes_types[i]
    
    
    def show(img_path, results):
        # 对结果进行显示
        frame = cv2.imread(img_path)
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(frame, generate_result(results), (10, 140), font, 3, (255, 0, 0), 2, cv2.LINE_AA)
        cv2.imshow('img', frame)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    

    predict.py:用于对测试数据集进行测试

    # encoding:utf-8
    '''
    加载垃圾分类模型
    '''
    from keras.models import Sequential
    from keras.layers import Conv2D, MaxPooling2D
    from keras.layers import Activation, Dropout, Flatten, Dense
    from keras import backend as K
    
    
    def model():
        # dimensions of our images.
        img_width, img_height = 512, 384
        if K.image_data_format() == 'channels_first':
            input_shape = (3, img_width, img_height)
        else:
            input_shape = (img_width, img_height, 3)
    
        model = Sequential()
        model.add(Conv2D(32, (3, 3), input_shape=input_shape))
        model.add(Activation('relu'))
        model.add(MaxPooling2D(pool_size=(2, 2)))
    
        model.add(Conv2D(32, (3, 3)))
        model.add(Activation('relu'))
        model.add(MaxPooling2D(pool_size=(2, 2)))
    
        model.add(Conv2D(64, (3, 3)))
        model.add(Activation('relu'))
        model.add(MaxPooling2D(pool_size=(2, 2)))
    
        model.add(Flatten())
        model.add(Dense(64))
        model.add(Activation('relu'))
        model.add(Dropout(0.5))
        model.add(Dense(3))  # 3分类
        model.add(Activation('softmax'))  # 采用Softmax
    
        model.compile(loss='categorical_crossentropy',  # 多分类
                      optimizer='rmsprop',
                      metrics=['accuracy'])
    
        model.load_weights("weights.h5")
        return model
    

    main.py:对各个模块进行调用,测试图片并显示最终结果

    # encoding:utf-8
    '''
    调用各个模块实现对图片的测试和显示结果
    '''
    from plot import show
    import predict
    from prepare_image import prepare_image
    
    
    def detect(img_path):
        model = predict.model()
        results = prepare_image(img_path=img_path, model=model)
        show(img_path=img_path, results=results)
    
    if __name__ == '__main__':
    
        detect("test/15.jpg")
    

    使用步骤

    训练
    调用train.py对训练数据集进行训练,得到weights.h5权值文件。
    测试
    调用main.py进行测试。

    分类的准确率不是很高,主要存在两个问题

    第一个问题:数据集过于杂乱,在选择不可回收垃圾数据集时,只要不属于前五类而且为不可回收垃圾,都放到了不可回收垃圾类别下,无法很好的进行特征的学习。

    第二个问题是,模型只有6层,较为简单,学习能力不够强。

    改进思路

    针对第一个问题,可以对数据集进行清洗,以便更好地对特征进行学习;针对第二个问题,可以选择一些比较成熟的模型架构,如VGG16或者ResNet,通过迁移学习进行改进。

    写在最后

    集中回答大家几个问题:
    1、数据集和代码在哪下载?
    根据文中链接进行下载。
    2、找不到weights.h5配置文件?
    weights.h5配置文件需要通过train.py文件训练生成,即在运行main.py文件之前需要运行train.py文件
    3、代码报错问题?
    由于代码是三年前写的了,因此可能由于TensorFlow和Keras的版本,会出现报错,需要大家自行查找解决方案。

    展开全文
  • Java异常分类

    万次阅读 多人点赞 2012-11-27 15:46:48
    1 基本概念 java.lang.Throwable是所有异常的根 java.lang.Error是错误信息 java.lang.Exception是异常信息 ...一般分为Checked异常和Runtime异常,所有RuntimeException类及其子类的实例被称为Runtime异常,不...
  • 混淆矩阵就是分别统计分类模型归错类,归对类的观测值个数,然后把结果放在一个表里展示出来。这个表就是混淆矩阵。 数据分析与挖掘体系位置 混淆矩阵是评判模型结果的指标,属于模型评估的一部分。此外,混淆...
  • 分类下的ROC曲线和AUC

    万次阅读 多人点赞 2018-03-05 17:37:20
    本文主要介绍一下多分类下的ROC曲线绘制和AUC计算,并以鸢尾花数据为例,简单用python进行一下说明。如果对ROC和AUC二分类下的概念不是很了解,可以先参考下这篇文章:...
  • 分类问题的评估(二分类&多分类

    万次阅读 2018-06-02 09:19:10
    对于二分类问题,可将样例根据其真实类别和分类器预测类别划分为: 真正例(True Positive,TP):真实类别为正例,预测类别为正例。 假正例(False Positive,FP):真实类别为负例,预测类别为正例。 假负例...
  • BERT模型实战之多文本分类(附源码)

    万次阅读 多人点赞 2019-03-21 11:00:36
    写在前面 BERT模型也出来很久了,之前看了论文学习...这篇文章的内容还是以比较简单文本分类任务入手,数据集选取的是新浪新闻cnews,包括了[‘体育’, ‘财经’, ‘房产’, ‘家居’, ‘教育’, ‘科技’, ‘时尚’...
  • CSDN分类专栏操作演示

    万次阅读 多人点赞 2019-08-21 12:06:53
    博客专栏与文章分类合并为分类专栏,同时新增二级分类功能。新创建的分类专栏不能超过50个(包含二级),标签不能超过3个。 之前创建超过数量的分类专栏不会自动合并,暂时先保持不变。 新分类专栏管理页面如下,...
  • 这篇文章将详细讲解图像分类知识,包括常见的图像分类算法,并介绍Python环境下的贝叶斯图像分类算法、基于KNN算法的图像分类和基于神经网络算法的图像分类等案例。万字长文整理,希望对您有所帮助。 同时,该部分...
  • Linux常用命令分类整理

    万次阅读 2020-11-12 10:09:40
    整理linux的一些基础命令 1. linux目录与文件 1.1 关于目录与文件的操作方式 1.2 符号链接 2 存储操作 2.1一般存储操作 ... 4.... 4.2 更改文件得权
  • 分类及多标签分类算法

    万次阅读 2019-04-08 19:49:55
    一、单标签多分类 1、单标签二分类算法原理 1、单标签二分类这种问题是我们最常见的算法问题,主要是指label 标签的取值只有两种,并且算法中只有一个需要预测的label标签; 直白来讲就是每个实例的可能类别...
  • 深度学习实战之垃圾分类

    万次阅读 多人点赞 2019-08-31 21:00:01
    垃圾分类,指按一定规定或标准将垃圾分类储存、分类投放和分类搬运,从而转变成公共资源的一系列活动的总称。分类的目的是提高垃圾的资源价值和经济价值,力争物尽其用;然而我们在日常生活中认为对垃圾分类还是有些...
  • 四个基本概念 TP、True Positive 真阳性:预测为正,实际也为正 FP、False Positive 假阳性:预测为正,实际为负 FN、False Negative 假阴性:预测与...以分类问题为例:(word公式为什么粘不过来??头疼。)...
  • 数据挖掘算法——常用分类算法总结

    万次阅读 多人点赞 2019-06-17 10:55:22
    常用分类算法总结分类算法总结NBC算法LR算法SVM算法ID3算法C4.5 算法C5.0算法KNN 算法ANN 算法 分类算法总结 分类是在一群已经知道类别标号的样本中,训练一种分类器,让其能够对某种未知的样本进行分类分类算法...
  • 图像分类

    万次阅读 多人点赞 2018-01-21 15:31:47
    图像物体分类与检测算法综述 转自《计算机学报》 目录 图像物体分类与检测算法综述 目录 图像物体分类与检测概述 物体分类与检测的难点与挑战 物体分类与检测数据库 物体分类与检测发展历程 ...
  • 高光谱图像分类(三)分类流程

    万次阅读 多人点赞 2016-10-18 16:33:35
    如何利用稀疏表示进行高光谱图像分类呢?前面我们已经了解了高光谱图像分类的一些基本概念,那这篇文章当中将讲解高光谱图像分类具体的流程是怎么样的。以下是高光谱图像分类的具体详细步骤: 1.导入indian_pines高...
  • opencv3.3版本训练自己的物体分类

    万次阅读 多人点赞 2018-01-09 11:04:22
    Opencv训练自己分类器 注:此文是我整理了网上的各方资料汇集而成,由于在实践中遇到了很多坑,所以把自己的成功训练的经验写下来做个笔记给大家做个参考,本文所使用 opencv版本为3.3 下载链接:...
  • PyCaret 分类

    千次阅读 2020-04-24 17:55:46
    PyCaret 分类
  • 分类

    万次阅读 多人点赞 2018-09-21 21:23:10
    分类器的作用:常规任务是利用给定的类别、已知的训练数据来学习分类规则和分类器,然后对未知数据进行分类(或预测)。逻辑回归(logistics)、SVM等常用于解决二分类问题,对于多分类问题(multi-class ...
  • 文本分类——常见分类模型

    万次阅读 多人点赞 2018-11-06 17:37:56
      文本分类方法模型主要分为两个大类,一类是基于规则的分类模型;另一类是基于概率统计的模型。 基于规则的模型   基于规则的分类模型相对简单,易于实现。它在特定领域的分类往往能够取得较好的效果。相对于...
  • 对于分类器,或者说分类算法,评价指标主要有precision,recall,F-score1,以及即将要讨论的ROC和AUC。本文通过对这些指标的原理做一个简单的介绍,然后用python分别实现二分类和多分类的ROC曲线。 1 基本概念...
  • 本文为原创文章:http://blog.csdn.net/programmer_wei/article/details/52072939Logistic Regression(逻辑回归)是机器学习中一个非常非常常见的模型,在实际生产环境中也常常被使用,是一种经典的分类模型(不是...
  • 详解sigmoid与softmax, 多分类及多标签分类

    万次阅读 多人点赞 2018-09-19 21:35:50
    详解sigmoid与softmax, 多分类及多标签分类激活函数介绍sigmoid激活函数sigmoid激活函数的性质sigmoid激活函数的使用 激活函数介绍 对于熟悉机器学习或神经网络的读者来说,sigmoid与softmax两个激活函数并不陌生,...
  • 分类和多分类问题的评价指标总结

    万次阅读 多人点赞 2019-07-09 18:51:55
    分类评价指标 准确率(Accuracy) 评价分类问题的性能指标一般是分类准确率,即对于给定的数据,分类正确的样本数占总样本数的比例。 注意:准确率这一指标在Unbalanced数据集上的表现很差,因为如果我们的正负...
  • 该案例是实际开发中运用,java递归查询分类分类下所有子分类。代码走起:1.jsp页面布局样式这里不再介绍,js业务逻辑展示分类树形结构如下:/** * 商品分类操作 */ /** * 初始化 */ $(function(){ //加载树 ...
  • SVM本身是一个二值分类器  SVM算法最初是为二值分类问题设计的,当处理多类问题时,就需要构造合适的多类分类器。  目前,构造SVM多类分类器的方法主要有两类  (1)直接法,直接在目标函数上进行修改,将多个...
  • 深度学习-Pytorch项目实战-垃圾分类

    万人学习 2019-12-08 11:15:53
    Pytorch项目实战 垃圾分类 课程从实战的角度出发,基于真实数据集与实际业务需求,结合当下最新话题-垃圾分类问题为实际业务出发点,介绍最前沿的深度学习解决方案。     从0到1讲解如何场景业务...
  • 快速搭建垃圾分类模型

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 644,539
精华内容 257,815
关键字:

分类