起因于合并 train 和 valid 文件夹下的文件用以重新划分训练/验证集
如果你将train
文件夹和valid
文件夹下的内容合并成一个新的文件夹(为了做 cross validation),那么在做 K-fold 的时候,序号一定要 shuffle 去打乱,你只要默认打乱了,就不需要考虑太多,否则就会出现一种情况:验证集的 label 有可能在训练集中不存在,那就意味着,你的模型可能几乎没见过验证集里面的 label,如果完全没见过,那 acc 甚至有可能是 0。下面是我当时疏忽导致的 bug:
这个错误完全是因为我在 Dataloader 中使用了shuffle=True,然后偷懒不打乱 (shuffle) 索引导致的,第一次运行的时候,甚至跑出了 acc=0。
下面是我代码中 Dataset 的简化版本,希望能帮助你更好的理解和定位问题:
class Dataset(Dataset):
def __init__(self,path):
super(FoodDataset).__init__()
self.path = path
self.files = sorted([os.path.join(path,x) for x in os.listdir(path) if x.endswith(".jpg")])
def __len__(self):
return len(self.files)
def __getitem__(self,idx):
fname = self.files[idx]
im = Image.open(fname)
try:
label = int(fname.split("/")[-1].split("_")[0])
except:
label = -1 # test has no label
return im,label
数据集命名格式:label_index.jpg
Dataset 中, sorted 将文件按顺序排列,这导致了一个问题,那就是不同的 label 也是按顺序的,如果索引时不打乱(shuffle),就会出现上面所说的问题。
下面是取 label 的代码演示:
print(int('./merge/1_0001'.split("/")[-1].split("_")[0]))
>> 1