FastAI自定义数据集训练ResNet-UNet时遇AttributeError:无'c'属性
问题分析与解决方案
这个错误我之前也碰到过,本质是fastai的unet_learner需要从你的数据对象里获取分割任务的类别数,但你的自定义NumbersDataset没提供这个关键属性,所以触发了AttributeError。下面给你两种可行的解决办法:
方法一:给自定义数据集添加c属性
直接在你的NumbersDataset类里补充类别数属性,比如如果是二分类分割(背景+目标)就设置self.c = 2,多分类就改成对应类别数:
class NumbersDataset(): def __init__(self, inputs, labels, c=2): # 新增c参数,默认二分类 self.X = inputs self.y = labels self.c = c # 关键:添加类别数属性 def __len__(self): return len(self.X) def __getitem__(self, idx): img_train = cv2.imread(self.X[idx]) img_mask = cv2.imread(self.y[idx]) img_train = cv2.resize(img_train, (427,240), interpolation = cv2.INTER_LANCZOS4) img_mask = cv2.resize(img_mask, (427,240), interpolation = cv2.INTER_LANCZOS4) # 补充fastai要求的格式转换:BGR转RGB、通道前置、归一化、掩码转long类型 img_train = cv2.cvtColor(img_train, cv2.COLOR_BGR2RGB) img_train = torch.from_numpy(img_train).permute(2,0,1).float()/255.0 img_mask = torch.from_numpy(img_mask).long() return img_train, img_mask
这里额外补充了格式转换的代码——fastai对输入张量有明确要求:图像需要是通道在前(C,H,W)的RGB格式,且归一化到0-1之间;掩码需要是long类型张量,不然后续训练还会出其他问题。
方法二:使用fastai内置的SegmentationItemList(更推荐)
你说之前试过SegmentationItemList.from_df没效果,大概率是用法不完整。用fastai的内置类可以自动处理格式转换、数据增强同步、类别数识别等细节,示例代码如下:
from fastai.vision import * # 替换成你的图像根文件夹路径 path = Path("./") # 构建完整的数据管道 src = (SegmentationItemList.from_df(df, path, cols='input_img') # 和你之前的train_test_split逻辑一致,按比例划分训练/验证集 .split_by_rand_pct(0.33, seed=42) # 从CSV加载掩码,classes替换成你的实际类别列表 .label_from_df(cols='mask_img', classes=['background', 'target']) # 应用数据增强,tfm_y=True保证图像和掩码做相同变换 .transform(get_transforms(), size=(240, 427), tfm_y=True) # 构建DataBunch .databunch(bs=4, num_workers=2)) # 确认类别数(二分类时src.c会自动设为2,也可以手动指定) print(f"类别数:{src.c}") # 构建Unet模型 learn = unet_learner(src, models.resnet34)
这种方法省去了手动处理格式的麻烦,fastai会帮你搞定大部分细节,出错概率更低。
内容的提问来源于stack exchange,提问作者Sarvagya Gupta
相关产品推荐
相关产品推荐

