我正在创建一个模型来分类输入波形是否包含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张量。
回答:
问题在于,从keras 2.0
开始,应用于序列的Dense
层会对每个时间步进行操作 – 因此给定一个序列,它会产生一个序列。所以你的Dense
实际上是产生一个1元素向量的序列,这导致了你的问题(因为你的目标不是一个序列)。
有几种方法可以将序列减少为向量,然后对其应用Dense
层:
-
GlobalPooling
:你可以使用
GlobalPooling
层,如GlobalAveragePooling1D
或GlobalMaxPooling1D
,例如: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"))
-
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"))
-
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"))