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
dataset_path = keras.utils.get_file('auto-mpg.data', 'http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data') print(dataset_path)
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() print(dataset.tail())
dataset.isna().sum()
dataset = dataset.dropna()
""" 独热码 在英文文献中称做one-hot code, 直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制。 通常,在通信网络协议栈中,使用八位或者十六位状态的独热码,且系统占用其中一个状态码,余下的可以供用户使用 """ origin = dataset.pop('Origin') dataset['USA'] = (origin == 1) * 1.0 dataset['Europe'] = (origin == 2) * 1.0 dataset['Japan'] = (origin == 3) * 1.0 print(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") plt.savefig('basicRegression.png') plt.show()
train_stats = train_dataset.describe() train_stats.pop('MPG') train_stats = train_stats.transpose() print(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()
model.summary()
example_batch = normed_train_data[:10] example_result = model.predict(example_batch) print(example_result)
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()] ) print("\n")
hist = pd.DataFrame(history.history) hist['epoch'] = history.epoch print(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 后没有改进,则自动停止训练。 """ model = build_model()
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)
loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=2) print("Testing set Mean Abs Error: {:5.2f} MPG".format(mae))
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]) plt.show()
error = test_predictions - test_labels plt.hist(error, bins=25) plt.xlabel("Prediction Error [MPG]") _ = plt.ylabel("Count") plt.show()
|