PointNet训练fit函数报错:标签与Logits维度不匹配
解决PointNet训练中标签与Logits维度不匹配的ValueError
问题描述
训练PointNet模型时,运行model.fit出现如下错误:
Exception has occurred: ValueError `labels.shape` must equal `logits.shape` except for the last dimension. Received: labels.shape=(300000,) and logits.shape=(60, 2)
模型实现代码
def conv_bn(x, filters): x = keras.layers.Conv1D(filters, kernel_size=1, padding="valid")(x) x = keras.layers.BatchNormalization(momentum=0.0)(x) return keras.layers.Activation("relu")(x) def dense_bn(x, filters): x = keras.layers.Dense(filters)(x) x = keras.layers.BatchNormalization(momentum=0.0)(x) return keras.layers.Activation("relu")(x) class OrthogonalRegularizer(keras.regularizers.Regularizer): def __init__(self, num_features, l2reg=0.001): self.num_features = num_features self.l2reg = l2reg self.eye = tf.eye(num_features) def __call__(self, x): x = tf.reshape(x, (-1, self.num_features, self.num_features)) xxt = tf.tensordot(x, x, axes=(2, 2)) xxt = tf.reshape(xxt, (-1, self.num_features, self.num_features)) return tf.reduce_sum(self.l2reg * tf.square(xxt - self.eye)) def tnet(inputs, num_features): # Initalise bias as the indentity matrix bias = keras.initializers.Constant(np.eye(num_features).flatten()) reg = OrthogonalRegularizer(num_features) x = conv_bn(inputs, 32) x = conv_bn(x, 64) x = conv_bn(x, 512) x = keras.layers.GlobalMaxPooling1D()(x) x = dense_bn(x, 256) x = dense_bn(x, 128) x = keras.layers.Dense(num_features * num_features, kernel_initializer="zeros",bias_initializer=bias, activity_regularizer=reg,)(x) feat_T = keras.layers.Reshape((num_features, num_features))(x) # Apply affine transformation to input features return keras.layers.Dot(axes=(2, 1))([inputs, feat_T]) inputs = keras.Input(shape=(BATCH_SIZE,7)) print(inputs) x = tnet(inputs, 7) x = conv_bn(x, 32) x = conv_bn(x, 32) x = tnet(x, 32) x = conv_bn(x, 32) x = conv_bn(x, 64) x = conv_bn(x, 512) x = keras.layers.GlobalMaxPooling1D()(x) x = dense_bn(x, 256) x = keras.layers.Dropout(0.3)(x) x = dense_bn(x, 128) x = keras.layers.Dropout(0.3)(x) outputs = keras.layers.Dense(NUM_CLASSES, activation="softmax")(x) model = keras.Model(inputs=inputs, outputs=outputs, name="pointnet") model.summary() model.compile(loss="sparse_categorical_crossentropy", optimizer=keras.optimizers.Adam(learning_rate=0.001), metrics=["sparse_categorical_accuracy"],) model.fit(train_dataset, epochs=12, validation_data=val_dataset)
模型结构摘要
__________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ================================================================================================== input_1 (InputLayer) [(None, 5000, 7)] 0 [] conv1d (Conv1D) (None, 5000, 32) 256 ['input_1[0][0]'] batch_normalization (BatchNorm (None, 5000, 32) 128 ['conv1d[0][0]'] alization) activation (Activation) (None, 5000, 32) 0 ['batch_normalization[0][0]'] conv1d_1 (Conv1D) (None, 5000, 64) 2112 ['activation[0][0]'] batch_normalization_1 (BatchNo (None, 5000, 64) 256 ['conv1d_1[0][0]'] rmalization) activation_1 (Activation) (None, 5000, 64) 0 ['batch_normalization_1[0][0]'] conv1d_2 (Conv1D) (None, 5000, 512) 33280 ['activation_1[0][0]'] batch_normalization_2 (BatchNo (None, 5000, 512) 2048 ['conv1d_2[0][0]'] rmalization) activation_2 (Activation) (None, 5000, 512) 0 ['batch_normalization_2[0][0]'] global_max_pooling1d (GlobalMa (None, 512) 0 ['activation_2[0][0]'] xPooling1D) dense (Dense) (None, 256) 131328 ['global_max_pooling1d[0][0]'] batch_normalization_3 (BatchNo (None, 256) 1024 ['dense[0][0]'] rmalization) activation_3 (Activation) (None, 256) 0 ['batch_normalization_3[0][0]'] dense_1 (Dense) (None, 128) 32896 ['activation_3[0][0]'] batch_normalization_4 (BatchNo (None, 128) 512 ['dense_1[0][0]'] rmalization) activation_4 (Activation) (None, 128) 0 ['batch_normalization_4[0][0]'] dense_2 (Dense) (None, 49) 6321 ['activation_4[0][0]'] reshape (Reshape) (None, 7, 7) 0 ['dense_2[0][0]'] dot (Dot) (None, 5000, 7) 0 ['input_1[0][0]', 'reshape[0][0]'] conv1d_3 (Conv1D) (None, 5000, 32) 256 ['dot[0][0]'] batch_normalization_5 (BatchNo (None, 5000, 32) 128 ['conv1d_3[0][0]'] rmalization) activation_5 (Activation) (None, 5000, 32) 0 ['batch_normalization_5[0][0]'] conv1d_4 (Conv1D) (None, 5000, 32) 1056 ['activation_5[0][0]'] batch_normalization_6 (BatchNo (None, 5000, 32) 128 ['conv1d_4[0][0]'] rmalization) activation_6 (Activation) (None, 5000, 32) 0 ['batch_normalization_6[0][0]'] conv1d_5 (Conv1D) (None, 5000, 32) 1056 ['activation_6[0][0]'] batch_normalization_7 (BatchNo (None, 5000, 32) 128 ['conv1d_5[0][0]'] rmalization) activation_7 (Activation) (None, 5000, 32) 0 ['batch_normalization_7[0][0]'] conv1d_6 (Conv1D) (None, 5000, 64) 2112 ['activation_7[0][0]'] batch_normalization_8 (BatchNo (None, 5000, 64) 256 ['conv1d_6[0][0]'] rmalization) activation_8 (Activation) (None, 5000, 64) 0 ['batch_normalization_8[0][0]'] conv1d_7 (Conv1D) (None, 5000, 512) 33280 ['activation_8[0][0]'] batch_normalization_9 (BatchNo (None, 5000, 512) 2048 ['conv1d_7[0][0]'] rmalization) activation_9 (Activation) (None, 5000, 512) 0 ['batch_normalization_9[0][0]'] global_max_pooling1d_1 (Global (None, 512) 0 ['activation_9[0][0]'] MaxPooling1D) dense_3 (Dense) (None, 256) 131328 ['global_max_pooling1d_1[0][0]'] batch_normalization_10 (BatchN (None, 256) 1024 ['dense_3[0][0]'] ormalization) activation_10 (Activation) (None, 256) 0 ['batch_normalization_10[0][0]'] dense_4 (Dense) (None, 128) 32896 ['activation_10[0][0]'] batch_normalization_11 (BatchN (None, 128) 512 ['dense_4[0][0]'] ormalization) activation_11 (Activation) (None, 128) 0 ['batch_normalization_11[0][0]'] dense_5 (Dense) (None, 1024) 132096 ['activation_11[0][0]'] reshape_1 (Reshape) (None, 32, 32) 0 ['dense_5[0][0]'] dot_1 (Dot) (None, 5000, 32) 0 ['activation_6[0][0]', 'reshape_1[0][0]'] conv1d_8 (Conv1D) (None, 5000, 32) 1056 ['dot_1[0][0]'] batch_normalization_12 (BatchN (None, 5000, 32) 128 ['conv1d_8[0][0]'] ormalization) activation_12 (Activation) (None, 5000, 32) 0 ['batch_normalization_12[0][0]'] conv1d_9 (Conv1D) (None, 5000, 64) 2112 ['activation_12[0][0]'] batch_normalization_13 (BatchN (None, 5000, 64) 256 ['conv1d_9[0][0]'] ormalization) activation_13 (Activation) (None, 5000, 64) 0 ['batch_normalization_13[0][0]'] conv1d_10 (Conv1D) (None, 5000, 512) 33280 ['activation_13[0][0]'] batch_normalization_14 (BatchN (None, 5000, 512) 2048 ['conv1d_10[0][0]'] ormalization) activation_14 (Activation) (None, 5000, 512) 0 ['batch_normalization_14[0][0]'] global_max_pooling1d_2 (Global (None, 512) 0 ['activation_14[0][0]'] MaxPooling1D) dense_6 (Dense) (None, 256) 131328 ['global_max_pooling1d_2[0][0]'] batch_normalization_15 (BatchN (None, 256) 1024 ['dense_6[0][0]'] ormalization) activation_15 (Activation) (None, 256) 0 ['batch_normalization_15[0][0]'] dropout (Dropout) (None, 256) 0 ['activation_15[0][0]'] dense_7 (Dense) (None, 128) 32896 ['dropout[0][0]'] batch_normalization_16 (BatchN (None, 128) 512 ['dense_7[0][0]'] ormalization) activation_16 (Activation) (None, 128) 0 ['batch_normalization_16[0][0]'] dropout_1 (Dropout) (None, 128) 0 ['activation_16[0][0]'] dense_8 (Dense) (None, 2) 258 ['dropout_1[0][0]'] ================================================================================================== Total params: 753,363 Trainable params: 747,283 Non-trainable params: 6,080 __________________________________________________________________________________________________
错误分析
从错误信息和模型结构可定位两个核心问题:
- 输入层定义错误:Keras的
Input层shape参数不应包含批量大小(BATCH_SIZE),批量维度由训练数据集自动处理,只需指定单个样本的形状。你的模型摘要中输入shape为(None,5000,7),说明BATCH_SIZE变量值为5000,这会导致模型将点云点数误判为批量大小。 - 标签维度与任务不匹配:当前模型是点云级分类结构(最后使用
GlobalMaxPooling1D,输出shape为(None,2),对应每个点云样本1个分类结果),但标签shape为(300000,),相当于每个点对应1个标签(60个批量样本×5000个点=300000),两者维度完全不匹配。
解决方案
方案1:点云分类任务(每个点云对应1个标签)
- 修正输入层定义:
将输入层代码修改为:# NUM_POINTS为每个点云的点数(如5000),BATCH_SIZE无需写在这里 inputs = keras.Input(shape=(NUM_POINTS,7)) - 调整数据集标签:
确保train_dataset和val_dataset返回的标签为每个点云对应1个值,即标签shape为(BATCH_SIZE,)。若原标签是每个点的标注,需将每个点云的所有点标签合并为一个(如取众数,或确认数据集本身的点云级标签)。
方案2:点分割任务(每个点对应1个标签)
若任务是对每个点进行分类(如语义分割),需修改模型结构以匹配点级输出:
- 移除最后的GlobalMaxPooling1D:
删除x = keras.layers.GlobalMaxPooling1D()(x)这一行,保留特征的(None,5000,512)形状。 - 调整输出层:
使用Conv1D替代Dense,让输出对应每个点的分类结果,确保输出shape为(None,5000,NUM_CLASSES):outputs = keras.layers.Conv1D(NUM_CLAS
相关产品推荐
相关产品推荐

