keras全卷积神经网络(CNN)实现时间序列分类
本文是翻译的keras库中的代码示例。
前言
本文是翻译的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个时代,如果我们继续训练,验证 准确率将开始下降,而训练准确率将继续提高: 模型开始过拟合。
更多推荐
所有评论(0)