使用Keras实现Unet肺分割模型预测输出空白图像问题咨询
嘿,这个问题我之前帮同行排查过好几次,咱们一步步拆解可能的原因,大部分情况都是预处理/后处理或者输入维度的小疏忽:
预处理步骤和训练时不一致
这是最常见的坑!训练时你肯定对图像做了归一化(比如img = img / 255.0)、尺寸缩放或者通道转换,但predict时很容易漏掉这些步骤。比如训练时把图像缩到0-1区间,而predict时直接喂入0-255的原始图像,模型输出的概率值会极低,看起来就是空白。
解决方法:把predict时的图像预处理代码和训练时的完全对齐,比如复用同一个预处理函数:def preprocess_img(img): img = cv2.resize(img, (256, 256)) # 和训练时一致的尺寸 img = img / 255.0 img = np.expand_dims(img, axis=-1) # 单通道任务需添加通道维度 return img # predict时用这个函数处理图像 input_img = preprocess_img(raw_img)缺少输出后处理步骤
Unet最后一层如果用的是sigmoid激活,输出的是0-1的概率图,不是直接的分割掩码。如果直接把这个概率图可视化,大部分区域的概率值可能低于人眼可见的阈值,看起来就是空白。
解决方法:给输出加阈值化处理,把概率转成二值掩码:pred_prob = model.predict(input_img) pred_mask = (pred_prob > 0.5).astype(np.uint8) # 0.5为通用阈值,可根据任务调整如果是多分类任务(比如背景+肺部+其他组织),用
softmax激活的话,要取argmax得到类别掩码:pred_mask = np.argmax(model.predict(input_img), axis=-1)输入维度不匹配
Keras模型的输入要求是(batch_size, height, width, channels),如果你直接喂入单张图像的(height, width, channels),模型虽然不会报错,但输出可能异常。
解决方法:用np.expand_dims增加batch维度:input_img = np.expand_dims(input_img, axis=0) # 转换成(1, 256, 256, 1)的格式模型加载错误
你可能误加载了未训练的初始模型,或者保存/加载路径出错。比如训练完保存的是model.save('lung_unet.h5'),但加载时用了load_model('wrong_path/unet.h5')。
解决方法:训练结束后立即用当前模型predict一个样本并保存结果;然后加载模型后再predict同一个样本,对比两次结果是否一致。如果不一致,说明模型加载环节有问题。数据类型不兼容
训练时模型的输入是float32类型,但predict时输入的是uint8的原始图像,可能导致模型输出异常。
解决方法:确保输入数据类型和训练时一致:input_img = input_img.astype('float32')
先从预处理和后处理这两点查起,这90%的概率能解决你的问题!
内容的提问来源于stack exchange,提问作者Usma Bhatt

