【问题标题】:keras conv1d input data reshapekeras conv1d 输入数据重塑
【发布时间】:2018-04-17 11:54:59
【问题描述】:

我正在尝试在 Keras 中使用一维 CNN 进行二元分类。我有一台连续执行动作的机器,我的目标是分类该动作是正常的还是异常的。

为了监控每个动作的行为,有 4 个传感器收集 100 个测量值。因此,对于每个动作,我有 4x100 = 400 个数据点。在一个单独的文件中,我有每个动作对应的标签。我的数据集如下所示:

measurement ID | action ID | sensor 1 | sensor 2 | sensor 3 | sensor 4 |
-----------------------------------------------------------------
       1       |     1     |   42.3   |   42.3   |   42.3   |   42.3   | 
       2       |     1     |   42.3   |   42.3   |   42.3   |   42.3   | 
       3       |     1     |   42.3   |   42.3   |   42.3   |   42.3   | 
      ...      |   ....    |   ....   |   ....   |   ....   |   ....   | 
      100      |     1     |   42.3   |   42.3   |   42.3   |   42.3   | 
       1       |     2     |   42.3   |   42.3   |   42.3   |   42.3   | 
       2       |     2     |   42.3   |   42.3   |   42.3   |   42.3   | 
       3       |     2     |   42.3   |   42.3   |   42.3   |   42.3   | 
      ...      |   ....    |   ....   |   ....   |   ....   |   ....   | 
      100      |     2     |   42.3   |   42.3   |   42.3   |   42.3   |
      ...      |   ....    |   ....   |   ....   |   ....   |   ....   |

我的问题是如何重塑此数据集以在 Keras 中应用 convd1。还有如何为一堆向量分配标签。请注意,我的数据集由 10,000 个操作组成。我的假设是我有 4 个通道(维度)和一个包含 100 个值的向量,所以我的输入形状应该是(maxlen=100,维度=4)。也许我完全错了。

模型应如下所示:

model = Sequential()
model.add(Conv1D(filters=64, kernel_size=5 activation='relu',input_shape=(100,4)))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
sgd = SGD(lr=0.1, momentum=0.9, decay=0, nesterov=False)
model.compile(loss='binary_crossentropy', optimizer=sgd)
model.fit(trainX, trainY, validation_data=(testX, testY), epochs=100, batch_size=100)

谁能指出实现这一目标的正确方法?

【问题讨论】:

    标签: python tensorflow keras conv-neural-network


    【解决方案1】:

    使用传感器数量似乎是合乎逻辑的,应该不是问题,并且考虑多次测量作为尺寸似乎也是正确的。因此,您可以尝试训练此模型并检查结果。

    我推荐的另一种方法是对所有传感器使用不同的卷积。因此,您将有 4 个卷积,每个卷积接受来自一个传感器的形状为 (100, 1) 的输入。 Keras 代码看起来像

    from keras.layers import Input, Conv1D, Dense, concatenate, Flatten
    from keras.models import Model
    
    s1_input = Input((100, 1))
    s2_input = Input((100, 1))
    s3_input = Input((100, 1))
    s4_input = Input((100, 1))
    
    conv1 = Conv1D(filters=64, kernel_size=5, activation='relu')(s1_input)
    conv2 = Conv1D(filters=64, kernel_size=5, activation='relu')(s2_input)
    conv3 = Conv1D(filters=64, kernel_size=5, activation='relu')(s3_input)
    conv4 = Conv1D(filters=64, kernel_size=5, activation='relu')(s4_input)
    
    f1 = Flatten()(conv1)
    f2 = Flatten()(conv2)
    f3 = Flatten()(conv3)
    f4 = Flatten()(conv4)
    
    dense_in = concatenate([f1, f2, f3, f4])
    output = Dense(1, activation='sigmoid')(dense_in)
    
    model = Model(inputs=[s1_input, s2_input, s3_input, s4_input], outputs=[output])
    

    还有另一种 RNN 方法,您将 100 次测量视为时间步长,并在每一步输入 4 个传感器的数据。但是,我非常怀疑这种方法能否优于 CNN 方法。

    【讨论】:

    • 感谢您的回答,但您能否进一步解释一下如何每个传感器使用 1 个卷积?我知道输入应该是(100, 1),但我该如何建模呢?复制此模型 4 次或如何复制。抱歉,我有点糊涂了……
    • 在这种情况下,您需要使用 Keras 的Functional API。我已经更新了我的答案,以展示如何建模。
    • 谢谢你的代码,现在我可以更好地理解它了!
    • @layog 将此处的内核描绘为形状 (5x1) 并且沿 100x1 时间序列向下移动是否准确?