神经网络进行训练之前,通常要将数据集分为train_db, test_db, val_db,一般数据集(numpy.ndarray 格式的 x和y对应起来的)是比较好切割的,可以用以下前三种方法,对于时间序列数据的处理,重点看最后一种方法:

方法一:借用三方sklearn库

train_test_split只能切2份,所以我们需要切2次:

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(
    x, y,                # x,y是原始数据
    test_size=0.2        # test_size默认是0.25
)  # 返回的是 剩余训练集+测试集

x_train, x_valid, y_train, y_valid = train_test_split(
    x_train, y_train,    # 把上面剩余的 x_train, y_train继续拿来切
    test_size=0.2        # test_size默认是0.25
)  # 返回的是 二次剩余训练集+验证集

训练的时候可以在fit里直接shuffle和batch:

history = model.fit(
    x_train, 
    y_train, 
    validation_data=(x_valid, y_valid),     # 验证集在这里用了!!!
    epochs=100, 
    batch_size = 32      #  batch_size 不传也行,因为默认就是32
    shuffle=True,        #  shuffle    不传也行,因为默认就是True
    # callbacks=callbacks, #
)
y_predict = model.predict(x_test)            # 返回的是预测结果

关于model.fit()的参数输入类型,点进代码去可以看到更全面易懂的介绍。

方法二:使用 tf.split

x_train, x_test, x_valid = tf.split(  
            x_data,
            num_or_size_splits=[train_sample_num, test_sample_num, valid_train_num],
            axis=0
        )
 y_train, y_test, y_valid = tf.split(
            self.y,
            [train_sample, test_sample, valid_train],
            axis=0
        )
 data = tf.data.Dataset.from_tensor_slices((x, y)).batch(128).shuffle(1000000)    # 封装 dataset数据集格式

方式三: 训验分割-1,不适用于dataset

validation_split is only supported for Tensors or NumPy arrays**

history = model.fit(
    # .....
    validation_split=0.2      # 训练集分出0.2给验证集
)

参数介绍:

validation_split: Float between 0 and 1. Fraction of the training data to be used as validation data. The model will set apart this fraction of the training data, will not train on it, and will evaluate the loss and any model metrics on this data at the end of each epoch. The validation data is selected from the last samples in the `x` and `y` data provided, before shuffling. This argument is not supported when `x` is a dataset, generator or `keras.utils.Sequence` instance.

方式四:训练分割-2, 适用于dataset

经过鄙人历尽艰苦千搜万寻,最终在dataset的method里发现这个功能。TensorFlow2.0官方教程里的章节<使用TensorFlow Keras进行训练和评估>里也提到了这个方法。

train_db = dataset.take(1000)  # 前1000个batch
test_db = dataset.skip(1000)  # 跳过前1000,选取后面的
**这个方法有什么独特的优点?

时间序列数据的特点——序列性,使得在组建窗口和标签之前,不得打乱数据,也不得拆分数据集。因为如果提前拆分数据集以采用前三种方法,为了保持窗口必然会浪费一些数据(drop_remainder = True)。如果打乱数据集,当然就没法正确的组建window;但是如果不打乱数据集,不好意思,结果会非常尴尬,因为你没法合适的对数据集进行特征处理,因为时间序列数据的趋势性会改变方差和均值,这个问题更加致命性,导致训练不出好的效果。所以只能把全部原始数据一次性转化为dataset(x和y组合起来),然后才方便shuffle和batch。然后dataset数据集比较死,处理起来简直无从下手!直到我发现了这个方法后,我才有办法灵活切割dataset。遗留的一个问题是,没找到对dataset进行特征处理的方法,尤其是对这种window组合好的dataset,一个弥补方法是在模型中加入BatchNormalization层。**