-
回归:预测出如价格\概率这样连续值的输出。
-
分类:从一系列的分类中选车出一个分类.
终端命令conda install seaborn
用于做图
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
tf.__version__
1. auto MPG 数据集
1.1 获取数据
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
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()
结果如下图:
1.2 清洗数据
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['Janpan'] = (origin == 3)*1.0
dataset.tail()
1.3拆分训练数据集和测试数据集
train_dataset = dataset.sample(frac = 0.8,random_state= 0)
test_dataset = dataset.drop(train_dataset.index)
1.4 数据检查
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
1.5 从标签中分体特征
将特征值从目标值或者’标签‘中分类,这个表示是使用训练模型时进行预测的值。
train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')
源数据的“MPG”删除,返回一个新的结果就是标签
1.6 数据规范化
归一化
再次审视下上面的 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)
警告: 用于归一化输入的数据统计(均值和标准差)需要反馈给模型从而应用于任何其他数据,以及我们之前所获得独热码。这些数据包含测试数据集以及生产环境中所使用的实时数据。
2. 模型
2.1 构建模型
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
2.2 检查模型
- 使用
.summary
方法
model.summary()
- 方法 2
example_batch = normed_train_data[:10]
example_result = model.predict(example_batch)
example_result
2.3 训练模型
class PrintDot(keras.callbacks.Callback):
def on_epoch_end(self,epoch,logs):
if epoch %100 == 0: print('')
print('.',end = '')
EPOCH = 1000
history = model.fit(
normed_train_data,train_labels,
epochs=EPOCH,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 后没有改进,则自动停止训练。
你可以从这里学习到更多的回调。
model = build_model()
patience 值用来检查改进 epochs 的数量
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)
history = model.fit(normed_train_data, train_labels, epochs=EPOCH,
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))
2.4 做预测
loss,mae,mse = model.evaluate(normed_test_data,test_labels,verbose =2)
print('testing set mean abs error:{:5.2f} MPG'.format(mae))
查看误差分布
error = test_predictions - test_labels
plt.hist(error, bins = 25)
plt.xlabel("Prediction Error [MPG]")
_ = plt.ylabel("Count")
它不是完全的高斯分布,但我们可以推断出,这是因为样本的数量很小所导致的。
结论
本笔记本 (notebook) 介绍了一些处理回归问题的技术。
- 均方误差(MSE)是用于回归问题的常见损失函数(分类问题中使用不同的损失函数)。
- 类似的,用于回归的评估指标与分类不同。 常见的回归指标是平均绝对误差(MAE)。
- 当数字输入数据特征的值存在不同范围时,每个特征应独立缩放到相同范围。
- 如果训练数据不多,一种方法是选择隐藏层较少的小网络,以避免过度拟合。
- 早期停止是一种防止过度拟合的有效技术。