CNN会针对所有输入数据预测同一类别

时间:2018-10-14 11:55:23

标签: python tensorflow neural-network keras conv-neural-network

我正在尝试在Keras中重新创建CNN以对点云数据进行分类。 this文件中描述了CNN。

网络设计 Image of

这是我当前的实现方式:

inputs = Input(shape=(None, 3))

x = Conv1D(filters=64, kernel_size=1, activation='relu')(inputs)
x = BatchNormalization()(x)
x = Conv1D(filters=64, kernel_size=1, activation='relu')(x)
x = BatchNormalization()(x)

y = Conv1D(filters=64, kernel_size=1, activation='relu')(x)
y = BatchNormalization()(y)
y = Conv1D(filters=128, kernel_size=1, activation='relu')(y)
y = BatchNormalization()(y)
y = Conv1D(filters=2048, kernel_size=1, activation='relu')(y)
y = MaxPooling1D(1)(y)

z = keras.layers.concatenate([x, y], axis=2)
z = Conv1D(filters=512, kernel_size=1, activation='relu')(z)
z = BatchNormalization()(z)
z = Conv1D(filters=512, kernel_size=1, activation='relu')(z)
z = BatchNormalization()(z)
z = Conv1D(filters=512, kernel_size=1, activation='relu')(z)
z = BatchNormalization()(z)
z = Dense(9, activation='softmax')(z)

model = Model(inputs=inputs, outputs=z)

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

问题在于网络为所有输入数据预测相同的类别。这可能是由于我的网络实施中的错误,过拟合或训练数据不足引起的。有人可以在我的实现中发现错误吗?

Yousefhussien,M.,Kelbe,D.J.,Ientilucci,E.J.,&Salvaggio,C.(2017年)。用于3D点云语义标记的完全卷积网络。 arXiv预印本arXiv:1710.01408。

3 个答案:

答案 0 :(得分:1)

相同的输出类通常表示刚刚初始化的网络,这意味着未加载训练权重。训练期间是否发生过同样的事情?不过,另一个原因可能是不良的预处理。我注意到的另一件事是该论文指出“一维全卷积网络”。您的致密层在本文中是一个卷积。

答案 1 :(得分:1)

我认为错误不在实现上。问题很可能是您的数据量不足。另外,如果网络为所有输入数据预测相同的类,则通常意味着您缺乏正则化功能。尝试向Dropout添加一些0.2且具有0.5缺失的图层,看看结果是否有所改善。

我也不认为

x = Conv1D(filters=64, kernel_size=1, activation='relu')(inputs)
x = BatchNormalization()(x)

相同
x = Conv1D(filters=64, kernel_size=1)(inputs)
x = BatchNormalization()(x)
x = ReLU(x)

我认为您需要后者。

您还可以尝试的另一件事是LeakyReLU,因为它通常比纯ReLU产生更好的结果。

答案 2 :(得分:1)

该网络已修复,因为它现在提供了预期的预测。感谢您的帮助!

基于答案,我更改了以下内容:

  • 激活顺序和批次标准化。
  • 从密集层到卷积层的最后一层。

我还将training=True参数添加到批处理规范化层

正确实现的代码:

inputs = Input(shape=(None, 3))

x = Conv1D(filters=64, kernel_size=1, input_shape=(None, 4))(inputs)
x = BatchNormalization()(x, training=True)
x = Activation('relu')(x)
x = Conv1D(filters=64, kernel_size=1, use_bias=False)(x)
x = BatchNormalization()(x, training=True)
x = Activation('relu')(x)

y = Conv1D(filters=64, kernel_size=1)(x)
y = BatchNormalization()(y, training=True)
y = Activation('relu')(y)
y = Conv1D(filters=128, kernel_size=1)(y)
y = BatchNormalization()(y, training=True)
y = Activation('relu')(y)
y = Conv1D(filters=2048, kernel_size=1)(y)
y = BatchNormalization()(y, training=True)
y = Activation('relu')(y)
y = MaxPooling1D(1)(y)

z = keras.layers.concatenate([x, y], axis=2)
z = Conv1D(filters=512, kernel_size=1)(z)
z = BatchNormalization()(z, training=True)
z = Activation('relu')(z)
z = Conv1D(filters=512, kernel_size=1)(z)
z = BatchNormalization()(z, training=True)
z = Activation('relu')(z)
z = Conv1D(filters=512, kernel_size=1)(z)
z = BatchNormalization()(z, training=True)
z = Activation('relu')(z)
z = Conv1D(filters=2, kernel_size=1, activation='softmax')(z)

model = Model(inputs=inputs, outputs=z)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])