kreas搭建神经网络预测波士顿房价(手写K折交叉验证)

1、程序说明

所有注意事项均写入注释

from keras.datasets import boston_housing
import numpy as np
from keras import models
from keras import layers
from keras.optimizers import RMSprop

#  载入数据
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()

#  训练集404个,测试集102个,13个属性
# print(train_data[0])
# print(train_data.shape)
# print(train_targets)
# print(test_data.shape)

#  数据标准化
'''
用于测试数据标准化的均值和标准差都是在训练数据上计算得到的。
不能使用在测试数据上计算得到的任何结果,即使是像数据标准化这么简单的事情也不行。
'''
mean = train_data.mean(axis=0)
train_data -= mean
test_data -= mean
std = train_data.std(axis=0)
train_data -= std
test_data -= std

def build_model():
    model = models.Sequential()
    model.add(layers.Dense(units=64, activation='relu', input_shape=(13, )))
    model.add(layers.Dense(units=64, activation='relu'))
    '''
        网络的最后一层只有一个单元,没有**,是一个线性层。这是标量回归(标量回归是预
    测单一连续值的回归)的典型设置。添加**函数将会限制输出范围。例如,如果向最后一层
    添加 sigmoid **函数,网络只能学会预测 0~1 范围内的值。这里最后一层是纯线性的,所以
    网络可以学会预测任意范围内的值。
    '''
    model.add(layers.Dense(units=1))
    model.compile(optimizer=RMSprop(lr=0.001), loss='mse', metrics=['mae'])
    return model

def k_fold(k, model):
    num_val_samples = len(train_data) // k
    all_scores = []
    for i in range(k):
        print('Processing fold #', i+1)

        #  准备测试集,第i块为测试集
        val_data = train_data[i*num_val_samples: (i+1)*num_val_samples]
        val_targets = train_targets[i*num_val_samples: (i+1)*num_val_samples]

        #  准备训练集,除了第i块都是训练集,这里用numpy的concatenate拼接
        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)
        '''
        verbose:日志显示
        verbose = 0 为不在标准输出流输出日志信息
        verbose = 1 为输出进度条记录
        verbose = 2 为每个epoch输出一行记录
        注意: 默认为 1
        '''
        model.fit(partial_train_data, partial_train_targets, epochs=100, batch_size=1, verbose=0)
        val_mse, val_mae = model.evaluate(val_data, val_targets)
        print('val_mse:', val_mae, '   val_mae:', val_mae)
        all_scores.append(val_mae)
    return all_scores

if __name__ == '__main__':
    all_scores = k_fold(5, build_model())
    print(all_scores)






2、训练结果展示

Processing fold # 1

32/80 [===========>..................] - ETA: 0s
80/80 [==============================] - 0s 424us/step
val_mse: 2.2958826065063476    val_mae: 2.2958826065063476
Processing fold # 2

32/80 [===========>..................] - ETA: 0s
80/80 [==============================] - 0s 25us/step
val_mse: 2.2359493732452393    val_mae: 2.2359493732452393
Processing fold # 3

32/80 [===========>..................] - ETA: 0s
80/80 [==============================] - 0s 25us/step
val_mse: 1.8176211357116698    val_mae: 1.8176211357116698
Processing fold # 4

32/80 [===========>..................] - ETA: 0s
80/80 [==============================] - 0s 25us/step
val_mse: 1.8358864784240723    val_mae: 1.8358864784240723
Processing fold # 5

32/80 [===========>..................] - ETA: 0s
80/80 [==============================] - 0s 25us/step
val_mse: 2.025705862045288    val_mae: 2.025705862045288
[2.2958826065063476, 2.2359493732452393, 1.8176211357116698, 1.8358864784240723, 2.025705862045288]

可见,平均mae为2.04,即平均误差为2040美元。

3、k折交叉验证

kreas搭建神经网络预测波士顿房价(手写K折交叉验证)

4、小结

  • 回归问题使用的损失函数与分类问题不同。回归常用的损失函数是均方误差(MSE),常见的回归指标是平均绝对误差(MAE)。
  • 如果可用的数据很少,使用 K 折验证可以可靠地评估模型。
  • 如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
  • 如果可用的训练数据很少,最好使用隐藏层较少(通常只有一到两个)的小型网络,以避免严重的过拟合。