【51CTO.com快译】回想起刚接触AI时,我清楚地记得一些概念看起来有多难。阅读神经网络的简单介绍常常碰到科学论文,里面的公式有你从未见过的符号,但开始编写第一个神经网络实际上容易得多!
那么神经网络是什么呢?
这个问题提得好!在自行用Python代码编写一个简单的神经网络之前,不妨介绍一下神经网络以及为何它如此令人兴奋!
HNC Software的联合创始人Robert Hecht-Nielsen博士简单地说。
……神经网络是由许多简单又高度互连的处理单元组成的计算系统,这些处理单元通过对外部输入的动态状态响应来处理信息。
——人工智能专家Maureen Caudill撰写的《神经网络入门:第一部分》,1989年2月
实际上,神经网络是一组擅长识别信息或数据中模式的数学表达式。神经网络通过一种模仿人类的感知来做到这点,但它不是像人类那样查看图片,而是表示以数字方式包含在Vector或Scalar中的信息(一个Vector只含一个数字)。
它通过层来传递该信息,一层的输出充当下一层的输入。经过这些层时,输入通过权重和偏差加以修改,然后发送到激活函数以映射输出。然后通过成本函数进行学习,该函数对实际输出和所需输出进行比较,这进而通过一种名为反向传播的过程,帮助函数更改并调整权重和偏差,实现成本最小化。
对于我们实现的示例神经网络,我们将使用MNIST数据集。
图1. MNIST样本数据集
MNIST好比是“Hello World”数据集,因为它能够非常简明地演示神经网络的功能。数据集由手写数字组成,我们将训练神经网络识别和分类这些数字。
Keras登场
为了便于实现,我们将使用Keras框架。Keras是用Python编写的一种高级API,它在TensorFlow和Theano等流行框架上运行,为机器学习从业人员提供了抽象层,以降低编写神经网络的固有复杂性。
建议你深入研究Keras说明文档(https://keras.io/),以真正熟悉该API。另外强烈推荐Francois Chollet撰写的《用Python做深度学习》一书,本教程的灵感源自此书。
该考验GPU的时候了
我们在本教程中将使用Keras和TensorFlow后端,因此如果你尚未安装其中任何一个,现在赶紧安装,只需在终端中运行这些命令即可。如果你不单单想了解简单的入门示例,最好搭建Anaconda环境,改用conda安装以下内容。
pip3 install Keras
pip3 install Tensorflow
你已安装了第一个神经网络所需的一切,现在打开常用的IDE,不妨导入我们所需的Python模块!
from keras.datasets import mnist
from keras import models
from keras import layers
from keras.utils import to_categorical
Keras有许多数据集可以用来帮助你学习,对我们来说幸好有MNIST这个数据集。Models和Layers这两个模块可帮助我们构建神经网络,to_categorical用于数据编码,不过稍后有详细介绍。
我们已导入了所需的模块,接下来应将数据集分成训练集和测试集。只要用下面这一行即可完成。
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
在该例子中,我们的神经网络通过对其输出与标记数据进行比较来学习。可以把这看成我们让神经网络猜测大量的手写数字,然后将猜测结果与实际标签进行比较。随后馈入结果,帮助模型调整权重和偏差,以便实现总成本最小化。
训练集和数据集已建好,现在我们准备构建模型。
network = models.Sequential()
network.add(layers.Dense(784, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(784, activation='relu', input_shape=(28 * 28,)))network.add(layers.Dense(10, activation='softmax'))network.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
这看起来代码有很多,但不妨分解一下。我们初始化名为network的顺序模型。
network = models.Sequential()
然后我们添加神经网络层。针对该例子,我们将使用密集层。密集层是指,每个神经元从上一层的所有神经元接收输入。[784]和[10]指输出空间的维数,这好比是后续层的输入数;由于我们试图解决的分类问题有10种可能的类别(数字0至9),最后层的潜在输出是10个单位。激活参数指我们想要使用的激活函数,实际上激活函数根据给定的输入来计算输出。 最后,28 * 28的输入形状是指图片的像素宽度和高度。
network.add(layers.Dense(784, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(784, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))
一旦模型定义完毕,并添加了神经网络层,我们只需用所选择的优化器、所选择的损失函数以及想用来评估模型性能的度量标准来编译该模型。
network.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
恭喜!你刚构建了你的第一个神经网络!
现在你可能仍有几个问题,比如relu和softmax是什么?adam又是谁?那些都是值得思考的问题……我们会在以后的文章中深入解释这些问题。
将数据馈入到刚创建的模型之前,我们需要将输入整形成模型可以读取的格式。输入的原始形状是[60000,28,28],实际上代表60000个像素高度和宽度是28 x28的图片。我们可以对数据进行整形,分为训练[60000]图片和测试[10000]图片。
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255
除了整形数据外,我们还需要编码数据。针对该例子,我们将使用分类编码,这实际上将许多特征变成数值表示。
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
我们的数据集已分成训练集和测试集,而且模型经过编译、数据经过整形和编码,现在我们现在准备训练神经网络!为此,我们要调用fit函数,并传递所需的参数。
network.fit(train_images, train_labels, epochs=5, batch_size=128)
我们传递训练图片及其标签,另外传递轮次(epoch)和批大小(batch_size),前者表明了向后传播和向前传播的数量,后者表明了每个向后/向前传播的训练样本数量。
我们还想要设置性能衡量参数,以便搞清楚这个模型的效果有多好。
test_loss, test_acc = network.evaluate(test_images, test_labels)
print('test_acc:', test_acc, 'test_loss', test_loss)
大功告成!你刚编写了自己的神经网络,整形并编码了数据集,并拟合了训练的模型。如果你首次运行Python脚本,Keras会下载MNIST数据集,开始训练5轮。
使用测试输出的训练周期
你的测试准确度应该达到98%左右,这意味着模型运行测试时在98%的时间段内正确预测了数字,这对你的第一个神经网络来说不赖!实际上,如果你的模型拟合过度/拟合不足,你希望同时查看测试结果和训练结果,以便想出好主意。
鼓励你调整一下层数、优化器、损失函数、轮次以及批大小,看看各自对模型的整体性能有何影响!
原文标题:Writing Your First Neural Net in Less Than 30 Lines of Code with Keras,作者:David Gündisch