TensorFlow入门训练笔记(二)——基本回归:预测燃油效率

PS:1、本文旨在对TF学习过程进行备忘,本人菜得抠脚,故文章难免会有一定错误,还望指出,谢谢;
2、本文程序代码使用Google TensorFlow所给出的官方入门教程;
3、本文使用tf.keras,对模型进行构建与训练。
4、本文实现通过回归的方式,预测燃油效率MPG与车辆其他参数之间的关系,主要通过全连接层神经网络模型进行训练,在设定固定训练步长时,可能出现不收敛的问题,造成最终产生的模型预测效果甚至不如早期拟合度较高的部分,所以采取设定真实值与预测值平均误差阈值的方式,过大时自动停止训练,后用该模型进行预测。

1、数据获取与预处理

import pathlib

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

#print(tf.__version__)

#获取数据集
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.head()
#数据集中可能存在缺省值,需要clear这些数据
#统计空白数据
dataset.isna().sum()
#删除空白数据
dataset = dataset.dropna()
#再次统计空白数据
dataset.isna().sum()

#由于Origin字段为类别类型数据,我们需要将其移除,转换为USA,Europe,Japan
# 处理类别型数据,其中 origin 列代表了类别 1,2,3,分布代表产地:美国、欧洲、日本
#删除并返回origin这一列
origin = dataset.pop('Origin')
#根据origin列写入新的三列,转换为one-hot码
dataset['USA'] = (origin == 1)*1.0
dataset['Europe'] = (origin == 2)*1.0
dataset['Japan'] = (origin == 3)*1.0
#查看新表格的后几项
dataset.tail()

#按8:2比例分割训练集和数据集
#分为训练集和数据集
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
#从标签中分离特征,将MPG字段移出为标签数据
#将特征值从目标值或者标签中分离,作为真实标签Y
train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')

#数据规范化,使用归一化的数据来训练模型
def norm(x):
  return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)

2、模型训练

#构建模型
#依然使用序贯模型方式构建,激活函数使用relu
#两个隐含层,单个连续值的输出层
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’条例子并对这些例子调用
# example_batch = normed_train_data[:10]
# example_result = model.predict(example_batch)
# print(example_result)

#训练模型
#对模型进行1000个周期的训练,并在 history 对象中记录训练和验证的准确性。
# 通过为每个完成的时期打印一个点来显示训练进度
class PrintDot(keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs):
    if epoch % 100 == 0: print('')
    print('.', end='')#通过打点,表示训练运行
#设置步数1000
EPOCHS = 1000

#显示日志verbose=1
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()

#该图表显示在约100个 epochs 之后误差非但没有改进,反而出现恶化。 让我们更新 model.fit 调用

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.title("Photo1")  # 设置title

  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.title("Photo2")  # 设置title
  plt.show()

plot_history(history)



#改进模型
#如图所示,验证集中的平均的误差通常在 +/- 2 MPG左右。 这个结果好么? 我们将决定权留给你。
model = build_model()

# patience 值用来检查改进 epochs 的数量
#当验证值没有提高上是自动停止训练。 我们将使用一个 EarlyStopping callback 来测试每个 epoch
#的训练条件。如果经过一定数量的 epochs 后没有改进,则自动停止训练。
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)
#再次训练模型,显示日志verbose=1
history = model.fit(normed_train_data, train_labels, epochs=EPOCHS,
 validation_split = 0.2, verbose=0, callbacks=[early_stop, PrintDot()])
plot_history(history)#显示方式使用以上函数

TensorFlow入门训练笔记(二)——基本回归:预测燃油效率_第1张图片
TensorFlow入门训练笔记(二)——基本回归:预测燃油效率_第2张图片

3、模型结果

#使用测试集验证模型的效果
#输入测试数据、测试数据标签,输出损失函数,均方差,mae(平均绝对误差)
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")

plt.show()

TensorFlow入门训练笔记(二)——基本回归:预测燃油效率_第3张图片

你可能感兴趣的:(TensorFlow,神经网络,深度学习)