1 import keras 2 from keras.datasets import boston_housing 3 import numpy as np 4 from keras import models 5 from keras import layers 6 import matplotlib.pyplot as plt 7 from keras import backend as K 8 # Some memory clean-up 9 K.clear_session() 10 11 #1. 获取数据集 12 (train_data, train_targets), (test_data, test_targets) = boston_housing.load_data() 13 14 #2. 数据处理 15 #2.1 数据归一化处理 16 mean = train_data.mean(axis=0)#按列计算均值 17 train_data -= mean#矩阵逐元素减法 18 std = train_data.std(axis=0)#按列计算标准差 19 train_data /= std#矩阵逐元素除法 20 21 test_data -= mean 22 test_data /= std 23 24 def build_model(): 25 model = models.Sequential() 26 model.add(layers.Dense(64,activation='relu',input_shape=(train_data.shape[1],))) 27 model.add(layers.Dense(1)) 28 model.compile(optimizer='rmsprop',loss='mse',metrics=['mae']) 29 #损失函数mse:均方误差 30 #监控指标mae:平均绝对误差 31 return model 32 33 # #5. K折交叉验证确定超参数 34 # #5.1开始 K折交叉验证的代码 35 # k = 4 #4折,将训练集分4份,其中3份做训练,1份做验证 36 # num_val_samples = len(train_data) // k #每一份的样本个数 37 # num_epochs = 100 #迭代轮数 38 # # all_scores = [] #保存每次的验证分数 39 # all_mae_histories = [] 40 # for i in range(k): 41 # print('processing fold #', i) 42 # # 准备验证集 43 # val_data = train_data[i * num_val_samples: (i + 1) * num_val_samples] 44 # val_targets = train_targets[i * num_val_samples: (i + 1) * num_val_samples] 45 46 # # 准备训练集 47 # partial_train_data = np.concatenate( 48 # [train_data[:i * num_val_samples], 49 # train_data[(i + 1) * num_val_samples:]], 50 # axis=0) 51 # partial_train_targets = np.concatenate( 52 # [train_targets[:i * num_val_samples], 53 # train_targets[(i + 1) * num_val_samples:]], 54 # axis=0) 55 56 # # 建立网络 57 # model = build_model() 58 # # 训练模型 (in silent mode, verbose=0) 59 # # model.fit(partial_train_data, partial_train_targets, 60 # # epochs=num_epochs, batch_size=1, verbose=0) 61 # # # 评估模型 62 # # val_mse, val_mae = model.evaluate(val_data, val_targets, verbose=0) 63 # # all_scores.append(val_mae) 64 # history = model.fit(partial_train_data, partial_train_targets, 65 # validation_data=(val_data, val_targets), 66 # epochs=num_epochs, batch_size=1, verbose=0) 67 # #print(history.history) 68 # #{'loss': [413.8923645019531], 'mae': [18.39319610595703], 'val_loss': [219.52098083496094], 'val_mae': [12.841739654541016]} 69 # mae_history = history.history['val_mae'] 70 # all_mae_histories.append(mae_history) 71 72 # # print(all_scores) 73 # #[1.8973649740219116, 2.338238000869751, 2.5596060752868652, 2.437340497970581] 74 # #5.1结束 K折交叉验证的代码 75 76 77 # #5.2开始 根据图形确定迭代轮数等超参数 78 # average_mae_history = [ 79 # np.mean([x[i] for x in all_mae_histories]) for i in range(num_epochs)] 80 81 82 #5.2.1 直接绘图 83 # plt.plot(range(1, len(average_mae_history) + 1), average_mae_history) 84 # plt.xlabel('Epochs') 85 # plt.ylabel('Validation MAE') 86 # plt.show() 87 88 89 # #5.2.2 使曲线平滑 90 # def smooth_curve(points, factor=0.9): 91 # smoothed_points = [] 92 # for point in points: 93 # if smoothed_points: 94 # previous = smoothed_points[-1] 95 # smoothed_points.append(previous * factor + point * (1 - factor)) 96 # else: 97 # smoothed_points.append(point) 98 # return smoothed_points 99 100 # smooth_mae_history = smooth_curve(average_mae_history[10:]) 101 # plt.plot(range(1, len(smooth_mae_history) + 1), smooth_mae_history) 102 # plt.xlabel('Epochs') 103 # plt.ylabel('Validation MAE') 104 # plt.show() 105 #5.2结束 106 107 108 #6. 调整好超参数,使用全部训练集来训练模型 109 model = build_model() 110 # Train it on the entirety of the data. 111 model.fit(train_data, train_targets, 112 epochs=80, batch_size=16, verbose=0) 113 114 #在测试集上评估模型 115 test_mse_score, test_mae_score = model.evaluate(test_data, test_targets) 116 117 print(test_mae_score) # 2.891572952270508
小结:
(1)回归问题使用的损失函数与分类问题不同。回归常用的损失函数是均方误差(MSE)。
(2)同样,回归问题使用的评估指标也与分类问题不同。显而易见,精度的概念不适用于回归问题。常见的回归指标是平均绝对误差(MAE)。
(3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
(4)如果可用的数据很少,使用 K 折验证可以可靠地评估模型。
(5)如果可用的训练数据很少,最好使用隐藏层较少(通常只有一到两个)的小型网络,以避免严重的过拟合。