Deep Learning in Keras - Building a Deep Learning Model
介绍
深度学习是当前人工智能(AI)和机器学习中最有趣和最有前途的领域之一。 近年来,随着技术和算法的巨大进步,深度学习为AI应用的新时代打开了大门。
在许多此类应用中,深度学习算法的性能与人类专家相当,有时甚至超过了专家。
Python已成为机器学习的首选语言,并且许多最流行,功能最强大的深度学习库和框架(例如TensorFlow,Keras和PyTorch)都是用Python构建的。
在本系列中,我们将使用Keras进行探索性数据分析(EDA),数据预处理,最后构建一个深度学习模型并对其进行评估。
在这个阶段,我们将建立一个深度神经网络模型,我们将对其进行训练,然后将其用于预测房价。
定义模型
深度学习神经网络只是具有许多隐藏层的神经网络。
定义模型可以分为几个特征:
层数
这些层的类型
每层中的单元(神经元)数
各层的激活功能
输入输出尺寸
深度学习层
深度学习模型有很多类型的层。 卷积层和池化层用于对图像进行分类或对象检测的CNN中,而递归层用于自然语言处理和语音识别中常见的RNN中。
我们将使用Dense和Dropout层。 密集层是最常见和最受欢迎的层类型-它只是常规的神经网络层,其中每个神经元都与上一层和下一层的神经元相连。
每个密集层都有一个激活功能,可以根据输入和突触的权重来确定其神经元的输出。
辍学层只是正则化层,它们将一些输入单元随机地降低为0。这有助于减少过度拟合神经网络的机会。
激活功能
还可以将许多类型的激活功能应用于图层。 它们每个都以不同的方式链接神经元的输入和权重,并使网络的行为不同。
真正常见的功能是ReLU(整流线性单元),Sigmoid函数和线性函数。 我们将混合几个不同的功能。
输入和输出层
除了隐藏层,模型还具有输入层和输出层:
输入层中神经元的数量与我们数据中要素的数量相同。 我们想教网络对这些功能做出反应。 我们在
对于输出层-神经元的数量取决于您的目标。 由于我们只是在预测价格-一个单一的值,因此我们将仅使用一个神经元。 分类模型将具有
由于模型的输出将是一个连续的数字,因此我们将使用
定义模型代码
我们将在前面的代码中使用一些导入:
1 2 3 4 5 6 7 8 9 | import matplotlib.pyplot as plt from matplotlib import ticker import numpy as np import pandas as pd import seaborn as sns import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers |
考虑到这些导入和参数,让我们使用Keras定义模型:
1 2 3 4 5 6 7 8 9 10 | model = keras.Sequential([ layers.Dense(64, activation='relu', input_shape=[train_df.shape[1]]), layers.Dropout(0.3, seed=2), layers.Dense(64, activation='swish'), layers.Dense(64, activation='relu'), layers.Dense(64, activation='swish'), layers.Dense(64, activation='relu'), layers.Dense(64, activation='swish'), layers.Dense(1) ]) |
在这里,我们使用Keras的
在此模型中,我们制作了几个
每层有64个神经元。 这通常取决于测试-每层放置更多的神经元将有助于提取更多特征,但是有时这些特征也可能对您不利。 经过一些测试,在此示例中,每层64个神经元产生了相当准确的结果。 强烈建议您使用数字!
为了避免过度拟合,我们迅速删除了30%的输入数据。
最后,我们有一个
编译模型
定义模型后,下一步是对其进行编译。 编译Keras模型意味着对其进行配置以进行训练。
要编译模型,我们需要选择:
损失函数-误差越小,模型越接近目标。 不同的问题需要不同的损失函数来跟踪进度。 这是受支持的损失函数的列表。
优化器-帮助我们获得损失函数更好结果的优化算法。
指标-用于评估模型的指标。 例如,如果我们具有均方误差损失函数,则使用均绝对误差作为用于评估的度量是有意义的。
考虑到这些,让我们编译模型:
1 2 3 4 5 | optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.001) model.compile(loss=tf.keras.losses.MeanSquaredError(), optimizer=optimizer, metrics=['mae']) |
在这里,我们创建了一个
注意:您可以声明优化器并使用该对象,也可以在
我们将损失函数设置为均方误差。 同样,请随意尝试其他损失函数并评估结果。 由于我们将MSE作为损失函数,因此我们选择了"平均绝对误差"作为评估模型的指标。
训练模型
编译模型后,我们可以使用我们的
1 2 3 4 | history = model.fit( train_df, train_labels, epochs=70, validation_split=0.2 ) |
在这里,我们传递了训练数据(
同样,学习是一个反复的过程。 我们已通知网络,该网络要遍历该训练数据集70次,以从中学习尽可能多的信息。 在最后一个时期的模型结果将比在第一个时期更好。
最后,我们传递用于验证的训练数据。 具体来说,我们告诉它使用训练数据的
这20%不会用于培训,而是用于验证以确保其取得进展。
此函数将打印每个时期的结果-损失函数的值以及我们选择要跟踪的度量。
完成后,我们可以看一下每个时期的完成情况:
1 2 3 4 5 6 7 8 9 10 11 12 | Epoch 65/70 59/59 [==============================] - 0s 2ms/step - loss: 983458944.0000 - mae: 19101.9668 - val_loss: 672429632.0000 - val_mae: 18233.3066 Epoch 66/70 59/59 [==============================] - 0s 2ms/step - loss: 925556032.0000 - mae: 18587.1133 - val_loss: 589675840.0000 - val_mae: 16720.8945 Epoch 67/70 59/59 [==============================] - 0s 2ms/step - loss: 1052588800.0000 - mae: 18792.9805 - val_loss: 608930944.0000 - val_mae: 16897.8262 Epoch 68/70 59/59 [==============================] - 0s 2ms/step - loss: 849525312.0000 - mae: 18392.6055 - val_loss: 613655296.0000 - val_mae: 16914.1777 Epoch 69/70 59/59 [==============================] - 0s 2ms/step - loss: 826159680.0000 - mae: 18177.8945 - val_loss: 588994816.0000 - val_mae: 16520.2832 Epoch 70/70 59/59 [==============================] - 0s 2ms/step - loss: 920209344.0000 - mae: 18098.7070 - val_loss: 571053952.0000 - val_mae: 16419.8359 |
训练后,该模型(存储在
在进行预测之前,让我们直观地看到损失值和
1 2 3 4 5 6 7 8 9 10 11 12 | model_history = pd.DataFrame(history.history) model_history['epoch'] = history.epoch fig, ax = plt.subplots(figsize=(14,8)) num_epochs = model_history.shape[0] ax.plot(np.arange(0, num_epochs), model_history["mae"], label="Training MAE", lw=3, color='#f4b400') ax.plot(np.arange(0, num_epochs), model_history["val_mae"], label="Validation MAE", lw=3, color='#0f9d58') ax.legend() plt.tight_layout() plt.show() |
我们可以清楚地看到
用模型进行预测
现在我们的模型已经训练完毕,让我们使用它来进行一些预测。 我们从测试数据中提取一个项目(在
1 | test_unit = test_df.iloc[[0]] |
为简便起见,存储在
这些是要素单元的值,我们将使用该模型预测其售价:
1 | test_pred = model.predict(test_unit).squeeze() |
我们使用模型的
注意:
现在,让我们从
1 | test_lbl = test_labels.iloc[0] |
现在,让我们比较一下预测价格和实际价格:
1 2 | print("Model prediction = {:.2f}".format(test_pred)) print("Actual value = {:.2f}".format(test_lbl)) |
1 2 | Model prediction = 225694.92 Actual value = 212000.00 |
因此,此单元的实际销售价格为212,000美元,我们的模型预测为$ * 225,694 *。 尽管该型号的价格超过了5%,但价格已经相当接近。
让我们尝试
1 | test_unit = test_df.iloc[[100]] |
我们将重复相同的过程以比较价格:
1 2 3 4 | test_pred = model.predict(test_unit).squeeze() test_lbl = test_labels.iloc[100] print("Model prediction = {:.2f}".format(test_pred)) print("Actual value = {:.2f}".format(test_lbl)) |
1 2 | Model prediction = 330350.47 Actual value = 340000.00 |
因此,对于该单元,实际价格为$ 340,000,而预测价格为?* $ 330,350 *。 再说一次,不是很准确,但这只是约3%的误差。 那是非常准确的。
评估模型
这是我们构建Keras深度学习模型的旅程的最后阶段。 在此阶段,我们将使用模型在测试数据(
Keras提供了
我们选择MAE作为我们的指标,因为它很容易解释。 MAE值表示模型误差的平均值:
$$
egin {equation *}
ext {MAE}(y,hat {y})= rac {1} {n} sum_ {i = 1} ^ {n} left | y_i-帽子{y} _i
ight |。
结束{equation *}
$$
为了我们的方便,
1 | loss, mae = model.evaluate(test_df, test_labels, verbose=0) |
对于这种方法,我们传递模型的测试数据(待评估)和实际数据(进行比较)。 此外,我们使用了
让我们运行代码,看看它是如何工作的:
1 | print('MAE = {:.2f}'.format(mae)) |
1 | MAE = 17239.13 |
平均绝对误差为
解释模型性能
结果有多好? 如果我们回顾在
为了用另一种方式解释这些结果,让我们将预测与实际价格作图:
1 2 3 4 5 6 7 8 9 | test_predictions_ = model.predict(test_df).flatten() test_labels_ = test_labels.to_numpy().flatten() fig, ax = plt.subplots(figsize=(14,8)) plt.scatter(test_labels_, test_predictions_, alpha=0.6, color='#ff7043', lw=1, ec='black') lims = [0, max(test_predictions_.max(), test_labels_.max())] plt.plot(lims, lims, lw=1, color='#00acc1') plt.tight_layout() plt.show() |
如果我们的模型在0 MAE情况下是100%准确的,则所有点都将精确显示在对角青色线上。 但是,没有一个模型是100%准确的,并且我们可以看到大多数点都靠近对角线,这意味着预测值接近于实际值。
有一些离群值,其中一些离得很远。 这些使我们模型的平均MAE大大提高。 实际上,对于这些要点中的大多数而言,MAE远小于17,239。
我们可以检查这些点并找出是否可以执行更多数据预处理和特征工程,以使模型更准确地预测它们。
结论
在本教程中,我们使用Keras构建了一个深度学习模型,对其进行了编译,并使用我们准备的干净数据进行了拟合,最后-根据所学知识进行了预测。
尽管不是100%准确,但我们设法以少量异常值获得了非常不错的结果。