Keras教程(Python深度学习)

本文概述

  • 深度学习
  • 人工神经网络介绍
  • 预测酒的类型:红色还是白色?
  • 数据探索
  • 预处理数据
  • 模型数据
  • 编译并拟合
  • 预测值
  • 评估模型
  • 更多实验
  • 预测葡萄酒质量
  • 走得更远!
Keras教程(Python深度学习)

文章图片
深度学习 到目前为止, 你可能已经知道机器学习, 这是计算机科学的一个分支, 研究可以学习的算法的设计。今天, 你将专注于深度学习, 它是机器学习的一个子领域, 它是一组受大脑结构和功能启发的算法。这些算法通常称为人工神经网络(ANN)。深度学习是数据科学领域最热门的领域之一, 许多案例研究在机器人技术, 图像识别和人工智能(AI)方面均取得了惊人的成果。
Keras是用于开发和评估深度学习模型的功能最强大且易于使用的Python库之一。它包装了高效的数值计算库Theano和TensorFlow。这样做的好处主要是可以轻松有趣地开始使用神经网络。
今天的Keras初学者教程将向你介绍Python深度学习的基础知识:
  • 你将首先了解什么是人工神经网络。
  • 然后, 本教程将逐步向你展示如何使用Python及其库来理解, 探索和可视化数据,
  • 如何预处理数据:你将学习如何在训练和测试集中拆分数据, 以及如何标准化数据,
  • 如何为分类任务建立多层感知器,
  • 如何将数据编译并适合这些模型,
  • 如何使用模型预测目标值, 以及
  • 如何验证你建立的模型。
  • 最后, 你还将看到如何为回归任务建立模型, 并且将学习如何微调已建立的模型。 
你想参加有关Keras和Python深度学习的课程吗?考虑参加srcmini的Python深度学习课程!
另外, 请不要错过我们的Keras备忘单, 它通过代码示例向你展示了在Python中构建神经网络所需要完成的六个步骤!
人工神经网络介绍 在深入了解Keras以及如何使用它来开始使用Python进行深度学习之前, 你可能应该对神经网络有所了解。正如你在上一节中简要阅读的那样, 神经网络发现了它们的灵感和生物学特性, 其中” 神经网络” 一词也可以用于神经元。这样, 人脑就是这种神经网络的一个例子, 它由许多神经元组成。
而且, 众所周知, 大脑能够执行相当复杂的计算, 这就是人工神经网络的灵感来源。整个网络是一个强大的建模工具。
感知器
最简单的神经网络是” 感知器” , 它以最简单的形式包含单个神经元。就像具有树突和轴突的生物神经元一样, 单个人工神经元是一个简单的树状结构, 具有输入节点和一个连接到每个输入节点的单个输出节点。这是两者的视觉对比:
Keras教程(Python深度学习)

文章图片
请注意, 如果你使用numpy包中的histogram()函数来计算白色和红色数据的直方图, 则可以再次进行检查, 如下所示:
如果你对matplotlib教程感兴趣, 请务必查看srcmini的Matplotlib入门教程和Viewing 3D Volumetric Data教程, 该教程向你展示如何利用Matplotlib的事件处理程序API。
硫酸盐
其次, 令我感兴趣的一件事是硫酸盐与葡萄酒质量之间的关系。正如你在上文中所读到的, 硫酸盐会导致人们头痛, 我想知道这是否会影响葡萄酒的质量。更重要的是, 我经常听到女性特别不想喝葡萄酒, 因为它会引起头痛。也许这会影响红酒的评级?
让我们来看看。
从下图中可以看出, 与白葡萄酒相比, 红葡萄酒似乎含有更多的硫酸盐, 而白葡萄酒在1 g / \(dm ^ 3 \)以上具有较少的硫酸盐。对于白葡萄酒, 似乎只有几个例外, 即略高于1 g / \(dm ^ 3 \), 而对于红葡萄酒肯定更多。这也许可以解释一般的说法, 即红酒会引起头痛, 但是质量呢?
你可以清楚地看到, 硫酸盐含量较低的白葡萄酒得分为9, 但对于其余葡萄酒, 此时很难正确解释数据。
当然, 你需要考虑到观察值的差异也可能影响图形以及你如何解释它们。
Keras教程(Python深度学习)

文章图片
很有意思!
训练和测试集
数据不平衡通常是指分类问题的问题, 其中类别没有被平等地表示。大多数分类数据集在每个类别中的实例数并不完全相等, 但是很小的差异通常并不重要。因此, 你需要确保训练模型中存在所有两类葡萄酒。此外, 所有两种葡萄酒的实例数量必须或多或少相等, 以便你在预测中不偏爱一种或另一种。
在这种情况下, 似乎存在不平衡, 但是你现在就可以解决这个问题。之后, 你可以评估模型, 如果模型表现不佳, 则可以采用欠采样或过采样来掩盖观测值的差异。
现在, 从sklearn.model_selection导入train_test_split并将数据和目标标签分配给变量X和y。你会看到, 你需要展平目标标签的数组, 以便完全准备使用X和y变量作为train_test_split()函数的输入。开始工作, 从下面的srcmini Light块开始!
你已经很好地构建了第一个神经网络, 但是仍然需要注意一件事!在查看白色和红色数据集的摘要时, 你是否还知道发现了什么?
确实, 其中一些价值观相距甚远。在这里进行一些标准化可能是有意义的。
标准化数据
标准化是处理距离如此遥远的这些价值观的一种方式。 scikit-learn包为你提供了一种使数据标准化的好方法:从sklearn.preprocessing导入StandardScaler模块, 你就可以扩展训练和测试数据了!
# Import `StandardScaler` from `sklearn.preprocessing`from sklearn.preprocessing import StandardScaler# Define the scaler scaler = StandardScaler().fit(X_train)# Scale the train setX_train = scaler.transform(X_train)# Scale the test setX_test = scaler.transform(X_test)

现在, 你已经对数据进行了预处理, 接下来可以进行实际工作:建立自己的神经网络来对葡萄酒进行分类。
模型数据 在开始建模之前, 请先回到原始问题:可以通过查看其化学特性(例如挥发性酸度或硫酸盐)来预测葡萄酒是红色还是白色?
由于只有白色和红色两个类, 因此将进行二进制分类。可以想象, “ 二进制” 表示0或1, 是或否。由于神经网络只能处理数字数据, 因此你已经将红色编码为1, 将白色编码为0。
多层感知器是在此类问题上表现良好的一种网络。正如你在本教程开始时所读的那样, 这种类型的神经网络通常是完全连接的。这意味着你正在寻求构建相当简单的全连接层堆栈以解决此问题。至于你将要使用的激活功能, 最好使用此处最常用的激活功能之一, 以便熟悉Keras和神经网络, 即relu激活功能。
现在, 你如何开始构建多层感知器?快速入门是使用Keras顺序模型:它是线性的图层堆栈。通过将图层实例列表传递给构造函数, 可以很容易地创建模型, 你可以通过运行model = Sequential()进行设置。
接下来, 最好回顾一下本教程开头可能已经了解的多层感知器的结构:你有一个输入层, 一些隐藏层和一个输出层。因此, 在制作模型时, 重要的是要考虑到第一层需要使输入形状清晰。该模型需要知道预期的输入形状, 这就是为什么你总是在层的文档以及这些层的实际示例中找到input_shape, input_dim, input_length或batch_size参数的原因。
在这种情况下, 你将必须使用密集层, 这是一个完全连接的层。密集层实现以下操作:输出=激活(点(输入, 内核)+偏置)。请注意, 如果没有激活功能, 则” 密集” 层将仅包含两个线性运算:点积和加法运算。
在第一层中, 激活参数采用值relu。接下来, 你还将看到input_shape已定义。这是你刚刚看到的操作的输入:模型采用形状为(12, )或(*, 12)的输入数组。最后, 你看到第一层具有12作为Dense()的units参数的第一个值, 这是输出空间的维数, 实际上是12个隐藏的单位。这意味着模型将输出形状为(*, 12)的数组:这是输出空间的维数。如果你现在还没有完全了解, 请不要担心, 稍后你将详细了解它!
单位实际上代表上述公式的内核或权重矩阵, 该权重矩阵由层创建的, 赋予所有输入节点的所有权重组成。请注意, 由于没有包含use_bias参数并将其设置为TRUE, 因此在下面的示例中没有包含任何偏差。
中间层还使用relu激活功能。该层的输出将是形状(*, 8)的数组。
你将使用大小为1的密集层结束网络。最后一层还将使用S型激活函数, 因此你的输出实际上是概率;这意味着这将导致得分在0到1之间, 表明样品具有目标” 1″ 的可能性或葡萄酒变红的可能性。
总而言之, 你会看到需要做出两个关键的体系结构决策才能建立模型:要使用的层数以及为每个层选择的” 隐藏单元” 数。
在这种情况下, 你为模型的第一层选择了12个隐藏的单位:如上所示, 这是输出空间的维数。换句话说, 你要设置允许网络在学习表示形式时拥有的自由度。如果你允许更多的隐藏单元, 则你的网络将能够学习更多复杂的表示形式, 但操作起来也很昂贵, 可能会过度拟合。
请记住, 当模型过于复杂时, 就会发生过度拟合:它将描述随机误差或噪声, 而不是需要描述的基本关系。换句话说, 训练数据建模得太好了!
请注意, 当你没有足够的训练数据时, 你应该使用隐藏层很少的小型网络(通常只有一个网络, 如上例所示)。
如果要获取有关刚刚创建的模型的一些信息, 则可以使用属性output_shape或summary()函数等。下面列出了一些最基本的方法。
尝试运行它们, 以查看你获得了什么样的结果, 以及它们告诉你有关刚刚创建的模型的信息:
编译并拟合 接下来, 是时候编译模型并使模型适合数据了:再次使用compile()和fit()来完成此操作。
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])model.fit(X_train, y_train, epochs=20, batch_size=1, verbose=1)

在编译时, 你需要使用adam优化器和binary_crossentropy损失函数来配置模型。此外, 你还可以通过将[‘ accuracy’ ]传递到metrics参数来监视训练期间的准确性。
如果要编译模型, 则优化器和损失是两个参数。使用的一些最受欢迎的优化算法是随机梯度下降(SGD), ADAM和RMSprop。根据你选择的算法, 你需要调整某些参数, 例如学习率或动量。损失函数的选择取决于你手头的任务:例如, 对于回归问题, 通常将使用均方误差(MSE)。如本例所示, 你使用了binary_crossentropy来解决确定葡萄酒是红色还是白色的二进制分类问题。最后, 通过多类别分类, 你将利用categorical_crossentropy。
之后, 你可以在X_train和y_train中的所有样本上以1个样本的批次训练模型20个纪元或迭代。你还可以指定详细参数。通过将其设置为1, 表示你要查看进度条日志记录。
换句话说, 你必须针对训练数据集的指定时期或曝光次数训练模型。一个时期是整个训练集的一次通过, 然后是验证集的测试。你在上面的代码中指定的批量大小定义了将通过网络传播的样本数量。另外, 这样做还可以优化效率, 因为可以确保不会同时将太多的输入模式加载到内存中。
预测值 让我们使用你的模型!你可以使用它来预测测试集的标签。只需使用predict()并将测试集传递给它即可预测数据的标签。在这种情况下, 结果存储在y_pred中:
y_pred = model.predict(X_test)

在评估模型之前, 你已经可以通过检查y_pred和y_test的比较方式来快速了解准确性:
y_pred[:5]

array([[0], [1], [0], [0], [0]], dtype=int32)

y_test[:5]

array([0, 1, 0, 0, 0])

你会看到这些值似乎加起来了, 但是如果没有一些固定数字, 这一切是什么?
评估模型 现在, 你已经建立了模型, 并使用它来对模型尚未看到的数据进行预测, 是时候评估其性能了。你可以直观地将预测结果与实际测试标签(y_test)进行比较, 也可以使用所有类型的指标来确定实际性能。在这种情况下, 你将使用评估()来执行此操作。传递测试数据和测试标签, 并根据需要将详细参数设为1。这样做时, 你会看到更多日志。
score = model.evaluate(X_test, y_test, verbose=1)print(score)

[0.025217213829228164, 0.99487179487179489]

分数是包含损失和准确性的组合的列表。在这种情况下, 你会看到两者看起来都很棒, 但是在这种情况下, 请记住你的数据有些不平衡:白葡萄酒的数量多于红葡萄酒的数量。准确性可能只是反映你数据的类别分布, 因为它只能预测白色, 因为这些观察值很多!
在开始重新排列数据并以其他方式将它们组合在一起之前, 尝试不同的评估指标总是一个好主意。为此, 你可以依靠scikit-learn(将其作为sklearn导入, 就像在制作训练和测试集之前一样)。
在这种情况下, 你将测试一些基本的分类评估技术, 例如:
  • 混淆矩阵, 这是将预测分解为表格的表格, 该表格显示正确的预测和做出的错误预测的类型。理想情况下, 你只会在对角线上看到数字, 这意味着你所有的预测都是正确的!
  • 精度是分类器准确性的度量。精度越高, 分类器越准确。
  • 召回率是衡量分类器完整性的指标。召回率越高, 分类器覆盖的案例越多。
  • F1分数或F分数是准确性和召回率的加权平均值。
  • 卡伯(Kappa)或科恩(Cohen)的卡伯(kappa)是通过数据中类的不平衡归一化的分类精度。
# Import the modules from `sklearn.metrics`from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, cohen_kappa_score# Confusion matrixconfusion_matrix(y_test, y_pred)

array([[1585, 3], [8, 549]])

# Precision precision_score(y_test, y_pred)

0.994565217391

# Recallrecall_score(y_test, y_pred)

0.98563734290843807

# F1 scoref1_score(y_test, y_pred)

0.99008115419296661

# Cohen's kappacohen_kappa_score(y_test, y_pred)

0.98662321692498967

所有这些分数都很好!尽管你有很多白葡萄酒类型的行, 但你已经做出了非常准确的模型。
做得好!
更多实验 你已经成功建立了第一个模型, 但是你可以使用这个模型进一步发展。为什么不尝试以下事情, 看看它们的作用是什么?就像你在上面阅读的一样, 你需要做出的两个关键体系结构决策涉及层和隐藏节点。这些是很好的起点:
  • 你使用了1个隐藏层。尝试使用2或3个隐藏层;
  • 使用具有更多隐藏单元或更少隐藏单元的图层;
  • 将质量列作为目标标签, 并将其余数据(包括编码类型列!)作为数据。你现在遇到了多类分类问题!
但是, 为什么还不尝试更改激活功能呢?代替使用reh, 尝试使用tanh激活功能, 看看结果如何!
预测葡萄酒质量 你的分类模型在首次运行时表现完美!
但是, 除了多层感知器之外, 你还可以做更多的事情, 不仅可以提高层次并尝试更复杂的结构。为什么不尝试建立神经网络来预测葡萄酒的品质呢?
在这种情况下, 本教程假定质量是一个连续变量:那么该任务不是二进制分类任务, 而是序数回归任务。这是一种用于预测序数变量的回归:质量值存在于任意范围内, 其中不同质量值之间的相对顺序很重要。在这个量表中, 从” 非常差” 到” 非常好” 的质量量表0-10是这样的例子。
请注意, 你也可以将此类问题视为分类问题, 并将质量标签视为固定类标签。
无论如何, 这种情况的设置将意味着你的目标标签将成为本教程第二部分的红色和白色DataFrames中的quality列。这将需要一些额外的预处理。
预处理数据
由于质量变量成为你的目标类别, 因此你现在需要将质量标签与其余数据集隔离。你将wines.quality放入另一个变量y中, 并将wines数据放入其中, 但quality列除外则放入变量x中。
接下来, 你已经准备好将数据分为训练和测试集, 但是在这种情况下, 即使你可以, 也不会采用这种方法。在本教程的第二部分中, 你将使用k倍验证, 这需要将数据分成K个分区。通常, 将K设置为4或5。接下来, 你实例化相同的模型并在一个分区上训练每个模型, 同时还评估剩余的分区。然后, 模型的验证分数是所获得的K验证分数的平均值。
稍后你将看到如何执行此操作。现在, 像以前一样, 在将数据拟合到模型之前, 使用StandardScaler确保数据在正确的位置。
请记住, 你还需要再次执行缩放, 因为红色, 白色(因此也包括葡萄酒)数据的某些值存在很大差异。
在下面的srcmini Light块中尝试一下。已为你加载了所有必需的库!
现在你又回到了刚才的位置。你可以再次开始对神经网络建模!
模型神经网络架构
现在, 你已经再次对数据进行了预处理, 现在是再次构建神经网络模型(多层感知器)的时候了。即使你将其用于回归任务, 其架构看起来也几乎相同, 只有两个密集层。
不要忘记第一层是你的输入层。你将需要将输入数据的形状传递给它。在这种情况下, 你会看到将要使用input_dim将输入数据的尺寸传递到Dense层。
再次注意, 你定义的第一层是输入层。该层需要知道数据的输入维。你输入的输入尺寸(在这种情况下为12)(不要忘记, 你还在计算在教程的第一部分中生成的Type列!)。你再次使用relu激活功能, 但是再次没有偏见。隐藏的单位数是64。
你的网络以单个单元Dense(1)结尾, 并且不包含激活。这是标量回归的典型设置, 你要在其中预测单个连续值。
编译模型, 拟合数据
有了模型, 你就可以再次对其进行编译并将其拟合为数据。可是等等。你不需要以前阅读过的K折验证分区吗?那就对了。
import numpy as npfrom sklearn.model_selection import StratifiedKFoldseed = 7np.random.seed(seed)kfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=seed)for train, test in kfold.split(X, Y):model = Sequential()model.add(Dense(64, input_dim=12, activation='relu'))model.add(Dense(1))model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])model.fit(X[train], Y[train], epochs=10, verbose=1)

使用compile()函数编译模型, 然后使用fit()将模型拟合到数据。要编译模型, 请再次确保至少定义了优化器和损失参数。在这种情况下, 你可以使用rsmprop(最流行的优化算法之一)并将mse用作损失函数, 这对于诸如你的回归问题非常典型。
你定义的其他指标参数实际上是一个用于判断模型性能的函数。对于回归问题, 通常以平均绝对误差(MAE)作为度量标准。你将在下一部分中详细了解此内容。
将火车数据和标签传递给fit(), 确定要运行拟合的历时, 批次大小, 如果需要, 可以将verbose参数设置为1以获取更多日志, 因为这可能会花费一些时间。
评估模型
像以前一样, 你还应该评估模型。除了在上面的其余代码中添加y_pred = model.predict(X [test])之外, 使用sklearn中的一些评估指标也是一个好主意, 就像你在本教程的第一部分中所做的一样。
为此, 你可以利用均方误差(MSE)和平均绝对误差(MAE)。前者也称为” 均方差” (MSD), 用于测量误差或偏差的平方的平均值。换句话说, 它量化了估计量和估计量之间的差异。这样, 你将对估计器的质量有更多了解:它总是非负的, 并且接近零的值更好。
后者的评估指标MAE代表平均绝对误差:它量化了预测与最终结果的接近程度。
将这些行添加到先前的代码块中, 并注意缩进:
mse_value, mae_value = http://www.srcmini.com/model.evaluate(X[test], Y[test], verbose=0)print(mse_value)

0.522478731072

print(mae_value)

0.561965950103

请注意, 除了MSE和MAE分数外, 你还可以使用R2分数或回归分数函数。在这里, 你应该获得1.0的最高分。但是, 分数也可以为负!
from sklearn.metrics import r2_scorer2_score(Y[test], y_pred)

0.3125092543

乍一看, 这些数字非常可怕, 对吧?不过, 这样做的好处是, 你现在可以尝试优化代码, 以使结果变得更好一点。
这就是下一节和最后一节的全部内容!
模型微调
微调模型可能是你将要做的事情, 因为并非所有问题都像在本教程第一部分中看到的那样简单。如上所读, 你可能已经要调整两个关键的决定:要使用多少个图层以及为每个图层选择多少个” 隐藏单位” 。
从一开始, 这确实是一个漫长的旅程。
添加图层 如果在模型中添加另一层会发生什么?如果看起来像这样怎么办?
model = Sequential()model.add(Dense(64, input_dim=12, activation='relu'))model.add(Dense(64, activation='relu'))model.add(Dense(1))

隐藏的单位 还可以尝试向模型的架构中添加更多隐藏单元的效果, 并研究对评估的效果, 如下所示:
model = Sequential()model.add(Dense(128, input_dim=12, activation='relu'))model.add(Dense(1))

再次提醒你, 通常来说, 由于你没有大量数据, 因此过度拟合的情况可能并将会越来越严重。因此, 你应该使用小型网络。
更多实验:优化参数 除了添加层并使用隐藏单元之外, 你还可以尝试调整提供给compile()函数的优化算法的(某些)参数。到目前为止, 你始终将诸如rmsprop之类的字符串传递给优化程序参数。
但这并不总是需要像这样!
例如, 尝试从keras.models导入RMSprop并调整学习率lr。你也可以更改为RMSprop()的其他参数设置的默认值, 但是不建议这样做。你可以在此处获取更多信息。
from keras.optimizers import RMSproprmsprop = RMSprop(lr=0.0001)model.compile(optimizer=rmsprop, loss='mse', metrics=['mae'])

另外, 请尝试尝试使用其他优化算法, 例如随机梯度下降(SGD)。你注意到效果了吗?
from keras.optimizers import SGD, RMSpropsgd=SGD(lr=0.1)model.compile(optimizer=sgd, loss='mse', metrics=['mae'])

走得更远! 【Keras教程(Python深度学习)】本教程只是你使用Python和Keras进行深度学习的起点。还有很多内容要讲, 为什么不参加srcmini的Python深度学习课程呢?同时, 请确保还查看Keras文档(如果你尚未这样做的话)。你将找到有关所有函数, 参数, 更多层等的更多示例和信息。当你学习如何在Python中使用神经网络时, 它无疑是必不可少的资源!如果你反而想读一本解释深度学习基础知识(使用Keras)以及其在实践中的用法的书, 则你绝对应该阅读Fran?oisChollet的《 Python深度学习》一书。

    推荐阅读