使用 Keras 实现简单神经网络 – Python 示例






1.89/5 (4投票s)
在本文中,我们将结合使用 Keras 和 TensorFlow。
- 可以 在此处 下载本文配套的代码。
早在 2015 年,Google 就发布了 TensorFlow,这个库将改变神经网络领域,并最终使其主流化。它不仅在开发神经网络方面变得流行,还支持在其之上运行更高级别的 API。Keras 就是这些 API 之一。Keras 用 Python 编写,并且它不仅支持 TensorFlow。它还能够运行在 CNTK 和 Theano 之上。在本文中,我们将仅与 TensorFlow 结合使用它,因此如果您需要有关安装 TensorFlow 或了解一些相关信息,可以查看我之前的文章。使用 Keras 有很多好处,其中一个主要好处肯定是用户友好性。API 易于理解且非常直接。另一个好处是模块化。神经网络(模型)可以被视为由独立的、松耦合的、完全可配置的模块组成的序列或图。最后,Keras 易于扩展。
安装与设置
如前所述,Keras 运行在 TensorFlow 之上。因此,为了让这个库工作,您首先需要安装 TensorFlow。我还需要提到的是,在本文的演示中,我使用的是 Windows 10 和 Python 3.6。此外,我使用 Spyder 进行开发,因此本文中的示例可能与其他操作系统和平台有所不同。由于 Keras 是一个 Python 库,它的安装过程相当标准。您可以使用“原生 pip”并使用此命令进行安装
pip install keras
如果您使用 Anaconda,则可以通过发出以下命令来安装 Keras
conda install -c anaconda keras
或者,可以通过使用 Github 源代码来完成安装过程。首先,您需要从存储库克隆代码
git <span class="hljs-built_in">clone</span> https://github.com/keras-team/keras.git
之后,您需要将终端定位到该文件夹并运行安装命令
python setup.py install
顺序模型和 Keras 层
使用 Keras 的主要优点之一是它是一个用户友好的 API。它有两种模型
- 顺序模型
- 与函数式 API 一起使用的模型类
顺序模型可能是 Keras 中最常用的功能。本质上,它代表 Keras 层的数组。通过向其中添加层,它可以方便地快速构建不同类型的神经网络。Keras 层有很多种。最基本的一种也是我们将在本文中使用的一种叫做 Dense
。它提供了许多用于设置输入、激活函数等的选项。除了 Dense
,丰富的 Keras API 还提供了用于卷积神经网络、循环神经网络等的不同类型的层。这超出了本文的范围,但我们将在下一篇文章中介绍它们。那么,让我们看看如何使用 Sequential
和 Dense
构建神经网络。
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(3, input_dim=2, activation='relu'))
model.add(Dense(1, activation='softmax'))
在此示例中,我们首先从 Keras 导入了 Sequential
和 Dense
。然后,我们实例化了一个 Sequential
类的对象。之后,我们使用函数 add
和 Dense
类将一个层添加到神经网络中。Dense
构造函数中的第一个参数用于定义该层中的神经元数量。此层的一个特定之处在于我们使用了 input_dim
参数。通过这样做,我们向网络添加了一个额外的输入层,其中神经元数量由 input_dim
参数定义。基本上,通过这一个调用,我们添加了两个层。第一个是带有两个神经元的输入层,第二个是带有三个神经元的隐藏层。
您可能还会注意到,另一个重要参数是 activation
参数。使用此参数,我们定义特定层中所有神经元的激活函数。在这里,我们使用了“relu
”值,这表明该层中的神经元将使用 Rectifier 激活函数。最后,我们再次调用 Sequential
对象的 add
方法并添加另一个层。由于我们没有使用 input_dim
参数,因此将添加一个层,并且由于这是我们添加到神经网络的最后一层,它也将成为网络的输出层。
鸢尾花数据集分类问题
与上一篇文章一样,我们将在此演示中使用鸢尾花数据集分类问题。鸢尾花数据集是模式识别领域中一个著名的数据集,被认为是机器学习分类问题的“Hello World”示例。它最早由英国统计学家和植物学家 Ronald Fisher 于 1936 年推出。在他的论文《多重测量在分类问题中的应用》中,他使用了收集到的三种不同鸢尾花类的数据:Iris setosa、Iris virginica 和 Iris versicolor。
该数据集每个类别包含 50 个样本。有趣的是,第一类与其他两类是线性可分的,但后两类之间不是线性可分的。每个样本有五个属性
- 萼片长度(厘米)
- 萼片宽度(厘米)
- 花瓣长度(厘米)
- 花瓣宽度(厘米)
- 类别(Iris setosa、Iris virginica、Iris versicolor)
在下一章中,我们将使用 Keras 构建一个神经网络,该网络能够根据提供的属性预测鸢尾花类别。
代码
Keras 程序与 TensorFlow 程序的流程类似。我们将遵循以下步骤
- 导入数据集
- 准备数据以供处理
- 创建模型
- 培训
- 评估模型准确性
- 使用模型预测结果
训练和评估过程对任何人工神经网络都至关重要。这些过程通常使用两个数据集来完成,一个用于训练,另一个用于测试训练网络的准确性。在现实世界中,我们通常只得到一个数据集,然后将其分成两个单独的数据集。对于训练集,我们通常使用 80% 的数据,另外 20% 用于评估我们的模型。这次,这已经为我们做好了。您可以 在此处 下载伴随本文代码的训练集和测试集。
然而,在我们继续之前,我们需要导入一些库。以下是我们需要的库列表。
# Importing libraries
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
import numpy
import pandas as pd
如您所见,我们正在导入 Keras 依赖项、NumPy 和 Pandas。NumPy
是科学计算的基础包,Pandas
提供了易于使用的数据结构和数据分析工具。
导入库后,我们可以继续导入数据并准备好进行处理。我们将使用 Pandas
来导入数据
# Import training dataset
training_dataset = pd.read_csv('iris_training.csv', names=COLUMN_NAMES, header=0)
train_x = training_dataset.iloc[:, 0:4].values
train_y = training_dataset.iloc[:, 4].values
# Import testing dataset
test_dataset = pd.read_csv('iris_test.csv', names=COLUMN_NAMES, header=0)
test_x = test_dataset.iloc[:, 0:4].values
test_y = test_dataset.iloc[:, 4].values
首先,我们使用 read_csv
函数将数据集导入本地变量,然后将输入 (train_x, test_x)
和预期输出 (train_y, test_y)
分开,创建四个单独的矩阵。它们看起来是这样的
但是,我们的数据尚未准备好进行处理。如果我们查看预期输出值,我们可以注意到我们有三个值:0、1 和 2。值 0 用于表示 Iris setosa,值 1 用于表示 Iris versicolor,值 2 用于表示 virginica。关于这些值的好消息是我们没有在数据集中得到字符串值。如果您遇到这种情况,您将需要使用某种编码器来格式化数据,使其类似于我们当前数据集中的数据。为此,可以使用 sklearn 库的 <a href="https://scikit-learn.cn/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html" rel="noopener">LabelEncoder</a>
。关于数据集中这些值的坏消息是它们不适用于 Sequential
模型。我们想要做的是将预期输出从包含每个类别值的向量重塑为一个包含每个类别值的布尔值的矩阵。这被称为独热编码。为了实现这一点,我们将使用 Keras 库中的 np_utils
# Encoding training dataset
encoding_train_y = np_utils.to_categorical(train_y)
# Encoding training dataset
encoding_test_y = np_utils.to_categorical(test_y)
如果您仍然对独热编码的作用有疑问,请观察下图。其中显示了 train_y
变量和 encoding_train_y
变量。请注意 train_y
中的第一个值是 2,并查看 encoding_train_y
中该行的对应值。
导入并准备好数据后,我们就可以创建模型了。我们已经知道需要通过使用 Sequence
和 Dense
类来完成此操作。那么,我们来做吧
# Creating a model
model = Sequential()
model.add(Dense(10, input_dim=4, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(3, activation='softmax'))
# Compiling model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
这次,我们正在创建
- 一个具有四个节点的输入层,因为我们的输入值中有四个属性
- 两个具有十个神经元的隐藏层
- 一个具有三个神经元的输出层,因为我们有三个输出类别
在隐藏层中,神经元使用 Rectifier 激活函数,而在输出层中,神经元使用 Softmax 激活函数(确保输出值在 0 到 1 的范围内)。之后,我们编译我们的模型,在其中定义我们的成本函数和优化器。在此实例中,我们将使用 Adam 梯度下降优化算法,并使用对数成本函数(在 Keras 中称为 categorical_crossentropy
)。
最后,我们可以训练我们的网络
# Training a model
model.fit(train_x, encoding_train_y, epochs=300, batch_size=10)
并对其进行评估
# Evaluate the model
scores = model.evaluate(test_x, encoding_test_y)
print("\nAccuracy: %.2f%%" % (scores[1]*100))
如果我们运行此代码,我们将获得以下结果
由于我们在上一篇文章中与 TensorFlow 一样,在同一数据集上构建了相同的网络,因此我们获得了相同的准确率 – 0.93。这相当不错。在此之后,我们可以使用单个数据调用我们的分类器并获得预测。
结论
Keras 是一个很棒的 API,它使构建人工神经网络变得更加容易。它非常容易上手。在本文中,我们只是触及了该 API 的表面,在未来的帖子中,我们将探讨如何使用该 API 实现不同类型的人工神经网络。
感谢阅读!