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

使用fastai的unet_learner做迁移学习报Target 20越界错误如何解决?

错误原因

这个报错的核心是模型输出的类别数和实际标签中的最大值不匹配:fastai的分割模型默认使用codes数组的长度作为输出类别数,索引从0开始计数。
从你提供的信息可以直接定位问题:

  1. 你的标签中存在数值20,意味着需要codes数组至少有21个元素(索引范围0~20)
  2. 你输出的codes数组只有20个元素,最大索引为19,完全匹配不上标签的20值,因此触发越界错误。
    进一步排查可以打印len(codes)和dls.c验证:dls.c是fastai识别的类别数,此时输出一定是20,和你的标签最大值20不匹配。

解决方法

根据你的实际类别数二选一处理:

情况1:你确实有21个类别(标签值范围0~20)

你在转换codes数组时指定了dtype='<U17',限制了字符串长度,同时大概率遗漏了最后一个类别Palustrine Aquatic Bed。修改codes生成逻辑即可:

# 去掉固定字符串长度限制,直接转换
codes = np.array(classes_list)
# 确认长度为21后再传入dls
print(len(codes))

重新生成dls后,dls.c会变为21,匹配标签的最大值。

情况2:你实际只有20个类别(标签值范围1~20,从1开始计数)

这种情况需要把标签值统一减1,映射到0~19的索引范围,和20个长度的codes对应。你可以在创建dls时自定义标签处理逻辑:

def label_func(fn): 
    label_path = pathB/"labels"/f"{fn.stem}_P.png"
    # 读取标签后把所有值减1
    y = np.array(Image.open(label_path)) - 1
    return PILMask.create(y)

# 生成dls的时候传入自定义的y处理逻辑
dls = SegmentationDataLoaders.from_label_func(
    pathB, bs=8, fnames = fnames, 
    label_func = label_func, codes = codes
)

处理完成后再执行unet_learner和fine_tune即可正常运行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 10:39:02