You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keras语义分割:小尺寸训练后无法预测大尺寸图像的问题

问题解答

完全可以在小尺寸图像上训练模型,同时对大尺寸图像进行预测,以下是具体解决思路和代码调整方案:

方案一:修改模型为动态输入尺寸(推荐)

你的U-Net模型当前输入尺寸固定为(128,128,1),这是导致输入不兼容的核心原因。U-Net的结构天然支持可变尺寸输入(只要输入尺寸是下采样/上采样步长的整数倍,256是128的2倍,完全符合要求),只需要修改输入层为动态尺寸即可:

修改后的模型代码

# 将固定输入尺寸改为动态尺寸,支持任意符合下采样倍数的输入
inputs = Input((None, None, 1))

s = Lambda(lambda x: x / 255)(inputs)

c1 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(s)
c1 = Dropout(0.1)(c1)
c1 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c1)
p1 = MaxPooling2D((2, 2))(c1)

c2 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(p1)
c2 = Dropout(0.1)(c2)
c2 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c2)
p2 = MaxPooling2D((2, 2))(c2)

# 保留原模型中间层代码...

u9 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same')(c8)
u9 = concatenate([u9, c1], axis=3)
c9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(u9)
c9 = Dropout(0.1)(c9)
c9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c9)

outputs = Conv2D(1, (1, 1), activation='sigmoid')(c9)

model = Model(inputs=[inputs], outputs=[outputs])
model.compile(optimizer='adam', loss='binary_crossentropy')

训练与预测调整

  • 训练阶段:依然使用128x128的图像输入,训练逻辑无需改变,模型会自动适配该尺寸。
  • 预测阶段:直接输入256x256的单通道图像(和训练输入格式一致),模型会输出对应尺寸的分割结果,完全满足竞赛要求。

方案二:缩放输入输出(临时替代方案)

如果不想修改模型结构,可以采用“缩放输入-预测-缩放输出”的流程,但会损失一定精度:

  • 预测时将256x256的图像缩放到128x128,输入模型得到128x128的预测结果
  • 将预测结果缩放到256x256,注意使用和图像缩放一致的插值方式(推荐用bilinear或nearest,避免模糊)

示例代码(预测阶段)

from skimage.transform import resize

# 加载256x256的单通道图像
image_256 = np.array(Image.open(test_path).convert('L'))
image_256 = np.expand_dims(image_256, axis=-1)

# 缩放到128x128用于预测
image_128 = resize(image_256, (128, 128), mode='constant', preserve_range=True)
image_128 = np.expand_dims(image_128, axis=0)  # 增加batch维度

# 预测
pred_128 = model.predict(image_128)

# 缩放回256x256
pred_256 = resize(pred_128[0], (256, 256), mode='constant', preserve_range=True)
pred_256 = np.expand_dims(pred_256, axis=0)  # 恢复batch维度

额外修正:数据获取函数的bug

你的get_data函数存在缩进错误,out[i] = image应该在for循环内部,否则只会将最后一张图像赋值到输出数组中,修正后的代码:

def get_data(a, path, IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS, t):
    out = np.zeros((len(a), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=t)
    for i, image_id in enumerate(a):
        path_image = path + image_id
        image = np.array(Image.open(path_image).convert('L'))
        image = resize(image, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)
        image = np.expand_dims(image, axis=-1)
        out[i] = image  # 修正缩进,放到循环内部
    return out

内容的提问来源于stack exchange,提问作者Snork Maiden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 17:37:33