diff --git "a/docs/TensorFlow2.x/\345\256\236\346\210\230\351\241\271\347\233\256_2_\346\261\275\350\275\246\347\207\203\346\262\271\346\225\210\347\216\207.md" "b/docs/TensorFlow2.x/\345\256\236\346\210\230\351\241\271\347\233\256_2_\346\261\275\350\275\246\347\207\203\346\262\271\346\225\210\347\216\207.md" new file mode 100644 index 0000000000000000000000000000000000000000..4da1a3d6192306bb9fdbd8f1677aa4506196aaa6 --- /dev/null +++ "b/docs/TensorFlow2.x/\345\256\236\346\210\230\351\241\271\347\233\256_2_\346\261\275\350\275\246\347\207\203\346\262\271\346\225\210\347\216\207.md" @@ -0,0 +1,903 @@ +# 实战项目_2_汽车燃油效率 + +Note: 我们的 TensorFlow 社区翻译了这些文档。因为社区翻译是尽力而为, 所以无法保证它们是最准确的,并且反映了最新的 +[官方英文文档](https://www.tensorflow.org/?hl=en)。如果您有改进此翻译的建议, 请提交 pull request 到 +[tensorflow/docs](https://github.com/tensorflow/docs) GitHub 仓库。要志愿地撰写或者审核译文,请加入 +[docs-zh-cn@tensorflow.org Google Group](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs-zh-cn)。 + +在 *回归 (regression)* 问题中,我们的目的是预测出如价格或概率这样连续值的输出。相对于*分类(classification)* 问题,*分类(classification)* 的目的是从一系列的分类出选择出一个分类 (如,给出一张包含苹果或橘子的图片,识别出图片中是哪种水果)。 + +本 notebook 使用经典的 [Auto MPG](https://archive.ics.uci.edu/ml/datasets/auto+mpg) 数据集,构建了一个用来预测70年代末到80年代初汽车燃油效率的模型。为了做到这一点,我们将为该模型提供许多那个时期的汽车描述。这个描述包含:气缸数,排量,马力以及重量。 + +本示例使用 `tf.keras` API,相关细节请参阅 [本指南](https://tensorflow.google.cn/guide/keras)。 + + +```python +# 使用 seaborn 绘制矩阵图 (pairplot) +!pip install seaborn +``` + + Requirement already satisfied: seaborn in /usr/local/lib/python3.6/dist-packages (0.9.0) + Requirement already satisfied: scipy>=0.14.0 in /usr/local/lib/python3.6/dist-packages (from seaborn) (1.3.1) + Requirement already satisfied: numpy>=1.9.3 in /usr/local/lib/python3.6/dist-packages (from seaborn) (1.16.5) + Requirement already satisfied: matplotlib>=1.4.3 in /usr/local/lib/python3.6/dist-packages (from seaborn) (3.0.3) + Requirement already satisfied: pandas>=0.15.2 in /usr/local/lib/python3.6/dist-packages (from seaborn) (0.24.2) + Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib>=1.4.3->seaborn) (2.4.2) + Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib>=1.4.3->seaborn) (1.1.0) + Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.6/dist-packages (from matplotlib>=1.4.3->seaborn) (0.10.0) + Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib>=1.4.3->seaborn) (2.5.3) + Requirement already satisfied: pytz>=2011k in /usr/local/lib/python3.6/dist-packages (from pandas>=0.15.2->seaborn) (2018.9) + Requirement already satisfied: setuptools in /usr/local/lib/python3.6/dist-packages (from kiwisolver>=1.0.1->matplotlib>=1.4.3->seaborn) (41.4.0) + Requirement already satisfied: six in /usr/local/lib/python3.6/dist-packages (from cycler>=0.10->matplotlib>=1.4.3->seaborn) (1.12.0) + + + +```python +from __future__ import absolute_import, division, print_function, unicode_literals + +import pathlib + +import matplotlib.pyplot as plt +import pandas as pd +import seaborn as sns + +try: + # %tensorflow_version only exists in Colab. + %tensorflow_version 2.x +except Exception: + pass +import tensorflow as tf + +from tensorflow import keras +from tensorflow.keras import layers + +print(tf.__version__) +``` + + TensorFlow 2.x selected. + 2.0.0 + + +## Auto MPG 数据集 + +该数据集可以从 [UCI机器学习库](https://archive.ics.uci.edu/ml/) 中获取. + + + +### 获取数据 +首先下载数据集。 + + +```python +dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data") +dataset_path +``` + + Downloading data from http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data + 32768/30286 [================================] - 0s 4us/step + + + + + + '/root/.keras/datasets/auto-mpg.data' + + + +使用 pandas 导入数据集。 + + +```python +column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight', + 'Acceleration', 'Model Year', 'Origin'] +raw_dataset = pd.read_csv(dataset_path, names=column_names, + na_values = "?", comment='\t', + sep=" ", skipinitialspace=True) + +dataset = raw_dataset.copy() +dataset.tail() +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MPGCylindersDisplacementHorsepowerWeightAccelerationModel YearOrigin
39327.04140.086.02790.015.6821
39444.0497.052.02130.024.6822
39532.04135.084.02295.011.6821
39628.04120.079.02625.018.6821
39731.04119.082.02720.019.4821
+
+ + + +### 数据清洗 + +数据集中包括一些未知值。 + + +```python +dataset.isna().sum() +``` + + + + + MPG 0 + Cylinders 0 + Displacement 0 + Horsepower 6 + Weight 0 + Acceleration 0 + Model Year 0 + Origin 0 + dtype: int64 + + + +为了保证这个初始示例的简单性,删除这些行。 + + +```python +dataset = dataset.dropna() +``` + +`"Origin"` 列实际上代表分类,而不仅仅是一个数字。所以把它转换为独热码 (one-hot): + + +```python +origin = dataset.pop('Origin') +``` + + +```python +dataset['USA'] = (origin == 1)*1.0 +dataset['Europe'] = (origin == 2)*1.0 +dataset['Japan'] = (origin == 3)*1.0 +dataset.tail() +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MPGCylindersDisplacementHorsepowerWeightAccelerationModel YearUSAEuropeJapan
39327.04140.086.02790.015.6821.00.00.0
39444.0497.052.02130.024.6820.01.00.0
39532.04135.084.02295.011.6821.00.00.0
39628.04120.079.02625.018.6821.00.00.0
39731.04119.082.02720.019.4821.00.00.0
+
+ + + +### 拆分训练数据集和测试数据集 + +现在需要将数据集拆分为一个训练数据集和一个测试数据集。 + +我们最后将使用测试数据集对模型进行评估。 + + +```python +train_dataset = dataset.sample(frac=0.8,random_state=0) +test_dataset = dataset.drop(train_dataset.index) +``` + +### 数据检查 + +快速查看训练集中几对列的联合分布。 + + +```python +sns.pairplot(train_dataset[["MPG", "Cylinders", "Displacement", "Weight"]], diag_kind="kde") +``` + + + + + + + + + +![png](http://data.apachecn.org/img/AiLearning/TensorFlow2.x/output_23_1.png) + + +也可以查看总体的数据统计: + + +```python +train_stats = train_dataset.describe() +train_stats.pop("MPG") +train_stats = train_stats.transpose() +train_stats +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
countmeanstdmin25%50%75%max
Cylinders314.05.4777071.6997883.04.004.08.008.0
Displacement314.0195.318471104.33158968.0105.50151.0265.75455.0
Horsepower314.0104.86942738.09621446.076.2594.5128.00225.0
Weight314.02990.251592843.8985961649.02256.502822.53608.005140.0
Acceleration314.015.5592362.7892308.013.8015.517.2024.8
Model Year314.075.8980893.67564270.073.0076.079.0082.0
USA314.00.6242040.4851010.00.001.01.001.0
Europe314.00.1783440.3834130.00.000.00.001.0
Japan314.00.1974520.3987120.00.000.00.001.0
+
+ + + +### 从标签中分离特征 + +将特征值从目标值或者"标签"中分离。 这个标签是你使用训练模型进行预测的值。 + + +```python +train_labels = train_dataset.pop('MPG') +test_labels = test_dataset.pop('MPG') +``` + +### 数据规范化 + +再次审视下上面的 `train_stats` 部分,并注意每个特征的范围有什么不同。 + +使用不同的尺度和范围对特征归一化是好的实践。尽管模型*可能* 在没有特征归一化的情况下收敛,它会使得模型训练更加复杂,并会造成生成的模型依赖输入所使用的单位选择。 + +注意:尽管我们仅仅从训练集中有意生成这些统计数据,但是这些统计信息也会用于归一化的测试数据集。我们需要这样做,将测试数据集放入到与已经训练过的模型相同的分布中。 + + +```python +def norm(x): + return (x - train_stats['mean']) / train_stats['std'] +normed_train_data = norm(train_dataset) +normed_test_data = norm(test_dataset) +``` + +我们将会使用这个已经归一化的数据来训练模型。 + +警告: 用于归一化输入的数据统计(均值和标准差)需要反馈给模型从而应用于任何其他数据,以及我们之前所获得独热码。这些数据包含测试数据集以及生产环境中所使用的实时数据。 + +## 模型 + +### 构建模型 + +让我们来构建我们自己的模型。这里,我们将会使用一个“顺序”模型,其中包含两个紧密相连的隐藏层,以及返回单个、连续值得输出层。模型的构建步骤包含于一个名叫 'build_model' 的函数中,稍后我们将会创建第二个模型。 两个密集连接的隐藏层。 + + +```python +def build_model(): + model = keras.Sequential([ + layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]), + layers.Dense(64, activation='relu'), + layers.Dense(1) + ]) + + optimizer = tf.keras.optimizers.RMSprop(0.001) + + model.compile(loss='mse', + optimizer=optimizer, + metrics=['mae', 'mse']) + return model +``` + + +```python +model = build_model() +``` + +### 检查模型 + +使用 `.summary` 方法来打印该模型的简单描述。 + + +```python +model.summary() +``` + + Model: "sequential" + _________________________________________________________________ + Layer (type) Output Shape Param # + ================================================================= + dense (Dense) (None, 64) 640 + _________________________________________________________________ + dense_1 (Dense) (None, 64) 4160 + _________________________________________________________________ + dense_2 (Dense) (None, 1) 65 + ================================================================= + Total params: 4,865 + Trainable params: 4,865 + Non-trainable params: 0 + _________________________________________________________________ + + + +现在试用下这个模型。从训练数据中批量获取‘10’条例子并对这些例子调用 `model.predict` 。 + + + +```python +example_batch = normed_train_data[:10] +example_result = model.predict(example_batch) +example_result +``` + + WARNING:tensorflow:Falling back from v2 loop because of error: Failed to find data adapter that can handle input: , + + + + + + array([[ 0.37002987], + [ 0.22292587], + [ 0.7729857 ], + [ 0.22504307], + [-0.01411032], + [ 0.25664118], + [ 0.05221634], + [-0.0256409 ], + [ 0.23223272], + [-0.00434934]], dtype=float32) + + + +它似乎在工作,并产生了预期的形状和类型的结果 + +### 训练模型 + +对模型进行1000个周期的训练,并在 `history` 对象中记录训练和验证的准确性。 + + +```python +# 通过为每个完成的时期打印一个点来显示训练进度 +class PrintDot(keras.callbacks.Callback): + def on_epoch_end(self, epoch, logs): + if epoch % 100 == 0: print('') + print('.', end='') + +EPOCHS = 1000 + +history = model.fit( + normed_train_data, train_labels, + epochs=EPOCHS, validation_split = 0.2, verbose=0, + callbacks=[PrintDot()]) +``` + + WARNING:tensorflow:Falling back from v2 loop because of error: Failed to find data adapter that can handle input: , + + .................................................................................................... + .................................................................................................... + .................................................................................................... + .................................................................................................... + .................................................................................................... + .................................................................................................... + .................................................................................................... + .................................................................................................... + .................................................................................................... + .................................................................................................... + +使用 `history` 对象中存储的统计信息可视化模型的训练进度。 + + +```python +hist = pd.DataFrame(history.history) +hist['epoch'] = history.epoch +hist.tail() +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
lossmaemseval_lossval_maeval_mseepoch
9952.2784290.9682912.2784298.6458832.2280308.645884995
9962.3008970.9556932.3008978.5265612.2542998.526561996
9972.3025050.9370352.3025058.6623122.2048578.662312997
9982.2653670.9426472.2653678.3191092.2241388.319109998
9992.2249380.9850292.2249388.4040062.2413038.404006999
+
+ + + + +```python +def plot_history(history): + hist = pd.DataFrame(history.history) + hist['epoch'] = history.epoch + + plt.figure() + plt.xlabel('Epoch') + plt.ylabel('Mean Abs Error [MPG]') + plt.plot(hist['epoch'], hist['mae'], + label='Train Error') + plt.plot(hist['epoch'], hist['val_mae'], + label = 'Val Error') + plt.ylim([0,5]) + plt.legend() + + plt.figure() + plt.xlabel('Epoch') + plt.ylabel('Mean Square Error [$MPG^2$]') + plt.plot(hist['epoch'], hist['mse'], + label='Train Error') + plt.plot(hist['epoch'], hist['val_mse'], + label = 'Val Error') + plt.ylim([0,20]) + plt.legend() + plt.show() + + +plot_history(history) +``` + + +![png](http://data.apachecn.org/img/AiLearning/TensorFlow2.x/output_45_0.png) + + + +![png](http://data.apachecn.org/img/AiLearning/TensorFlow2.x/output_45_1.png) + + +该图表显示在约100个 epochs 之后误差非但没有改进,反而出现恶化。 让我们更新 `model.fit` 调用,当验证值没有提高上是自动停止训练。 +我们将使用一个 *EarlyStopping callback* 来测试每个 epoch 的训练条件。如果经过一定数量的 epochs 后没有改进,则自动停止训练。 + +你可以从[这里](https://tensorflow.google.cn/versions/master/api_docs/python/tf/keras/callbacks/EarlyStopping)学习到更多的回调。 + + +```python +model = build_model() + +# patience 值用来检查改进 epochs 的数量 +early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10) + +history = model.fit(normed_train_data, train_labels, epochs=EPOCHS, + validation_split = 0.2, verbose=0, callbacks=[early_stop, PrintDot()]) + +plot_history(history) +``` + + WARNING:tensorflow:Falling back from v2 loop because of error: Failed to find data adapter that can handle input: , + + ........................................................ + + +![png](http://data.apachecn.org/img/AiLearning/TensorFlow2.x/output_47_1.png) + + + +![png](http://data.apachecn.org/img/AiLearning/TensorFlow2.x/output_47_2.png) + + +如图所示,验证集中的平均的误差通常在 +/- 2 MPG左右。 这个结果好么? 我们将决定权留给你。 + +让我们看看通过使用 **测试集** 来泛化模型的效果如何,我们在训练模型时没有使用测试集。这告诉我们,当我们在现实世界中使用这个模型时,我们可以期望它预测得有多好。 + + +```python +loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=2) + +print("Testing set Mean Abs Error: {:5.2f} MPG".format(mae)) +``` + + WARNING:tensorflow:Falling back from v2 loop because of error: Failed to find data adapter that can handle input: , + 78/78 - 0s - loss: 5.8737 - mae: 1.8844 - mse: 5.8737 + Testing set Mean Abs Error: 1.88 MPG + + +### 做预测 + +最后,使用测试集中的数据预测 MPG 值: + + +```python +test_predictions = model.predict(normed_test_data).flatten() + +plt.scatter(test_labels, test_predictions) +plt.xlabel('True Values [MPG]') +plt.ylabel('Predictions [MPG]') +plt.axis('equal') +plt.axis('square') +plt.xlim([0,plt.xlim()[1]]) +plt.ylim([0,plt.ylim()[1]]) +_ = plt.plot([-100, 100], [-100, 100]) + +``` + + WARNING:tensorflow:Falling back from v2 loop because of error: Failed to find data adapter that can handle input: , + + + +![png](http://data.apachecn.org/img/AiLearning/TensorFlow2.x/output_51_1.png) + + +这看起来我们的模型预测得相当好。我们来看下误差分布。 + + +```python +error = test_predictions - test_labels +plt.hist(error, bins = 25) +plt.xlabel("Prediction Error [MPG]") +_ = plt.ylabel("Count") +``` + + +![png](http://data.apachecn.org/img/AiLearning/TensorFlow2.x/output_53_0.png) + + +它不是完全的高斯分布,但我们可以推断出,这是因为样本的数量很小所导致的。 + +## 结论 + +本笔记本 (notebook) 介绍了一些处理回归问题的技术。 + +* 均方误差(MSE)是用于回归问题的常见损失函数(分类问题中使用不同的损失函数)。 +* 类似的,用于回归的评估指标与分类不同。 常见的回归指标是平均绝对误差(MAE)。 +* 当数字输入数据特征的值存在不同范围时,每个特征应独立缩放到相同范围。 +* 如果训练数据不多,一种方法是选择隐藏层较少的小网络,以避免过度拟合。 +* 早期停止是一种防止过度拟合的有效技术。 diff --git a/src/py3.x/tensorflow2.x/text_regression.py b/src/py3.x/tensorflow2.x/text_regression.py new file mode 100644 index 0000000000000000000000000000000000000000..20efcab1bf8d7433f073a1c2b6e64cf9aa33aa43 --- /dev/null +++ b/src/py3.x/tensorflow2.x/text_regression.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +"""text_regression.ipynb + +Note: 我们的 TensorFlow 社区翻译了这些文档。因为社区翻译是尽力而为, 所以无法保证它们是最准确的,并且反映了最新的 +[官方英文文档](https://www.tensorflow.org/?hl=en)。如果您有改进此翻译的建议, 请提交 pull request 到 +[tensorflow/docs](https://github.com/tensorflow/docs) GitHub 仓库。要志愿地撰写或者审核译文,请加入 +[docs-zh-cn@tensorflow.org Google Group](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs-zh-cn)。 + +在 *回归 (regression)* 问题中,我们的目的是预测出如价格或概率这样连续值的输出。相对于*分类(classification)* 问题,*分类(classification)* 的目的是从一系列的分类出选择出一个分类 (如,给出一张包含苹果或橘子的图片,识别出图片中是哪种水果)。 + +本 notebook 使用经典的 [Auto MPG](https://archive.ics.uci.edu/ml/datasets/auto+mpg) 数据集,构建了一个用来预测70年代末到80年代初汽车燃油效率的模型。为了做到这一点,我们将为该模型提供许多那个时期的汽车描述。这个描述包含:气缸数,排量,马力以及重量。 + +本示例使用 `tf.keras` API,相关细节请参阅 [本指南](https://tensorflow.google.cn/guide/keras)。 +""" + +# 使用 seaborn 绘制矩阵图 (pairplot) +!pip install seaborn + +# Commented out IPython magic to ensure Python compatibility. +from __future__ import absolute_import, division, print_function, unicode_literals + +import pathlib + +import matplotlib.pyplot as plt +import pandas as pd +import seaborn as sns + +try: + # %tensorflow_version only exists in Colab. +# %tensorflow_version 2.x +except Exception: + pass +import tensorflow as tf + +from tensorflow import keras +from tensorflow.keras import layers + +print(tf.__version__) + +"""## Auto MPG 数据集 + +该数据集可以从 [UCI机器学习库](https://archive.ics.uci.edu/ml/) 中获取. + +### 获取数据 +首先下载数据集。 +""" + +dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data") +dataset_path + +"""使用 pandas 导入数据集。""" + +column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight', + 'Acceleration', 'Model Year', 'Origin'] +raw_dataset = pd.read_csv(dataset_path, names=column_names, + na_values = "?", comment='\t', + sep=" ", skipinitialspace=True) + +dataset = raw_dataset.copy() +dataset.tail() + +"""### 数据清洗 + +数据集中包括一些未知值。 +""" + +dataset.isna().sum() + +"""为了保证这个初始示例的简单性,删除这些行。""" + +dataset = dataset.dropna() + +"""`"Origin"` 列实际上代表分类,而不仅仅是一个数字。所以把它转换为独热码 (one-hot):""" + +origin = dataset.pop('Origin') + +dataset['USA'] = (origin == 1)*1.0 +dataset['Europe'] = (origin == 2)*1.0 +dataset['Japan'] = (origin == 3)*1.0 +dataset.tail() + +"""### 拆分训练数据集和测试数据集 + +现在需要将数据集拆分为一个训练数据集和一个测试数据集。 + +我们最后将使用测试数据集对模型进行评估。 +""" + +train_dataset = dataset.sample(frac=0.8,random_state=0) +test_dataset = dataset.drop(train_dataset.index) + +"""### 数据检查 + +快速查看训练集中几对列的联合分布。 +""" + +sns.pairplot(train_dataset[["MPG", "Cylinders", "Displacement", "Weight"]], diag_kind="kde") + +"""也可以查看总体的数据统计:""" + +train_stats = train_dataset.describe() +train_stats.pop("MPG") +train_stats = train_stats.transpose() +train_stats + +"""### 从标签中分离特征 + +将特征值从目标值或者"标签"中分离。 这个标签是你使用训练模型进行预测的值。 +""" + +train_labels = train_dataset.pop('MPG') +test_labels = test_dataset.pop('MPG') + +"""### 数据规范化 + +再次审视下上面的 `train_stats` 部分,并注意每个特征的范围有什么不同。 + +使用不同的尺度和范围对特征归一化是好的实践。尽管模型*可能* 在没有特征归一化的情况下收敛,它会使得模型训练更加复杂,并会造成生成的模型依赖输入所使用的单位选择。 + +注意:尽管我们仅仅从训练集中有意生成这些统计数据,但是这些统计信息也会用于归一化的测试数据集。我们需要这样做,将测试数据集放入到与已经训练过的模型相同的分布中。 +""" + +def norm(x): + return (x - train_stats['mean']) / train_stats['std'] +normed_train_data = norm(train_dataset) +normed_test_data = norm(test_dataset) + +"""我们将会使用这个已经归一化的数据来训练模型。 + +警告: 用于归一化输入的数据统计(均值和标准差)需要反馈给模型从而应用于任何其他数据,以及我们之前所获得独热码。这些数据包含测试数据集以及生产环境中所使用的实时数据。 + +## 模型 + +### 构建模型 + +让我们来构建我们自己的模型。这里,我们将会使用一个“顺序”模型,其中包含两个紧密相连的隐藏层,以及返回单个、连续值得输出层。模型的构建步骤包含于一个名叫 'build_model' 的函数中,稍后我们将会创建第二个模型。 两个密集连接的隐藏层。 +""" + +def build_model(): + model = keras.Sequential([ + layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]), + layers.Dense(64, activation='relu'), + layers.Dense(1) + ]) + + optimizer = tf.keras.optimizers.RMSprop(0.001) + + model.compile(loss='mse', + optimizer=optimizer, + metrics=['mae', 'mse']) + return model + +model = build_model() + +"""### 检查模型 + +使用 `.summary` 方法来打印该模型的简单描述。 +""" + +model.summary() + +"""现在试用下这个模型。从训练数据中批量获取‘10’条例子并对这些例子调用 `model.predict` 。""" + +example_batch = normed_train_data[:10] +example_result = model.predict(example_batch) +example_result + +"""它似乎在工作,并产生了预期的形状和类型的结果 + +### 训练模型 + +对模型进行1000个周期的训练,并在 `history` 对象中记录训练和验证的准确性。 +""" + +# 通过为每个完成的时期打印一个点来显示训练进度 +class PrintDot(keras.callbacks.Callback): + def on_epoch_end(self, epoch, logs): + if epoch % 100 == 0: print('') + print('.', end='') + +EPOCHS = 1000 + +history = model.fit( + normed_train_data, train_labels, + epochs=EPOCHS, validation_split = 0.2, verbose=0, + callbacks=[PrintDot()]) + +"""使用 `history` 对象中存储的统计信息可视化模型的训练进度。""" + +hist = pd.DataFrame(history.history) +hist['epoch'] = history.epoch +hist.tail() + +def plot_history(history): + hist = pd.DataFrame(history.history) + hist['epoch'] = history.epoch + + plt.figure() + plt.xlabel('Epoch') + plt.ylabel('Mean Abs Error [MPG]') + plt.plot(hist['epoch'], hist['mae'], + label='Train Error') + plt.plot(hist['epoch'], hist['val_mae'], + label = 'Val Error') + plt.ylim([0,5]) + plt.legend() + + plt.figure() + plt.xlabel('Epoch') + plt.ylabel('Mean Square Error [$MPG^2$]') + plt.plot(hist['epoch'], hist['mse'], + label='Train Error') + plt.plot(hist['epoch'], hist['val_mse'], + label = 'Val Error') + plt.ylim([0,20]) + plt.legend() + plt.show() + + +plot_history(history) + +"""该图表显示在约100个 epochs 之后误差非但没有改进,反而出现恶化。 让我们更新 `model.fit` 调用,当验证值没有提高上是自动停止训练。 +我们将使用一个 *EarlyStopping callback* 来测试每个 epoch 的训练条件。如果经过一定数量的 epochs 后没有改进,则自动停止训练。 + +你可以从[这里](https://tensorflow.google.cn/versions/master/api_docs/python/tf/keras/callbacks/EarlyStopping)学习到更多的回调。 +""" + +model = build_model() + +# patience 值用来检查改进 epochs 的数量 +early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10) + +history = model.fit(normed_train_data, train_labels, epochs=EPOCHS, + validation_split = 0.2, verbose=0, callbacks=[early_stop, PrintDot()]) + +plot_history(history) + +"""如图所示,验证集中的平均的误差通常在 +/- 2 MPG左右。 这个结果好么? 我们将决定权留给你。 + +让我们看看通过使用 **测试集** 来泛化模型的效果如何,我们在训练模型时没有使用测试集。这告诉我们,当我们在现实世界中使用这个模型时,我们可以期望它预测得有多好。 +""" + +loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=2) + +print("Testing set Mean Abs Error: {:5.2f} MPG".format(mae)) + +"""### 做预测 + +最后,使用测试集中的数据预测 MPG 值: +""" + +test_predictions = model.predict(normed_test_data).flatten() + +plt.scatter(test_labels, test_predictions) +plt.xlabel('True Values [MPG]') +plt.ylabel('Predictions [MPG]') +plt.axis('equal') +plt.axis('square') +plt.xlim([0,plt.xlim()[1]]) +plt.ylim([0,plt.ylim()[1]]) +_ = plt.plot([-100, 100], [-100, 100]) + +"""这看起来我们的模型预测得相当好。我们来看下误差分布。""" + +error = test_predictions - test_labels +plt.hist(error, bins = 25) +plt.xlabel("Prediction Error [MPG]") +_ = plt.ylabel("Count") + +"""它不是完全的高斯分布,但我们可以推断出,这是因为样本的数量很小所导致的。 + +## 结论 + +本笔记本 (notebook) 介绍了一些处理回归问题的技术。 + +* 均方误差(MSE)是用于回归问题的常见损失函数(分类问题中使用不同的损失函数)。 +* 类似的,用于回归的评估指标与分类不同。 常见的回归指标是平均绝对误差(MAE)。 +* 当数字输入数据特征的值存在不同范围时,每个特征应独立缩放到相同范围。 +* 如果训练数据不多,一种方法是选择隐藏层较少的小网络,以避免过度拟合。 +* 早期停止是一种防止过度拟合的有效技术。 +""" \ No newline at end of file