前言

本文是翻译的keras库中的代码示例,点击跳转原链接


一、导入库

import keras
import numpy as np
import matplotlib.pyplot as plt

二、加载数据:FordA 数据集

数据集说明
在这里使用的数据集称为 FordA。 数据来自 UCR 存档。 数据集包含 3601 个训练实例和另外 1320 个测试实例。 每个时间序列对应于电机传感器捕获的发动机噪声测量值。 对于此任务,目标是自动检测是否存在特定问题 引擎。问题在于平衡的二元分类任务。的完整描述 这个数据集可以在这里找到。

读取 TSV 数据
我们将使用该文件进行训练,将该文件用于测试。此数据集的简单性 使我们能够有效地演示如何使用 ConvNet 进行时间序列分类。 在此文件中,第一列对应于标签:FordA_TRAINFordA_TEST

def readucr(filename):
    data = np.loadtxt(filename, delimiter="\t")
    y = data[:, 0]
    x = data[:, 1:]
    return x, y.astype(int)


root_url = "https://raw.githubusercontent.com/hfawaz/cd-diagram/master/FordA/"

x_train, y_train = readucr(root_url + "FordA_TRAIN.tsv")
x_test, y_test = readucr(root_url + "FordA_TEST.tsv")

三、可视化数据

在这里,我们可视化数据集中每个类的一个时间序列示例

classes = np.unique(np.concatenate((y_train, y_test), axis=0))

plt.figure()
for c in classes:
    c_x_train = x_train[y_train == c]
    plt.plot(c_x_train[0], label="class " + str(c))
plt.legend(loc="best")
plt.show()
plt.close()

在这里插入图片描述

四、标准化数据

我们的时间序列已经处于单一长度 (500) 中。但是,它们的值是 通常在各种范围内。这对于神经网络来说并不理想; 一般来说,我们应该设法使输入值归一化。 对于此特定数据集,数据已进行 z 规范化:每个时间序列样本 均值等于零,标准差等于 1。这种类型的 归一化对于时间序列分类问题非常常见。

请注意,此处使用的时间序列数据是单变量的,这意味着我们只有一个通道 每个时间序列示例。 因此,我们将时间序列转换为具有一个通道的多变量序列 通过 numpy 使用简单的重塑。 这将使我们能够构建一个易于适用于多变量时间的模型。

x_train = x_train.reshape((x_train.shape[0], x_train.shape[1], 1))
x_test = x_test.reshape((x_test.shape[0], x_test.shape[1], 1))
#计数事先的类数
num_classes = len(np.unique(y_train))
#现在我们随机播放训练集,因为我们将使用该选项 以后训练时。validation_split
idx = np.random.permutation(len(x_train))
x_train = x_train[idx]
y_train = y_train[idx]
#将标签标准化为正整数。 然后,预期的标签将为 0 和 1。
y_train[y_train == -1] = 0
y_test[y_test == -1] = 0

五、构建模型

我们构建了一个最初在本文中提出的全卷积神经网络。 该实现基于此处提供的 TF 2 版本。 发现以下超参数(kernel_size、过滤器、BatchNorm 的用法) 通过使用 KerasTuner 进行随机搜索。

def make_model(input_shape):
    input_layer = keras.layers.Input(input_shape)

    conv1 = keras.layers.Conv1D(filters=64, kernel_size=3, padding="same")(input_layer)
    conv1 = keras.layers.BatchNormalization()(conv1)
    conv1 = keras.layers.ReLU()(conv1)

    conv2 = keras.layers.Conv1D(filters=64, kernel_size=3, padding="same")(conv1)
    conv2 = keras.layers.BatchNormalization()(conv2)
    conv2 = keras.layers.ReLU()(conv2)

    conv3 = keras.layers.Conv1D(filters=64, kernel_size=3, padding="same")(conv2)
    conv3 = keras.layers.BatchNormalization()(conv3)
    conv3 = keras.layers.ReLU()(conv3)

    gap = keras.layers.GlobalAveragePooling1D()(conv3)

    output_layer = keras.layers.Dense(num_classes, activation="softmax")(gap)

    return keras.models.Model(inputs=input_layer, outputs=output_layer)
model = make_model(input_shape=x_train.shape[1:])
keras.utils.plot_model(model, show_shapes=True)

六、训练模型

epochs = 500
batch_size = 32

callbacks = [
    keras.callbacks.ModelCheckpoint(
        "best_model.keras", save_best_only=True, monitor="val_loss"
    ),
    keras.callbacks.ReduceLROnPlateau(
        monitor="val_loss", factor=0.5, patience=20, min_lr=0.0001
    ),
    keras.callbacks.EarlyStopping(monitor="val_loss", patience=50, verbose=1),
]
model.compile(
    optimizer="adam",
    loss="sparse_categorical_crossentropy",
    metrics=["sparse_categorical_accuracy"],
)
history = model.fit(
    x_train,
    y_train,
    batch_size=batch_size,
    epochs=epochs,
    callbacks=callbacks,
    validation_split=0.2,
    verbose=1,
)

七、根据测试数据评估模型

model = keras.models.load_model("best_model.keras")

test_loss, test_acc = model.evaluate(x_test, y_test)

print("Test accuracy", test_acc)
print("Test loss", test_loss)

八、绘制模型的训练和验证损失

metric = "sparse_categorical_accuracy"
plt.figure()
plt.plot(history.history[metric])
plt.plot(history.history["val_" + metric])
plt.title("model " + metric)
plt.ylabel(metric, fontsize="large")
plt.xlabel("epoch", fontsize="large")
plt.legend(["train", "val"], loc="best")
plt.show()
plt.close()

在这里插入图片描述

我们可以看到训练准确率在 100 个 epoch 后如何达到近 0.95。 但是,通过观察验证精度,我们可以看到网络仍然需要 训练直到验证和训练准确率达到接近 0.97 200 个时代后。超过200个时代,如果我们继续训练,验证 准确率将开始下降,而训练准确率将继续提高: 模型开始过拟合。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐