我正在尝试在Keras中重新创建CNN以对点云数据进行分类。 this文件中描述了CNN。
这是我当前的实现方式:
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。
答案 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'])