TensorFlow图像处理:车道线检测掩码预测异常问题排查
车道线检测U-Net模型输出异常排查建议
以下是针对你遇到的模型输出仅为原图加红色滤镜问题的具体排查方向:
输出层激活逻辑错误
你的模型最后一层先用relu激活再接softmax,这会截断Conv2D输出的负值,破坏softmax的概率分布计算逻辑。应该把conv9的activation='relu'去掉,改为线性激活(即不指定activation参数),让softmax直接接收原始logits:conv9 = Conv2D(n_classes, 1, activation=None, # 修改为None padding='same', kernel_initializer='he_normal')(ublock9)损失函数与标签格式不匹配
确认损失函数和掩码格式对应:- 如果掩码是单通道类别索引图(每个像素值为0/1/2对应背景、左车道、右车道),损失函数用
sparse_categorical_crossentropy; - 如果掩码是三通道one-hot编码图,才用
categorical_crossentropy。
格式不匹配会导致模型无法有效学习掩码特征。
- 如果掩码是单通道类别索引图(每个像素值为0/1/2对应背景、左车道、右车道),损失函数用
数据预处理不一致
- 检查输入图像和掩码的归一化是否统一:比如图像是否缩放到0-1区间,而掩码是否还是0-255的原始值?未归一化的掩码会让模型难以收敛。
- 确认掩码的类别映射是否正确:
n_classes=3是否对应实际类别数(背景+两条车道),掩码中的每个类别是否正确对应模型输出的通道。
输出后处理方式错误
模型输出的是三通道概率分布(softmax结果),不能直接当作RGB图像显示。需要对每个像素取概率最大的通道索引(tf.argmax(output, axis=-1)),得到单通道类别掩码后,再给不同类别分配颜色进行可视化。直接显示概率图会因通道值分布问题,呈现类似滤镜的效果。单样本训练的逻辑漏洞
用单张图片训练时,要确认训练循环是否正确传入图像和对应掩码标签,是否执行了正确的梯度更新步骤。比如是否存在标签传错(把图像本身当作标签)的情况,这会导致模型拟合原图,输出类似原图的结果。
核心代码
def convolutional_block(inputs=None, n_filters=32, dropout_prob=0, max_pooling=True): conv = Conv2D(n_filters, kernel_size = 3, activation='relu', padding='same', kernel_initializer=tf.keras.initializers.HeNormal())(inputs) conv = Conv2D(n_filters, kernel_size = 3, activation='relu', padding='same', kernel_initializer=tf.keras.initializers.HeNormal())(conv) if dropout_prob > 0: conv = Dropout(dropout_prob)(conv) if max_pooling: next_layer = MaxPooling2D(pool_size=(2,2))(conv) else: next_layer = conv #conv = BatchNormalization()(conv) skip_connection = conv return next_layer, skip_connection def upsampling_block(expansive_input, contractive_input, n_filters=32): up = Conv2DTranspose( n_filters, kernel_size = 3, strides=(2,2), padding='same')(expansive_input) merge = concatenate([up, contractive_input], axis=3) conv = Conv2D(n_filters, kernel_size = 3, activation='relu', padding='same', kernel_initializer=tf.keras.initializers.HeNormal())(merge) conv = Conv2D(n_filters, kernel_size = 3, activation='relu', padding='same', kernel_initializer=tf.keras.initializers.HeNormal())(conv) return conv def unet_model(input_size=(720, 1280,3), n_filters=32, n_classes=3): inputs = Input(input_size) #contracting path cblock1 = convolutional_block(inputs, n_filters) cblock2 = convolutional_block(cblock1[0], 2*n_filters) cblock3 = convolutional_block(cblock2[0], 4*n_filters) cblock4 = convolutional_block(cblock3[0], 8*n_filters, dropout_prob=0.2) cblock5 = convolutional_block(cblock4[0],16*n_filters, dropout_prob=0.2, max_pooling=None) #expanding path ublock6 = upsampling_block(cblock5[0], cblock4[1], 8 * n_filters) ublock7 = upsampling_block(ublock6, cblock3[1], n_filters*4) ublock8 = upsampling_block(ublock7,cblock2[1] , n_filters*2) ublock9 = upsampling_block(ublock8,cblock1[1], n_filters) conv9 = Conv2D(n_classes, 1, activation='relu', padding='same', kernel_initializer='he_normal')(ublock9) conv10 = Activation('softmax')(conv9) model = tf.keras.Model(inputs=inputs, outputs=conv10) return model
内容的提问来源于stack exchange,提问作者tailoxyn
相关产品推荐
相关产品推荐

