原文连接:www.pyimagesearch.com/2019/01/14/…python
做者:Adrian Rosebrockgit
这是一篇手把手教你使用 Python 实现机器学习算法,并在数值型数据和图像数据集上运行模型的入门教程,当你看完本文后,你应当能够开始你的机器学习之旅了!程序员
本教程会采用下述两个库来实现机器学习算法:算法
此外,你还将学习到:shell
在本文会用到的机器学习算法包括:编程
开始本教程前,须要先确保安装了一下的 Python 库:bash
--upgrade
)安装命令以下,推荐采用虚拟环境(好比利用 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!”app
这个数据集是一个数值型的数据,以下图所示,其实就是一个表格数据,每一行表明一个样本,而后每一列就是不一样的属性。这个数据集主要是收集了三种不一样的鸢尾花的数据,分别为:
对应图中最后一列 Class label
,而后还有四种属性,分别是:
这个数据集多是最简单的机器学习数据集之一了,一般是用于教导程序员和工程师的机器学习和模式识别基础的数据集。
对于该数据集,咱们的目标就是根据给定的四个属性,训练一个机器学习模型来正确分类每一个样本的类别。
须要注意的是,其中有一个类别和另外两个类别是线性可分的,但这两个类别之间却并不是线性可分,因此咱们须要采用一个非线性模型来对它们进行分类。固然了,在现实生活中,采用非线性模型的机器学习算法是很是常见的。
第二个数据集是一个三场景的图像数据集。这是帮助初学者学习如何处理图像数据,而且哪一种算法在这两种数据集上性能最优。
下图是这个三场景数据集的部分图片例子,它包括森林、高速公路和海岸线三种场景,总共是 948 张图片,每一个类别的具体图片数量以下:
这个三场景数据集是采样于一个八场景数据集中,做者是 Oliva 和 Torralba 的 2001 年的一篇论文,Modeling the shape of the scene: a holistic representation of the spatial envelope
不管何时实现机器学习算法,推荐采用以下流程来开始:
这个流程会随着你机器学习方面的经验的积累而改善和优化,但对于初学者,这是我建议入门机器学习时采用的流程。
因此,如今开始吧!第一步,就是评估咱们的问题,问一下本身:
最后一个问题很是重要,随着你使用 Python 实现机器学习的次数的增长,你也会随之得到更多的经验。根据以前的经验,你可能知道有一种算法的性能还不错。
所以,接着就是准备数据,也就是数据预处理以及特征工程了。
通常来讲,这一步,包括了从硬盘中载入数据,检查数据,而后决定是否须要作特征提取或者特征工程。
特征提取就是应用某种算法经过某种方式来量化数据的过程。好比,对于图像数据,咱们能够采用计算直方图的方法来统计图像中像素强度的分布,经过这种方式,咱们就获得描述图像颜色的特征。
而特征工程则是将原始输入数据转换成一个更好描述潜在问题的特征表示的过程。固然特征工程是一项更先进的技术,这里建议在对机器学习有了必定经验后再采用这种方法处理数据。
第三步,就是检查各类机器学习算法,也就是实现一系列机器学习算法,并应用在数据集上。
这里,你的工具箱应当包含如下几种不一样类型的机器学习算法:
应当选择比较鲁棒(稳定)的一系列机器学习模型来评估问题,由于咱们的目标就是判断哪一种算法在当前问题的性能很好,而哪些算法很糟糕。
决定好要采用的模型后,接下来就是训练模型并在数据集上测试,观察每一个模型在数据集上的性能结果。
在屡次实验后,你可能就是有一种“第六感”,知道哪一种算法更适用于哪一种数据集。
好比,你会发现:
而以上的经验得到,固然就须要你多动手,多进行实战来深刻了解不一样的机器学习算法了!
接下来就开始敲代码来实现机器学习算法,并在上述两个数据集上进行测试。本教程的代码文件目录以下,包含四份代码文件和一个 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
库中就集成了咱们将要实现的几种机器学习算法的代码,包括:
咱们直接调用 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_))
复制代码
完成这两份代码后,咱们就能够开始运行下代码,对比不一样算法在两个数据集上的性能。
由于篇幅的缘由,这里我会省略原文对每一个算法的介绍,具体的能够查看以前我写的对机器学习算法的介绍:
这里咱们先运行下 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 在 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% 的准确率,和原文的同样。固然实际上原文给出的结果以下图所示,能够看到其实类别数量上是不相同的。
最后就是实现 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%,它是优于以前的几种机器学习算法的结果。
最后,这仅仅是一份对机器学习彻底是初学者的教程,其实就是简单调用现有的库来实现对应的机器学习算法,让初学者简单感觉下如何使用机器学习算法,正如同在学习编程语言的时候,对着书本的代码例子敲起来,而后运行代码,看看本身写出来的程序的运行结果。
经过这份简单的入门教程,你应该明白的是:
接着,根据这份教程,你能够继续进一步了解每种机器学习算法,了解每种算法的基本原理和实现,尝试本身手动实现,而不是简单调用现有的库,这样更加能加深印象,这里推荐《机器学习实战》,经典的机器学习算法都有介绍,而且都会带你一步步实现算法!
最后,极力推荐你们去阅读下原文做者的博客,原文做者也是一个大神,他的博客地址以下:
他的博客包含了 Opencv、Python、机器学习和深度学习方面的教程和文章,并且做者喜欢经过实战学习,因此不少文章都是经过一些实战练习来学习某个知识点或者某个算法,正如同本文经过实现这几种常见的机器学习算法在两个不一样类型数据集上的实战来带领初学者入门机器学习。
对该教程的代码和数据集获取方式以下:
欢迎关注个人微信公众号--机器学习与计算机视觉,或者扫描下方的二维码,你们一块儿交流,学习和进步!