Keras中1D CNN中的激活功能错误

时间:2017-05-22 11:55:51

标签: python machine-learning neural-network deep-learning keras

如果输入波形包含I2C线的SDA上升沿,我正在创建一个模型进行分类。

我的输入有20000个数据点和100个训练数据。

我最初在Keras 1D CNN: How to specify dimension correctly?

找到了有关输入的答案

但是,我在激活功能中遇到错误:

ValueError: Error when checking target: expected activation_1 to have 3 dimensions, but got array with shape (100, 1)

我的模特是:

model.add(Conv1D(filters=n_filter,
             kernel_size=input_filter_length,
             strides=1,
             activation='relu',
             input_shape=(20000,1)))
model.add(BatchNormalization())
model.add(MaxPooling1D(pool_size=4, strides=None))

model.add(Dense(1))
model.add(Activation("sigmoid"))

adam = Adam(lr=learning_rate)

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

model.fit(train_data, train_label,
      nb_epoch=10,
      batch_size=batch_size, shuffle=True)

score = np.asarray(model.evaluate(test_new_data, test_label, batch_size=batch_size))*100.0

我无法在这里确定问题。关于激活函数为什么需要3D张量的原因。

2 个答案:

答案 0 :(得分:4)

问题在于,从keras 2.0开始,应用于序列的Dense层将该层应用于每个时间步 - 因此给定序列将产生序列。所以你的Dense实际上产生了一个1元素向量序列,这会导致你的问题(因为你的目标不是一个序列)。

有多种方法可以将序列缩减为向量,然后对其应用Dense

  1. GlobalPooling

    您可以使用GlobalPoolingGlobalAveragePooling1DGlobalMaxPooling1D图层,例如:

    model.add(Conv1D(filters=n_filter,
             kernel_size=input_filter_length,
             strides=1,
             activation='relu',
             input_shape=(20000,1)))
    model.add(BatchNormalization())
    model.add(GlobalMaxPooling1D(pool_size=4, strides=None))
    
    model.add(Dense(1))
    model.add(Activation("sigmoid"))
    
  2. Flattening

    您可以使用Flatten图层将整个序列折叠为单个矢量:

    model.add(Conv1D(filters=n_filter,
             kernel_size=input_filter_length,
             strides=1,
             activation='relu',
             input_shape=(20000,1)))
    model.add(BatchNormalization())
    model.add(MaxPooling1D(pool_size=4, strides=None))
    model.add(Flatten())
    
    model.add(Dense(1))
    model.add(Activation("sigmoid"))
    
  3. RNN后处理:

    您还可以在序列的顶部添加一个循环图层,并使其仅返回最后一个输出:

    model.add(Conv1D(filters=n_filter,
             kernel_size=input_filter_length,
             strides=1,
             activation='relu',
             input_shape=(20000,1)))
    model.add(BatchNormalization())
    model.add(MaxPooling1D(pool_size=4, strides=None))
    model.add(SimpleRNN(10, return_sequences=False))
    
    model.add(Dense(1))
    model.add(Activation("sigmoid"))
    

答案 1 :(得分:0)

Conv1D的输出有3个维度(在Dense图层之前会一直保持这种状态)。

Conv输出:( BatchSize,Length,Filters)

要使Dense图层只输出一个结果,您需要添加Flatten()Reshape((shape))图层,才能生成它(BatchSize,Lenght)。

如果您致电model.summary(),您会看到每个图层输出的确切形状。您必须将输出调整为与传递的数组完全相同的形状,作为正确的结果。这些形状中显示的None是批量大小,可以忽略。

关于你的模型:我认为你需要更多的卷积层,逐渐减少滤波器的数量,因为在单个Dense层中压缩如此多的数据通常不会带来好的结果。

关于维度: keras layers toturial and samples