使用keras对不同大小序列进行时间序列分类

2024-05-20 12:10:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我想做一个神经网络,它可以把身体部位的一些坐标作为输入(使用posenet提取),然后可以对用户正在做的运动进行分类。为此,我想给我的网络提供一系列坐标,并对7个不同的练习进行分类,其中一个是空闲的。我已经将训练数据加载到一个包含6个元素的列表中,每个元素是一个可变长度的numpy数组(一个大约为12.000,向下大约为2.000),每个时间步长由51个值组成(17个身体部位,具有x和y坐标,以及来自posenet的置信值)。我的模型如下所示:

    model.add(LSTM(32, input_shape=(None, 51), return_sequences=True))
    model.add(LSTM(16, return_sequences=True))
    model.add(LSTM(8, return_sequences=True))
    model.add(Dense(7, activation='softmax'))

    model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

我尝试使用以下方法来拟合模型:

model.fit(train_x, train_y,
          validation_data=(validation_x, validation_y), epochs=100,
          callbacks=[EarlyStopping(monitor='val_loss')])

我得到以下错误:

ValueError: Data cardinality is ambiguous:
  x sizes: 12578, 3102, 12684, 7021, 2111, 2635
  y sizes: 12578, 3102, 12684, 7021, 2111, 2635
Make sure all arrays contain the same number of samples.

我的数据的形状如下所示:

train_x: (12578, 51), (3102, 51), (12684, 51), (7021, 51), (2111, 51), (2635, 51)
train_y: (12578,), (3102,), (12684,), (7021,), (2111,), (2635,)
validation_x: (2989, 51), (4425, 51), (2919, 51)
validation_y: (2989,), (4425,), (2919,)

我如何格式化输入以能够训练我的模型


1条回答
网友
1楼 · 发布于 2024-05-20 12:10:57

许多解决方案都可以解决您的问题,但我将重点介绍我最常用的两种不同方法:

生成一个固定窗口作为输入

您可以构建大小固定的窗口(例如n_steps= 50),输入大小将为n_steps。这是一个函数,我使用它从系列中构建这种固定窗口大小的方法:

def split_sequence(sequence, n_steps,pred_steps):
    X, y = list(), list()
    for i in range(len(sequence)):
        # find the end of this pattern
        end_ix = i + n_steps
        # check if we are beyond the sequence
        if end_ix > len(sequence)-pred_steps:
            break
        # gather input and output parts of the pattern
        seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:end_ix+pred_steps]
        X.append(seq_x)
        y.append(seq_y)
    return np.array(X), np.array(y)

其中pred_steps是未来窗口预测,用作模型的目标。此函数将从序列中为您的模型提供X和y

将整个系列作为输入,但用零填充未看到的事件

您可以生成序列大小为零的输入,并在每个时间步追加每个新值:

series = [1,2,3,4,5]
#at time t=0
input = [0,0,0,0,0]
#at time t=1
input = [0,0,0,0,1]
#at time t=2
input = [0,0,0,1,2]
# and this continue until the end of the series

输出将具有与固定大小解决方案中类似的形状。要实现此解决方案,可以使用Numpy函数np.deletenp.appendnp.concatenate

检查Numpy文档以了解:https://numpy.org/doc/stable/reference/routines.array-manipulation.html

仅在序列的最后一个值中使用

由于您使用的是LSTM体系结构和内存门,因此网络会记住以前的输出和输入。我不确定这种方法,但它也可以起作用

相关问题 更多 >