APP下载
报价宝  ›  科技  › 

初学者的机器学习入门实战教程

报价宝 来源:baojiabao.com 发布时间:2019-10-27 14:58:00 10月27日更新
报价宝综合消息初学者的机器学习入门实战教程

原文连结:https://www.pyimagesearch.com/2019/01/14/machine-learning-in-python/

作者:Adrian Rosebrock

这是一篇手把手教你使用 Python 实现机器学习算法,并在数值型资料和影象资料集上执行模型的入门教程,当你看完本文后,你应当可以开始你的机器学习之旅了!

本教程会采用下述两个库来实现机器学习算法:

scikit-learnKeras此外,你还将学习到:

评估你的问题准备资料(原始资料、特征提取、特征工程等等)检查各种机器学习算法检验实验结果深入了解效能最好的算法在本文会用到的机器学习算法包括:

KNN朴素贝叶斯逻辑回归SVM决策树随机森林感知机多层前向网络CNNs安装必备的 Python 机器学习库

开始本教程前,需要先确保安装了一下的 Python 库:

Numpy:用于 Python 的数值处理PIL:一个简单的影象处理库scikit-learn:包含多种机器学习算法(注意需要采用 0.2+ 的版本,所以下方安装命令需要加上 --upgrade )Kears 和 TensorFlow:用于深度学习。本教程可以仅采用 CPU 版本的 TensorFlowOpenCV:本教程并不会采用到 OpenCV,但 imutils 库依赖它;imutils :作者的影象处理/计算机视觉库安装命令如下,推荐采用虚拟环境(比如利用 anaconda 建立一个新的环境):

$ pip install numpy

$ pip install pillow

$ pip install --upgrade scikit-learn

$ pip install tensorflow # or tensorflow-gpu

$ pip install keras

$ pip install opencv-contrib-python

$ pip install --upgrade imutils

资料集

本教程会用到两个资料集来帮助更好的了解每个机器学习算法的效能。

第一个资料集是 Iris(鸢尾花) 资料集。这个资料集的地位,相当于你刚开始学习一门程式语言时,敲下的 “Hello,World!”

这个资料集是一个数值型的资料,如下图所示,其实就是一个表格资料,每一行代表一个样本,然后每一列就是不同的属性。这个资料集主要是收集了三种不同的鸢尾花的资料,分别为:

Iris SetosaIris VersicolorIris Virginica对应图中最后一列 Class label,然后还有四种属性,分别是:

Sepal length--萼片长度Sepal width--萼片宽度Petal length--花瓣长度Petal width--花瓣宽度

这个资料集可能是最简单的机器学习资料集之一了,通常是用于教导程序员和工程师的机器学习和模式识别基础的资料集。

对于该资料集,我们的目标就是根据给定的四个属性,训练一个机器学习模型来正确分类每个样本的类别。

需要注意的是,其中有一个类别和另外两个类别是线性可分的,但这两个类别之间却并非线性可分,所以我们需要采用一个非线性模型来对它们进行分类。当然了,在现实生活中,采用非线性模型的机器学习算法是非常常见的。

第二个资料集是一个三场景的影象资料集。这是帮助初学者学习如何处理影象资料,并且哪种算法在这两种资料集上效能最优。

下图是这个三场景资料集的部分图片例子,它包括森林、高速公路和海岸线三种场景,总共是 948 张图片,每个类别的具体图片数量如下:

Coast: 360Forest: 328Highway: 260

这个三场景资料集是取样于一个八场景资料集中,作者是 Oliva 和 Torralba 的 2001 年的一篇论文,Modeling the shape of the scene: a holistic representation of the spatial envelope: http://people.csail.mit.edu/torralba/code/spatialenvelope/

利用 Python 实现机器学习的步骤

无论什么时候实现机器学习算法,推荐采用如下流程来开始:

评估你的问题准备资料(原始资料、特征提取、特征工程等等)检查各种机器学习算法检验实验结果深入了解效能最好的算法这个流程会随着你机器学习方面的经验的积累而改善和优化,但对于初学者,这是我建议入门机器学习时采用的流程。

所以,现在开始吧!第一步,就是评估我们的问题,问一下自己:

资料集是哪种型别?数值型,类别型还是影象?模型的最终目标是什么?如何定义和衡量“准确率”呢?以目前自身的机器学习知识来看,哪些算法在处理这类问题上效果很好?最后一个问题非常重要,随着你使用 Python 实现机器学习的次数的增加,你也会随之获得更多的经验。根据之前的经验,你可能知道有一种算法的效能还不错。

因此,接着就是准备资料,也就是资料预处理以及特征工程了。

一般来说,这一步,包括了从硬盘中载入资料,检查资料,然后决定是否需要做特征提取或者特征工程。

特征提取就是应用某种算法通过某种方式来量化资料的过程。比如,对于影象资料,我们可以采用计算直方图的方法来统计影象中画素强度的分布,通过这种方式,我们就得到描述影象颜色的特征。

而特征工程则是将原始输入资料转换成一个更好描述潜在问题的特征表示的过程。当然特征工程是一项更先进的技术,这里建议在对机器学习有了一定经验后再采用这种方法处理资料。

第三步,就是检查各种机器学习算法,也就是实现一系列机器学习算法,并应用在资料集上。

这里,你的工具箱应当包含以下几种不同型别的机器学习算法:

线性模型(比如,逻辑回归,线性 SVM)非线性模型(比如 RBF SVM,梯度下降分类器)树和基于整合的模型(比如 决策树和随机森林)神经网络(比如 多层感知机,卷积神经网络)应当选择比较鲁棒(稳定)的一系列机器学习模型来评估问题,因为我们的目标就是判断哪种算法在当前问题的效能很好,而哪些算法很糟糕。

决定好要采用的模型后,接下来就是训练模型并在资料集上测试,观察每个模型在资料集上的效能结果。

在多次实验后,你可能就是有一种“第六感”,知道哪种算法更适用于哪种资料集。

比如,你会发现:

对于有很多特征的资料集,随机森林算法的效果很不错;而逻辑回归算法可以很好处理高维度的稀疏资料;对于影象资料,CNNs 的效果非常好。而以上的经验获得,当然就需要你多动手,多进行实战来深入了解不同的机器学习算法了!

开始动手吧!

接下来就开始敲程式码来实现机器学习算法,并在上述两个资料集上进行测试。本教程的程式码档案目录如下,包含四份程式码档案和一个 3scenes资料夹,该资料夹就是三场景资料集,而 Iris 资料集直接采用 scikit-learn 库载入即可。

├── 3scenes

│ ├── coast [360 entries]

│ ├── forest [328 entries]

│ └── highway [260 entries]

├── classify_iris.py

├── classify_images.py

├── nn_iris.py

└── basic_cnn.py

程式码和资料集档案可以在公众号后台,也就是公众号会话界面回复 ‘py_ml’获取!

首先是实现 classify_iris.py,这份程式码是采用机器学习算法来对 Iris 资料集进行分类。

首先汇入需要的库:

from sklearn.neighbors import KNeighborsClassifier

from sklearn.naive_bayes import GaussianNB

from sklearn.linear_model import LogisticRegression

from sklearn.svm import SVC

from sklearn.tree import DecisionTreeClassifier

from sklearn.ensemble import RandomForestClassifier

from sklearn.neural_network import MLPClassifier

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

from sklearn.datasets import load_iris

import argparse

# 设定引数

ap = argparse.ArgumentParser()

ap.add_argument("-m", "--model", type=str, default="knn", help="type of python machine learning model to use")

args = vars(ap.parse_args())

# 定义一个储存模型的字典,根据 key 来选择载入哪个模型

models = {

"knn": KNeighborsClassifier(n_neighbors=1),

"naive_bayes": GaussianNB(),

"logit": LogisticRegression(solver="lbfgs", multi_class="auto"),

"svm": SVC(kernel="rbf", gamma="auto"),

"decision_tree": DecisionTreeClassifier(),

"random_forest": RandomForestClassifier(n_estimators=100),

"mlp": MLPClassifier()

}

可以看到在 sklearn 库中就集成了我们将要实现的几种机器学习算法的程式码,包括:

KNN朴素贝叶斯逻辑回归SVM决策树随机森林感知机我们直接呼叫 sklearn 中相应的函式来实现对应的算法即可,比如对于 knn 算法,直接呼叫 sklearn.neighbors 中的 KNeighborsClassifier() 即可,只需要设定引数 n_neighbors ,即最近邻的个数。

这里直接用一个 models 的字典来储存不同模型的初始化,然后根据引数 --model 来呼叫对应的模型,比如命令输入 python classify_irs.py --model knn 就是呼叫 knn 算法模型。

接着就是载入资料部分:

print("[INFO] loading data...")

dataset = load_iris()

(trainX, testX, trainY, testY) = train_test_split(dataset.data,

dataset.target, random_state=3, test_size=0.25)

这里直接呼叫 sklearn.datasets 中的 load_iris() 载入资料,然后采用 train_test_split 来划分训练集和资料集,这里是 75% 资料作为训练集,25% 作为测试集。

最后就是训练模型和预测部分:

# 训练模型

print("[INFO] using '{}' model".format(args["model"]))

model = models[args["model"]]

model.fit(trainX, trainY)

# 预测并输出一份分类结果报告

print("[INFO] evaluating")

predictions = model.predict(testX)

print(classification_report(testY, predictions, target_names=dataset.target_names))

完整版程式码程式码如下:

from sklearn.neighbors import KNeighborsClassifier

from sklearn.naive_bayes import GaussianNB

from sklearn.linear_model import LogisticRegression

from sklearn.svm import SVC

from sklearn.tree import DecisionTreeClassifier

from sklearn.ensemble import RandomForestClassifier

from sklearn.neural_network import MLPClassifier

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

from sklearn.datasets import load_iris

import argparse

# 设定引数

ap = argparse.ArgumentParser()

ap.add_argument("-m", "--model", type=str, default="knn", help="type of python machine learning model to use")

args = vars(ap.parse_args())

# 定义一个储存模型的字典,根据 key 来选择载入哪个模型

models = {

"knn": KNeighborsClassifier(n_neighbors=1),

"naive_bayes": GaussianNB(),

"logit": LogisticRegression(solver="lbfgs", multi_class="auto"),

"svm": SVC(kernel="rbf", gamma="auto"),

"decision_tree": DecisionTreeClassifier(),

"random_forest": RandomForestClassifier(n_estimators=100),

"mlp": MLPClassifier()

}

# 载入 Iris 资料集,然后进行训练集和测试集的划分,75%资料作为训练集,其余25%作为测试集

print("[INFO] loading data...")

dataset = load_iris()

(trainX, testX, trainY, testY) = train_test_split(dataset.data, dataset.target, random_state=3, test_size=0.25)

# 训练模型

print("[INFO] using '{}' model".format(args["model"]))

model = models[args["model"]]

model.fit(trainX, trainY)

# 预测并输出一份分类结果报告

print("[INFO] evaluating")

predictions = model.predict(testX)

print(classification_report(testY, predictions, target_names=dataset.target_names))

接着就是采用三场景影象资料集的分类预测程式码 classify_images.py ,跟 classify_iris.py 的程式码其实是比较相似的,首先汇入库部分,增加以下几行程式码:

from sklearn.preprocessing import LabelEncoder

from PIL import Image

from imutils import paths

import numpy as np

import os

其中 LabelEncoder 是为了将标签从字串编码为整型,然后其余几项都是处理影象相关。

对于影象资料,如果直接采用原始画素资讯输入模型中,大部分的机器学习算法效果都很不理想,所以这里采用特征提取方法,主要是统计影象颜色通道的均值和标准差资讯,总共是 RGB 3个通道,每个通道各计算均值和标准差,然后结合在一起,得到一个六维的特征,函式如下所示:

def extract_color_stats(image):

'''

将图片分成 RGB 三通道,然后分别计算每个通道的均值和标准差,然后返回

:param image:

:return:

'''

(R, G, B) = image.split()

features = [np.mean(R), np.mean(G), np.mean(B), np.std(R), np.std(G), np.std(B)]

return features

然后同样会定义一个 models 字典,程式码一样,这里就不贴出来了,然后影象载入部分的程式码如下:

# 载入资料并提取特征

print("[INFO] extracting image features...")

imagePaths = paths.list_images(args['dataset'])

data = []

labels = []

# 循环遍历所有的图片资料

for imagePath in imagePaths:

# 载入图片,然后计算图片的颜色通道统计资讯

image = Image.open(imagePath)

features = extract_color_stats(image)

data.append(features)

# 储存图片的标签资讯

label = imagePath.split(os.path.sep)[-2]

labels.append(label)

# 对标签进行编码,从字串变为整数型别

le = LabelEncoder()

labels = le.fit_transform(labels)

# 进行训练集和测试集的划分,75%资料作为训练集,其余25%作为测试集

(trainX, testX, trainY, testY) = train_test_split(data, labels, test_size=0.25)

上述程式码就完成从硬盘中载入图片的路径资讯,然后依次遍历,读取图片,提取特征,提取标签资讯,储存特征和标签资讯,接着编码标签,然后就是划分训练集和测试集。

接着是相同的训练模型和预测的程式码,同样没有任何改变,这里就不列举出来了。

完整版如下:

from sklearn.neighbors import KNeighborsClassifier

from sklearn.naive_bayes import GaussianNB

from sklearn.linear_model import LogisticRegression

from sklearn.svm import SVC

from sklearn.tree import DecisionTreeClassifier

from sklearn.ensemble import RandomForestClassifier

from sklearn.neural_network import MLPClassifier

from sklearn.preprocessing import LabelEncoder

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

from PIL import Image

from imutils import paths

import numpy as np

import argparse

import os

def extract_color_stats(image):

'''

将图片分成 RGB 三通道,然后分别计算每个通道的均值和标准差,然后返回

:param image:

:return:

'''

(R, G, B) = image.split()

features = [np.mean(R), np.mean(G), np.mean(B), np.std(R), np.std(G), np.std(B)]

return features

# 设定引数

ap = argparse.ArgumentParser()

ap.add_argument("-d", "--dataset", type=str, default="3scenes",

help="path to directory containing the '3scenes' dataset")

ap.add_argument("-m", "--model", type=str, default="knn",

help="type of python machine learning model to use")

args = vars(ap.parse_args())

# 定义一个储存模型的字典,根据 key 来选择载入哪个模型

models = {

"knn": KNeighborsClassifier(n_neighbors=1),

"naive_bayes": GaussianNB(),

"logit": LogisticRegression(solver="lbfgs", multi_class="auto"),

"svm": SVC(kernel="rbf", gamma="auto"),

"decision_tree": DecisionTreeClassifier(),

"random_forest": RandomForestClassifier(n_estimators=100),

"mlp": MLPClassifier()

}

# 载入资料并提取特征

print("[INFO] extracting image features...")

imagePaths = paths.list_images(args['dataset'])

data = []

labels = []

# 循环遍历所有的图片资料

for imagePath in imagePaths:

# 载入图片,然后计算图片的颜色通道统计资讯

image = Image.open(imagePath)

features = extract_color_stats(image)

data.append(features)

# 储存图片的标签资讯

label = imagePath.split(os.path.sep)[-2]

labels.append(label)

# 对标签进行编码,从字串变为整数型别

le = LabelEncoder()

labels = le.fit_transform(labels)

# 进行训练集和测试集的划分,75%资料作为训练集,其余25%作为测试集

(trainX, testX, trainY, testY) = train_test_split(data, labels, random_state=3, test_size=0.25)

# print('trainX numbers={}, testX numbers={}'.format(len(trainX), len(testX)))

# 训练模型

print("[INFO] using '{}' model".format(args["model"]))

model = models[args["model"]]

model.fit(trainX, trainY)

# 预测并输出分类结果报告

print("[INFO] evaluating...")

predictions = model.predict(testX)

print(classification_report(testY, predictions, target_names=le.classes_))

完成这两份程式码后,我们就可以开始执行下程式码,对比不同算法在两个资料集上的效能。

因为篇幅的原因,这里我会省略原文对每个算法的介绍.

KNN

这里我们先执行下 classify_irs,呼叫预设的模型 knn ,看下 KNN 在 Iris资料集上的实验结果,如下所示:

其中主要是给出了对每个类别的精确率、召回率、F1 以及该类别测试集数量,即分别对应 precision, recall, f1-score, support 。根据最后一行第一列,可以看到 KNN 取得 95% 的准确率。

接着是在三场景图片资料集上的实验结果:

这里 KNN 取得 72% 的准确率。

(ps:实际上,执行这个算法,不同次数会有不同的结果,原文作者给出的是 75%,其主要原因是因为在划分训练集和测试集的时候,程式码没有设定引数 random_state,这导致每次执行划分的训练集和测试集的图片都是不同的,所以执行结果也会不相同!)

朴素贝叶斯

接着是朴素贝叶斯算法,分别测试两个资料集,结果如下:

同样,朴素贝叶斯在 Iris 上有 98% 的准确率,但是在影象资料集上仅有 63% 的准确率。

那么,我们是否可以说明 KNN 算法比朴素贝叶斯好呢?

当然是不可以的,上述结果只能说明在三场景影象资料集上,KNN 算法优于朴素贝叶斯算法。

实际上,每种算法都有各自的优缺点和适用场景,不能一概而论地说某种算法任何时候都优于另一种算法,这需要具体问题具体分析。

逻辑回归

接着是逻辑回归算法,分别测试两个资料集,结果如下:

同样,逻辑回归在 Iris 上有 98% 的准确率,但是在影象资料集上仅有 77% 的准确率(对比原文作者的逻辑回归准确率是 69%)

支援向量机 SVM

接着是 SVM 算法,分别测试两个资料集,结果如下:

同样,SVM 在 Iris 上有 98% 的准确率,但是在影象资料集上仅有 76% 的准确率(对比原文作者的准确率是 83%,主要是发现类别 coast 差别有些大)

决策树

接着是决策树算法,分别测试两个资料集,结果如下:

同样,决策树在 Iris 上有 98% 的准确率,但是在影象资料集上仅有 71% 的准确率(对比原文作者的决策树准确率是 74%)

随机森林

接着是随机森林算法,分别测试两个资料集,结果如下:

同样,随机森林在 Iris 上有 96% 的准确率,但是在影象资料集上仅有 77% 的准确率(对比原文作者的决策树准确率是 84%)

注意了,一般如果决策树算法的效果还不错的话,随机森林算法应该也会取得不错甚至更好的结果,这是因为随机森林实际上就是多棵决策树通过整合学习方法组合在一起进行分类预测。

多层感知机

最后是多层感知机算法,分别测试两个资料集,结果如下:

同样,多层感知机在 Iris 上有 98% 的准确率,但是在影象资料集上仅有 79% 的准确率(对比原文作者的决策树准确率是 81%).

深度学习以及深度神经网络

神经网络

最后是实现深度学习的算法,也就是 nn_iris.py 和 basic_cnn.py 这两份程式码。

(这里需要注意 TensorFlow 和 Keras 的版本问题,我采用的是 TF=1.2 和 Keras=2.1.5)

首先是 nn_iris.py 的实现,同样首先是汇入库和资料的处理:

from keras.models import Sequential

from keras.layers.core import Dense

from keras.optimizers import SGD

from sklearn.preprocessing import LabelBinarizer

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

from sklearn.datasets import load_iris

# 载入 Iris 资料集,然后进行训练集和测试集的划分,75%资料作为训练集,其余25%作为测试集

print("[INFO] loading data...")

dataset = load_iris()

(trainX, testX, trainY, testY) = train_test_split(dataset.data,

dataset.target, test_size=0.25)

# 将标签进行 one-hot 编码

lb = LabelBinarizer()

trainY = lb.fit_transform(trainY)

testY = lb.transform(testY)

这里我们将采用 Keras 来实现神经网络,然后这里需要将标签进行 one-hot 编码,即独热编码。

接着就是搭建网络模型的结构和训练、预测程式码:

# 利用 Keras 定义网络模型

model = Sequential()

model.add(Dense(3, input_shape=(4,), activation="sigmoid"))

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

model.add(Dense(3, activation="softmax"))

# 采用梯度下降训练模型

print('[INFO] training network...')

opt = SGD(lr=0.1, momentum=0.9, decay=0.1 / 250)

model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=["accuracy"])

H = model.fit(trainX, trainY, validation_data=(testX, testY), epochs=250, batch_size=16)

# 预测

print('[INFO] evaluating network...')

predictions = model.predict(testX, batch_size=16)

print(classification_report(testY.argmax(axis=1), predictions.argmax(axis=1), target_names=dataset.target_names))

这里是定义了 3 层全连线层的神经网络,前两层采用 Sigmoid 启用函式,然后最后一层是输出层,所以采用 softmax 将输出变成概率值。接着就是定义了使用 SGD 的优化算法,损失函式是 categorical_crossentropy,迭代次数是 250 次,batch_size 是 16。

完整版如下:

from keras.models import Sequential

from keras.layers.core import Dense

from keras.optimizers import SGD

from sklearn.preprocessing import LabelBinarizer

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

from sklearn.datasets import load_iris

# 载入 Iris 资料集,然后进行训练集和测试集的划分,75%资料作为训练集,其余25%作为测试集

print("[INFO] loading data...")

dataset = load_iris()

(trainX, testX, trainY, testY) = train_test_split(dataset.data,

dataset.target, test_size=0.25)

# 将标签进行 one-hot 编码

lb = LabelBinarizer()

trainY = lb.fit_transform(trainY)

testY = lb.transform(testY)

# 利用 Keras 定义网络模型

model = Sequential()

model.add(Dense(3, input_shape=(4,), activation="sigmoid"))

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

model.add(Dense(3, activation="softmax"))

# 采用梯度下降训练模型

print('[INFO] training network...')

opt = SGD(lr=0.1, momentum=0.9, decay=0.1 / 250)

model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=["accuracy"])

H = model.fit(trainX, trainY, validation_data=(testX, testY), epochs=250, batch_size=16)

# 预测

print('[INFO] evaluating network...')

predictions = model.predict(testX, batch_size=16)

print(classification_report(testY.argmax(axis=1),

predictions.argmax(axis=1), target_names=dataset.target_names))

直接执行命令 python nn_iris.py, 输出的结果如下:

这里得到的是 100% 的准确率,和原文的一样。当然实际上原文给出的结果如下图所示,可以看到其实类别数量上是不相同的。

CNN

最后就是实现 basic_cnn.py 这份程式码了。

同样首先是汇入必须的库函式:

from keras.models import Sequential

from keras.layers.convolutional import Conv2D

from keras.layers.convolutional import MaxPooling2D

from keras.layers.core import Activation

from keras.layers.core import Flatten

from keras.layers.core import Dense

from keras.optimizers import Adam

from sklearn.preprocessing import LabelBinarizer

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

from PIL import Image

from imutils import paths

import numpy as np

import argparse

import os

# 配置引数

ap = argparse.ArgumentParser()

ap.add_argument("-d", "--dataset", type=str, default="3scenes",

help="path to directory containing the '3scenes' dataset")

args = vars(ap.parse_args())

同样是要汇入 Keras 来建立 CNN 的网络模型,另外因为是处理影象资料,所以 PIL、imutils 也是要汇入的。

然后是载入资料和划分训练集和测试集,对于载入资料,这里直接采用原始影象画素资料,只需要对影象资料做统一尺寸的调整,这里是统一调整为 32×32,并做归一化到 [0,1] 的范围。

# 载入资料并提取特征

print("[INFO] extracting image features...")

imagePaths = paths.list_images(args['dataset'])

data = []

labels = []

# 循环遍历所有的图片资料

for imagePath in imagePaths:

# 载入图片,然后调整成 32×32 大小,并做归一化到 [0,1]

image = Image.open(imagePath)

image = np.array(image.resize((32, 32))) / 255.0

data.append(image)

# 储存图片的标签资讯

label = imagePath.split(os.path.sep)[-2]

labels.append(label)

# 对标签编码,从字串变为整型

lb = LabelBinarizer()

labels = lb.fit_transform(labels)

# 划分训练集和测试集

(trainX, testX, trainY, testY) = train_test_split(np.array(data), np.array(labels), test_size=0.25)

接着定义了一个 4 层的 CNN 网络结构,包含 3 层卷积层和最后一层输出层,优化算法采用的是 Adam 而不是 SGD 。程式码如下所示:

# 定义 CNN 网络模型结构

model = Sequential()

model.add(Conv2D(8, (3, 3), padding="same", input_shape=(32, 32, 3)))

model.add(Activation("relu"))

model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

model.add(Conv2D(16, (3, 3), padding="same"))

model.add(Activation("relu"))

model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

model.add(Conv2D(32, (3, 3), padding="same"))

model.add(Activation("relu"))

model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

model.add(Flatten())

model.add(Dense(3))

model.add(Activation("softmax"))

# 训练模型

print("[INFO] training network...")

opt = Adam(lr=1e-3, decay=1e-3 / 50)

model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])

H = model.fit(trainX, trainY, validation_data=(testX, testY),

epochs=50, batch_size=32)

# 预测

print("[INFO] evaluating network...")

predictions = model.predict(testX, batch_size=32)

print(classification_report(testY.argmax(axis=1),

predictions.argmax(axis=1), target_names=lb.classes_))

完整版如下:

from keras.models import Sequential

from keras.layers.convolutional import Conv2D

from keras.layers.convolutional import MaxPooling2D

from keras.layers.core import Activation

from keras.layers.core import Flatten

from keras.layers.core import Dense

from keras.optimizers import Adam

from sklearn.preprocessing import LabelBinarizer

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

from PIL import Image

from imutils import paths

import numpy as np

import argparse

import os

# 配置引数

ap = argparse.ArgumentParser()

ap.add_argument("-d", "--dataset", type=str, default="3scenes",

help="path to directory containing the '3scenes' dataset")

args = vars(ap.parse_args())

# 载入资料并提取特征

print("[INFO] extracting image features...")

imagePaths = paths.list_images(args['dataset'])

data = []

labels = []

# 循环遍历所有的图片资料

for imagePath in imagePaths:

# 载入图片,然后调整成 32×32 大小,并做归一化到 [0,1]

image = Image.open(imagePath)

image = np.array(image.resize((32, 32))) / 255.0

data.append(image)

# 储存图片的标签资讯

label = imagePath.split(os.path.sep)[-2]

labels.append(label)

# 对标签编码,从字串变为整型

lb = LabelBinarizer()

labels = lb.fit_transform(labels)

# 划分训练集和测试集

(trainX, testX, trainY, testY) = train_test_split(np.array(data), np.array(labels), test_size=0.25)

# 定义 CNN 网络模型结构

model = Sequential()

model.add(Conv2D(8, (3, 3), padding="same", input_shape=(32, 32, 3)))

model.add(Activation("relu"))

model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

model.add(Conv2D(16, (3, 3), padding="same"))

model.add(Activation("relu"))

model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

model.add(Conv2D(32, (3, 3), padding="same"))

model.add(Activation("relu"))

model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

model.add(Flatten())

model.add(Dense(3))

model.add(Activation("softmax"))

# 训练模型

print("[INFO] training network...")

opt = Adam(lr=1e-3, decay=1e-3 / 50)

model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])

H = model.fit(trainX, trainY, validation_data=(testX, testY),

epochs=50, batch_size=32)

# 预测

print("[INFO] evaluating network...")

predictions = model.predict(testX, batch_size=32)

print(classification_report(testY.argmax(axis=1),

predictions.argmax(axis=1), target_names=lb.classes_))

执行命令 python basic_cnn.py, 输出结果如下:

CNN 的准确率是达到 90%,它是优于之前的几种机器学习算法的结果。

小结

最后,这仅仅是一份对机器学习完全是初学者的教程,其实就是简单呼叫现有的库来实现对应的机器学习算法,让初学者简单感受下如何使用机器学习算法,正如同在学习程式语言的时候,对著书本的程式码例子敲起来,然后执行程式码,看看自己写出来的程式的执行结果。

通过这份简单的入门教程,你应该明白的是:

没有任何一种算法是完美的,可以完全适用所有的场景,即便是目前很热门的深度学习方法,也存在它的局限性,所以应该具体问题具体分析!记住开头推荐的 5 步机器学习操作流程,这里再次复习一遍:评估你的问题准备资料(原始资料、特征提取、特征工程等等)检查各种机器学习算法检验实验结果深入了解效能最好的算法最后一点,是我执行算法结果,和原文作者的结果会不相同,这实际上就是每次取样资料,划分训练集和测试集不相同的原因!这其实也说明了资料非常重要,对于机器学习来说,好的资料很重要!接着,根据这份教程,你可以继续进一步了解每种机器学习算法,了解每种算法的基本原理和实现,尝试自己手动实现,而不是简单呼叫现有的库,这样更加能加深印象,这里推荐《机器学习实战》,经典的机器学习算法都有介绍,并且都会带你一步步实现算法!

最后,极力推荐大家去阅读下原文作者的部落格,原文作者也是一个大神,他的部落格地址如下:

https://www.pyimagesearch.com/

他的部落格包含了 Opencv、Python、机器学习和深度学习方面的教程和文章,而且作者喜欢通过实战学习,所以很多文章都是通过一些实战练习来学习某个知识点或者某个算法,正如同本文通过实现这几种常见的机器学习算法在两个不同型别资料集上的实战来带领初学者入门机器学习。

文章标签: 报价宝 降噪耳机价格 耳机价格 红米手机价格 华为手机价格 小米手机价格 电视机价格 笔记本电脑价格 笔记本价格 汽车价格 报价宝 笔记本价格 笔记本电脑价格 耳机价格 降噪耳机价格