TensorFlow 2.0 教程学习记录(四)

目录

Basic regression: Predict fuel efficiency

基本回归:预测燃油效率

Auto MPG 数据集

获取数据 

数据清洗

将数据拆分为训练集和测试集

数据检查

从标签中分离特征

数据规范化

模型

构建模型

训练模型

做预测

结论


我们将会使用这个已经归一化的数据来训练模型。

警告: 用于归一化输入的数据统计(均值和标准差)需要反馈给模型从而应用于任何其他数据,以及我们之前所获得独热码。这些数据包含测试数据集以及生产环境中所使用的实时数据。

Basic regression: Predict fuel efficiency

基本回归:预测燃油效率

在  回归 (regression) 问题中,我们的目的是预测出如价格或概率这样连续值的输出。
相对于 分类(classification) 问题, 分类(classification) 的目的是从一系列的分类出选择出一个分类 (如,给出一张包含苹果或橘子的图片,识别出图片中是哪种水果)。
此教程使用经典的  Auto MPG 数据集并演示了如何构建模型来预测 20 世纪 70 年代末和 20 世纪 80 年代初汽车的燃油效率。为此,您需要为模型提供该时期的许多汽车的描述。这种描述包括诸如气缸、排量、马力和重量等特性。
# Use seaborn for pairplot.使用 seaborn 绘制矩阵图 (pairplot)
!pip install -q seaborn

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
# Make NumPy printouts easier to read.使NumPy打印输出更易于阅读。
np.set_printoptions(precision=3, suppress=True)

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
print(tf.__version__)
#2.9.2

Auto MPG 数据集

获取数据 

下载数据集。
url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data'
column_names = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight',
                'Acceleration', 'Model Year', 'Origin']
#列名:“MPG”、“气缸”、“排量”、“马力”、“重量”、“加速”、“车型年份”、“原产地”。
#使用 pandas 导入数据集。
raw_dataset = pd.read_csv(url, 
              names=column_names,
              na_values='?', 
              comment='\t',
              sep=' ', 
              skipinitialspace=True)

dataset = raw_dataset.copy()
dataset.tail()#显示数据集部分数据集。tail()的意思是显示数据后5行的内容。

使用 pandas 导入数据集。

#pandas用来读入数据.url是导入的地址,names指定列的名称以列表表示。

#原数据中有数据缺失为?,na_values='?'可以将?标明为NAN(未知值)。

#comment='\t'的意思是忽略以\t(一个制表符)开头后的行内容,这部分内容不读入。

#sep=' '的意思是将数据中有空白的部分当作分隔符,用来分割不同列的数据。(指定分隔符,默认为逗号’,’)

#skipinitialspace=True的意思则是忽略分隔符后的空白。

数据清洗

数据集包含一些未知值:

dataset.isna().sum()
#显示为空值(NAN)的特征类别和数目。

#为了保证此初始教程简单,请删除这些行:
dataset = dataset.dropna()
#处理这些缺省值,处理缺省值的方式有很多种,比如去掉,取中位数,平均值等等。这里选取的是去掉。
#因为空值数据不多,因此我们直接用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()

将数据拆分为训练集和测试集

现在,将数据集拆分为训练集和测试集。您将在模型的最终评估中使用测试集。

#采用sample函数进行训练集分割,其中frac参数为分割比例,random_state=0意思取得的数据不重复,如果等于1则是代表取得的数据可以重复。
#测试集就是训练集剩下的部分,我们用drop函数移除训练集的部分,剩下的部分自然就是测试集,并用变量保存起来。
train_dataset = dataset.sample(frac=0.8, random_state=0)#分割80%训练集,取不重复的数据
test_dataset = dataset.drop(train_dataset.index)#分割20测试集

数据检查

检查训练集中几对列的联合分布。第一行表明燃油效率 (MPG) 是所有其他参数的函数。其他行表示它们是彼此的函数

sns.pairplot(train_dataset[['MPG', 'Cylinders', 'Displacement', 'Weight']], diag_kind='kde')
#diag_kind='kde'为图的设定,若是单变量图(自己和自己比较)则是线性图,若是不同变量比较则为散点图。

也可以查看总体的数据统计:

train_stats = train_dataset.describe()#.describe()查看数据统计的参数值
train_stats.pop("MPG")
train_stats = train_stats.transpose()#.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' 的函数中,稍后我们将会创建第二个模型。 两个密集连接的隐藏层。

  • 均方误差(MSE)是用于回归问题的常见损失函数(分类问题中使用不同的损失函数)。
  • 类似的,用于回归的评估指标与分类不同。 常见的回归指标是平均绝对误差(MAE)。
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)
  ])

#优化器使用RMSprop,学习率选择为0.001,
  optimizer = tf.keras.optimizers.RMSprop(0.001)
#模型设置
  model.compile(loss='mse',  #损失函数选择为mse(mean-square error均方误差)
                optimizer=optimizer,
                metrics=['mae', 'mse'])  #度量的参数为mae(绝对值误差)和mse(均方误差)的loss
  return model

model = build_model()

#检查模型 打印模型概要
model.summary()

现在试用下这个模型。从训练数据中批量获取‘10’条例子并对这些例子调用 model.predict 。

example_batch = normed_train_data[:10]#取前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 = model.fit(
  normed_train_data, train_labels,
  epochs=1000, validation_split = 0.2, verbose=2)

参考于Tensorflow2.0学习(六) — 线性回归模型(燃油效率预测)_Yohann、的博客-CSDN博客

使用 history 对象中存储的统计信息可视化模型的训练进度。

该图表显示在约100个 epochs 之后误差非但没有改进,反而出现恶化。 让我们更新 model.fit 调用,当验证值没有提高上是自动停止训练。 我们将使用一个 EarlyStopping callback 来测试每个 epoch 的训练条件。如果经过一定数量的 epochs 后没有改进,则自动停止训练。

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 后没有改进,则自动停止训练。

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)。
  • 当数字输入数据特征的值存在不同范围时,每个特征应独立缩放到相同范围。
  • 如果训练数据不多,一种方法是选择隐藏层较少的小网络,以避免过度拟合。
  • 早期停止是一种防止过度拟合的有效技术。
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值