在Chapter3的前面两个例子中我们都是使用深度学习算法来解决分类问题,而另一种在机器学习领域经常遇到的是回归问题
在本例中将要根据数据预测20实际70年代中期的波士顿郊区房屋价格的中位数,可能影响的因素有犯罪率、房产税率等等
数据特征
# 加载数据
from keras.datasets import boston_housing
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()
# 数据观察
print(train_data.shape) # 对应影响房子价格的因素有13种
print(train_data[0])
print(test_data.shape)
print(train_targets) # 房子价格,单位:千美元
(404, 13)
[ 1.23247 0. 8.14 0. 0.538 6.142 91.7
3.9769 4. 307. 21. 396.9 18.72 ]
(102, 13)
[15.2 42.3 50. 21.1 17.7 18.5 11.3 15.6 15.6 14.4 12.1 17.9 23.1 19.9
15.7 8.8 50. 22.5 24.1 27.5 10.9 30.8 32.9 24. 18.5 13.3 22.9 34.7
16.6 17.5 22.3 16.1 14.9 23.1 34.9 25. 13.9 13.1 20.4 20. 15.2 24.7
22.2 16.7 12.7 15.6 18.4 21. 30.1 15.1 18.7 9.6 31.5 24.8 19.1 22.
14.5 11. 32. 29.4 20.3 24.4 14.6 19.5 14.1 14.3 15.6 10.5 6.3 19.3
19.3 13.4 36.4 17.8 13.5 16.5 8.3 14.3 16. 13.4 28.6 43.5 20.2 22.
23. 20.7 12.5 48.5 14.6 13.4 23.7 50. 21.7 39.8 38.7 22.2 34.9 22.5
31.1 28.7 46. 41.7 21. 26.6 15. 24.4 13.3 21.2 11.7 21.7 19.4 50.
22.8 19.7 24.7 36.2 14.2 18.9 18.3 20.6 24.6 18.2 8.7 44. 10.4 13.2
21.2 37. 30.7 22.9 20. 19.3 31.7 32. 23.1 18.8 10.9 50. 19.6 5.
14.4 19.8 13.8 19.6 23.9 24.5 25. 19.9 17.2 24.6 13.5 26.6 21.4 11.9
22.6 19.6 8.5 23.7 23.1 22.4 20.5 23.6 18.4 35.2 23.1 27.9 20.6 23.7
28. 13.6 27.1 23.6 20.6 18.2 21.7 17.1 8.4 25.3 13.8 22.2 18.4 20.7
31.6 30.5 20.3 8.8 19.2 19.4 23.1 23. 14.8 48.8 22.6 33.4 21.1 13.6
32.2 13.1 23.4 18.9 23.9 11.8 23.3 22.8 19.6 16.7 13.4 22.2 20.4 21.8
26.4 14.9 24.1 23.8 12.3 29.1 21. 19.5 23.3 23.8 17.8 11.5 21.7 19.9
25. 33.4 28.5 21.4 24.3 27.5 33.1 16.2 23.3 48.3 22.9 22.8 13.1 12.7
22.6 15. 15.3 10.5 24. 18.5 21.7 19.5 33.2 23.2 5. 19.1 12.7 22.3
10.2 13.9 16.3 17. 20.1 29.9 17.2 37.3 45.4 17.8 23.2 29. 22. 18.
17.4 34.6 20.1 25. 15.6 24.8 28.2 21.2 21.4 23.8 31. 26.2 17.4 37.9
17.5 20. 8.3 23.9 8.4 13.8 7.2 11.7 17.1 21.6 50. 16.1 20.4 20.6
21.4 20.6 36.5 8.5 24.8 10.8 21.9 17.3 18.9 36.2 14.9 18.2 33.3 21.8
19.7 31.6 24.8 19.4 22.8 7.5 44.8 16.8 18.7 50. 50. 19.5 20.1 50.
17.2 20.8 19.3 41.3 20.4 20.5 13.8 16.5 23.9 20.6 31.5 23.3 16.8 14.
33.8 36.1 12.8 18.3 18.7 19.1 29. 30.1 50. 50. 22. 11.9 37.6 50.
22.7 20.8 23.5 27.9 50. 19.3 23.9 22.6 15.2 21.7 19.2 43.8 20.3 33.2
19.9 22.5 32.7 22. 17.1 19. 15. 16.1 25.1 23.7 28.7 37.2 22.6 16.4
25. 29.8 22.1 17.4 18.1 30.3 17.5 24.7 12.6 26.5 28.7 13.3 10.4 24.4
23. 20. 17.8 7. 11.8 24.4 13.8 19.4 25.2 19.4 19.4 29.1]
将不同取值范围的数据直接塞进网络中的做法是有问题的,为此我们应对所有的输入数据进行标准化:减去样本平均值,再除以标准差(所得的数据特征平均值 = 0, 标准差 = 1)
X ^ i j = X i j − X ˉ i ∑ j = 1 N ( X i j − X ˉ i ) 2 \hat{X}_{i j}=\frac{X_{i j}-\bar{X}_{i}}{\sqrt{\sum_{j=1}^{N}\left(X_{i j}-\bar{X}_{i}\right)^{2}}} X^ij=∑j=1N(Xij−Xˉi)2Xij−Xˉi
# 数据标准化
# 样本数据标准化
mean = train_data.mean(axis = 0) # 对数据按列求均值(即按指标求均值)
train_data -= mean
std = train_data.std(axis = 0) # 对数据按列求标准差(即按指标求标准差)
train_data /= std
# 测试数据标准化
# 注意:这里对测试数据求得标准差都是除以训练数据的,
# 因为在实际测试中我们不能使用任何通过测试数据计算的结果
test_data -= mean
test_data /= std
# 定义模型
from keras import models
from keras import layers
def build_model():
# 模型实例化
model = models.Sequential() # 用同一个函数来 构建模型
model.add(layers.Dense(64, activation = 'relu', input_shape = (train_data.shape[1], )))
model.add(layers.Dense(64, activation = 'relu'))
model.add(layers.Dense(1))
# 网络的最后一层只有一个单元,没有激活层
# 目的是为了直接输出一个预测的数值,而不是一个0~1之间的概率
model.compile(optimizer = 'rmsprop', loss = 'mse', metrics = ['mae']) # mse:均方误差(mean squared error)...
# mae:平均绝对误差(mean absloute error):如MAE = 0.5 表示你的房价与实际的价格相差500美元
return model
由于训练的样本过小,如果单单将数据分为验证集和测试集,则会使得最终得分有较大的分差,我们使用K验证方法对样本进行验证
# K折验证
import numpy as np
k = 4
num_val_samples = len(train_data) // k
num_epochs = 100
all_scores = []
for i in range(k):
print('processing fold #', i)
val_data = train_data[i * num_val_samples:(i + 1) * num_val_samples] # 准备验证集数据:第K个
val_targets = train_targets[i * num_val_samples:(i + 1) * num_val_samples] # i从0开始
# 将数据按行分段,进行K划分,详见书P69页图
partial_train_data = np.concatenate(
[train_data[:i * num_val_samples],
train_data[(i + 1) * num_val_samples:]],
axis = 0)
partial_train_targets = np.concatenate(
[train_targets[:i * num_val_samples],
train_targets[(i + 1) * num_val_samples:]],
axis = 0)
model = build_model() # 构建Keras模型
# 训练模型 (静默模式 verbose = 0)
model.fit(partial_train_data, partial_train_targets,
epochs = num_epochs, batch_size = 1, verbose = 0)
val_mse, val_mae = model.evaluate(val_data, val_targets, verbose = 0)
# 记录mae数据
all_scores.append(val_mae)
# 显示训练结果
print(all_scores)
print("各折最终训练分数:%f" % np.mean(all_scores))
processing fold # 0
processing fold # 1
processing fold # 2
processing fold # 3
[2.043470859527588, 2.728513479232788, 2.582028865814209, 2.374497175216675]
各折最终训练分数:2.432128
我们将训练的时间再拉长,并且将每一轮的结果都记录在一个向量中
# K折验证
import numpy as np
k = 4
num_val_samples = len(train_data) // k
num_epochs = 100
all_scores = []
# 训练500轮
num_epochs = 500
all_mae_histories = []
for i in range(k):
print('processing fold #', i)
val_data = train_data[i * num_val_samples:(i + 1) * num_val_samples] # 准备验证集数据:第K个
val_targets = train_targets[i * num_val_samples:(i + 1) * num_val_samples] # i从0开始
# 准备训练数据
# 将数据按行分段,进行K划分,详见书P69页图
partial_train_data = np.concatenate(
[train_data[:i * num_val_samples],
train_data[(i + 1) * num_val_samples:]],
axis = 0)
partial_train_targets = np.concatenate(
[train_targets[:i * num_val_samples],
train_targets[(i + 1) * num_val_samples:]],
axis = 0)
model = build_model() # 构建Keras模型
# 训练模型 (静默模式 verbose = 0)
# 记录训练历史
history = model.fit(partial_train_data, partial_train_targets,
validation_data = (val_data, val_targets),
epochs = num_epochs, batch_size = 1, verbose = 0)
# mae
# mae_history = history.history['val_mean_absolute_error']
mae_history = history.history['val_mae'] # 作者本版本的键值已修改,仅供参考
all_mae_histories.append(mae_history)
processing fold # 0
processing fold # 1
processing fold # 2
processing fold # 3
average_mae_history = [
np.mean([x[i] for x in all_mae_histories]) for i in range(num_epochs)
]
# 绘图
import matplotlib.pyplot as plt
plt.plot(range(1, len(average_mae_history) + 1), average_mae_history)
plt.xlabel('Epochs')
plt.ylabel('Validation MAE')
plt.show()
由于前10个数据点的缘故,使得纵轴的数据范围较大,所以难以看清楚该图的规律,为此,我们重新绘制一张数据图
def smooth_cruve(points, factor = 0.9):
smoothed_points = []
for point in points:
if smoothed_points:
previous = smoothed_points[-1]
smoothed_points.append(previous * factor + point * (1 - factor))
else:
smoothed_points.append(point)
return smoothed_points
smooth_mae_history = smooth_cruve(average_mae_history[10:])
plt.plot(range(1, len(smooth_mae_history) + 1), smooth_mae_history)
plt.xlabel('Epochs')
plt.ylabel('Validation MAE')
plt.show()
model_f = build_model()
model_f.fit(train_data, train_targets, epochs = 80, batch_size = 16, verbose = 0)
test_mse_score, test_mae_score = model.evaluate(test_data, test_targets)
# 打印结果
print(test_mae_score)
102/102 [==============================] - 0s 29us/step
2.8328466415405273
注:本文代码来自《Python 深度学习》,做成电子笔记的方式上传,仅供学习参考,作者均已运行成功,如有遗漏请练习本文作者
各位看官,都看到这里了,麻烦动动手指头给博主来个点赞8,您的支持作者最大的创作动力哟!
<(^-^)>
才疏学浅,若有纰漏,恳请斧正
本文章仅用于各位同志作为学习交流之用,不作任何商业用途,若涉及版权问题请速与作者联系,望悉知