手把手教你用keras完成第一个深度学习项目

翻译自Jason Brownlee PhD的博文,原文链接:
https://machinelearningmastery.com/tutorial-first-neural-network-python-keras/

Keras是一个用于开发和评估深度学习模型的强大又便捷的免费开源 Python 库。它封装了高效的数值计算库 Theano 和 TensorFlow,使用户只需几行代码即可定义和训练神经网络模型。
下面将通过Pima二分类问题,手把手教你如何使用keras进行深度学习实战。具体步骤包括

  1. 导入数据
  2. 定义Keras模型
  3. 编译Keras模型
  4. 训练Keras模型
  5. 评估Keras模型
  6. 进行预测
    本 Keras 教程的环境要求包括:
    (1)安装并配置了 Python 2 或 3
    (2)安装并配置了 SciPy(包括 NumPy)
    (3)安装并配置了 Keras 和后端(Theano 或 TensorFlow)
    搭建环境可参考以下链接:
    https://machinelearningmastery.com/setup-python-environment-machine-learning-deep-learning-anaconda/

导入数据

首先,需要定义我们打算在本教程中使用的函数和类。我们使用 NumPy 库加载我们的数据集,使用 Keras 库中的两个类来定义我们的模型。

下面列出了所需的库:

from numpy import loadtxt
from keras.models import Sequential
from keras.layers import Dense

在本 Keras 教程中,我们将使用来自 UCI的Pima印第安人糖尿病发病数据集。 该数据集描述了皮马印第安人的患者病历数据,以及他们是否在五年内患上糖尿病。这是一个二元分类问题(糖尿病发病为 1 ,不发病为 0)。 描述每个患者的所有输入变量都是数字变量。 这使得它很容易直接应用于需要数值输入和输出值的神经网络。这个数据集可以从以下链接下载:

我们可以使用 NumPy 函数 loadtxt() 将文件加载为数字矩阵。

Pima数据集中有八个输入变量和一个输出变量(最后一列为输出变量)。 我们将学习一个模型来将输入变量 (X) 映射到输出变量 (y),即 y = f(X)。

这些变量的含义如下:

  1. 怀孕次数
  2. 口服葡萄糖耐量试验中 2 小时的血浆葡萄糖浓度
  3. 舒张压(毫米汞柱)
  4. 三头肌皮褶厚度(mm)
  5. 2 小时血清胰岛素 (mu U/ml)
  6. BMI(体重公斤/(身高米)^2)
  7. 糖尿病谱系函数
  8. 年龄(岁)

输出变量
类别(0或1)

在将 CSV 文件加载到内存之后,我们就可以将数据列拆分为输入和输出变量。数据存储在二维数组中,其中第一维是行,第二维是列,例如 [行,列]。

我们可以通过使用标准 NumPy 切片运算符或“:”选择列子集将数组拆分为两个输入变量和输出变量,其中输入变量为索引 0 到索引 7 的前 8 列,输出变量为索引 8。

请注意,数据集有 9 列,范围 0:8 将选择从 0 到 7 的列,在索引 8 之前停止。如果这对您来说是新知识,那么您可以在这篇文章中了解有关数组切片和范围的更多信息:
https://machinelearningmastery.com/index-slice-reshape-numpy-arrays-machine-learning-python/

# load the dataset
dataset = loadtxt('pima.csv', delimiter=',')
# split into input (X) and output (y) variables
X = dataset[:,0:8]
y = dataset[:,8]

定义Keras模型

Keras 中的模型被定义为一系列的层。我们创建Sequential模型,每次添加一层直至我们对构建的网络框架感到满意。

保证模型正确性的第一件事是确保输入层具有正确数量的输入特征。这可以在使用 input_dim 参数创建第一层并将其设置为 8 ,因为在该问题中有 8 个输入变量。

那么,我们如何知道层的数量及其类型?

这是一个非常难的问题。我们可以使用一些启发式方法,通常最好的网络结构是通过反复试验的过程找到的。详情可参考文章:
https://machinelearningmastery.com/how-to-configure-the-number-of-layers-and-nodes-in-a-neural-network/

通常,需要一个足够大的网络来捕获问题的结构。

在本例中,我们将使用具有三层的全连接网络结构。

全连接层使用 Dense 类(https://keras.io/api/layers/core_layers/)定义。我们可以指定层中神经元或节点的数量作为第一个参数,并使用 activation 参数指定激活函数。

我们将在前两层使用 ReLU激活函数(rectified linear unit activation function),在输出层使用 Sigmoid 函数。

P.S. 过去,所有层都首选 Sigmoid 和 Tanh 激活函数。现在,使用 ReLU 激活函数可以获得更好的性能。我们在输出层使用 sigmoid 以确保我们的网络输出介于 0 和 1 之间,这可以使我们轻松地确定类别为1的概率或者是通过默认阈值0.5来对结果进行分类。

在本例中,模型参数设置如下:

  1. 该模型需要具有 8 个变量的数据行(input_dim=8 参数)
  2. 第一个隐藏层有 12 个节点,使用 relu 激活函数。
  3. 第二个隐藏层有8个节点,使用relu激活函数。
  4. 输出层有一个节点,使用sigmoid激活函数。
# define the keras model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

请注意,这里最令人困惑的是模型输入的形状(也就是输入的属性数)被定义为第一个隐藏层的参数。 这意味着添加第一个 Dense 层的代码行做了两件事,定义输入或可见层,定义第一个隐藏层。

编译Keras模型

在定义好模型的基础上,我们将对模型展开编译。

编译模型使用了有效的数字库(即所谓的后端),例如 Theano 或 TensorFlow。 后端会自动选择最好的方式来表示网络,以便在您的硬件上(例如CPU,GPU甚至是分布式)进行训练和预测。

编译时,我们必须指定训练网络时所需的一些附加属性,训练网络意味着找到最佳权重集以将数据集中的输入映射到输出上。

我们必须指定用于评估一组权重的损失函数(loss function),优化器(optimizer)用于搜索网络的不同权重以及我们希望在训练期间收集和报告的任何可选指标。

在这种情况下,我们将使用交叉熵(cross entropy )作为损失参数。 这种损失是针对二元分类问题的,在 Keras 中被定义为“binary_crossentropy”。 可以在此处了解有关不同问题下如何选择损失函数的更多指导:

https://machinelearningmastery.com/how-to-choose-loss-functions-when-training-deep-learning-neural-networks/

我们将优化器定义为高效的随机梯度下降算法“adam”。 这是梯度下降的流行版本,因为它会自动调整自身并在许多问题中给出良好的结果。 要了解有关 Adam 版本的随机梯度下降的更多信息,可参阅链接:

https://machinelearningmastery.com/adam-optimization-algorithm-for-deep-learning/

最后,因为这是一个分类问题,我们将整理并给出通过度量参数定义的分类准确度。

# compile the keras model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

训练Keras模型

我们已经定义了模型并对它进行了编译,为高效计算做好了准备。

现在是对一些数据执行模型的时候了。

我们可以通过调用模型上的 fit() 函数在加载的数据上进行训练或拟合模型。

训练发生在 epoch 上,每个 epoch 被分成批次。

Epoch:一次遍历训练数据集中的所有行。
Batch:在更新权重之前,模型在一个epoch内考虑的一个或多个样本。

一个epoch由一个或多个batch组成,基于所选的batch大小,并且该模型由多个epoch进行拟合。有关 epochs 和 batches 之间差异的更多信息,请参阅帖子:

https://machinelearningmastery.com/difference-between-a-batch-and-an-epoch/

训练过程将通过数据集上运行固定次数的迭代进行,必须使用 epochs 参数指定。我们还必须设置在每个epoch内更新模型权重之前考虑的数据集行数,称为批大小,并使用 batch_size 参数进行设置。

对于这个问题,我们将运行少量epoch(150)并使用相对较小的批次batch= 10。

这些配置可以通过反复试验通过实验来选择。我们希望对模型进行足够的训练,以便它学习到输入数据行到输出分类的良好(或足够好)映射。模型总会有一些错误,但对于给定的模型配置,错误量会在某个时间点后趋于平稳。这称为模型收敛。

# fit the keras model on the dataset
model.fit(X, y, epochs=150, batch_size=10)

运行结果如下:

在这里插入图片描述
需要注意的是,神经网络是一种随机算法,这意味着每次运行代码时,相同数据上的相同算法可以训练具有不同技能的不同模型。

评估Keras模型

我们已经在整个数据集上训练了我们的神经网络,我们可以在同一数据集上评估训练得到的神经网络的性能。

这只会让我们了解我们对数据集建模的程度(例如训练准确性),但不知道算法在新数据上的表现如何。我们这样做是为了简单起见,但理想情况下,需要将数据分成训练和测试数据集,用于训练和评估模型。

可以使用模型上的evaluate() 函数在训练数据集上评估模型,并将用于训练模型的相同输入和输出传递给它。

这将为每个输入和输出对生成预测并收集分数,包括平均损失和其他任何指标,例如准确性。

evaluate() 函数将返回一个包含两个值的列表。第一个是模型在数据集上的损失,第二个是模型在数据集上的准确性。我们只对报告准确性感兴趣,因此我们将忽略损失值。

# evaluate the keras model
_, accuracy = model.evaluate(X, y)
print('Accuracy: %.2f' % (accuracy*100))

理想情况下,我们希望损失为零,准确度为 1.0(例如 100%)。 这对于最微不足道的机器学习问题是不可能的。 相反,我们的模型中总会有一些错误。 目标是选择一个模型配置和训练配置,以实现给定数据集的最低损失和最高准确度。

进行预测

进行预测就像在模型上调用 predict() 函数一样简单。 我们在输出层使用 sigmoid 激活函数,因此预测将是 0 到 1 范围内的概率。我们可以通过四舍五入轻松地将它们转换为该分类任务下的二元类别预测。

# make probability predictions with the model
predictions = model.predict(X)
# round predictions 
rounded = [round(x[0]) for x in predictions]

或者,我们可以将概率转换为 0 或 1 以直接预测清晰的类别,例如:

# make class predictions with the model
predictions = (model.predict(X) > 0.5).astype(int)

下面的完整示例对数据集中的每个示例进行预测,然后打印数据集中前 5 个示例的输入数据、预测类别和预期类别。

# first neural network with keras make predictions
from numpy import loadtxt
from keras.models import Sequential
from keras.layers import Dense
# load the dataset
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=',')
# split into input (X) and output (y) variables
X = dataset[:,0:8]
y = dataset[:,8]
# define the keras model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# compile the keras model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# fit the keras model on the dataset
model.fit(X, y, epochs=150, batch_size=10, verbose=0)
# make class predictions with the model
predictions = (model.predict(X) > 0.5).astype(int)
# summarize the first 5 cases
for i in range(5):
	print('%s => %d (expected %d)' % (X[i].tolist(), predictions[i], y[i]))
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值