Evaluation on sipakmed
一、理论分析
这一部分主要是说论文的评估策略。我第一次看以为这个5-folder是五个目录下的数据进行验证,太天真了。这里的5-folder cross validation是五折交叉验证的意思:
- 把所有的数据等分为五份(因为是五折,如果是十折就是十份)
- 每一次选这五份中的一份作为测试集,剩下的就是训练集
- 直到每份都作为了一次测试集
- 也就是说,所有的数据被训练了五次,最后用五次测试的平均精度来评估模型
二、代码(纯python)
-
数据集目录
-
现在要做的就是把每次的训练测试集数据单独划分到一个文件夹下,因为五份被划分出来之后,每一份的内容、索引都已经确定了。
如下图所示
为什么要在每个文件夹下也要按类别建立子文件夹?(如下图所示)因为我用的是pytorch的imageFolder来加载本地数据集,对数据集的目录要求比较严格。当然也可以采用重写Dataset方法来实现。
-
在每个train和test文件夹下放入对应的图片
-
首先把所有的数据按
"the absolute path of each image" "label"
的格式把写入txt文件(中间用空格隔开,当然也可以用,隔开)path要改成你本地的路径
#这个脚本就是遍历所有数据,把它的绝对路径和标签写入txt文件 #path就写成datasets/sipakmedPics的绝对路径 def getAllPicsTxt(path): f = open(path+"\\"+"pics.txt",'w+') classes = os.listdir(path) for index,c in enumerate(classes): if(c.startswith("im")): img_base_path = path+"\\"+c imgs = os.listdir(img_base_path) for img in imgs: f.writelines(img_base_path+"\\"+img+" "+str(index)+"\n")
这里的类别从上到下分别对应0 1 2 3 4
运行完之后会生成pic.txt文件
-
将所有数据从txt文件读入,并转化为一个list,打乱顺序和平均分为5份。
import rando import numpy as np def func(listTemp, n): for i in range(0, len(listTemp), n): yield listTemp[i:i + n] if __name__ == '__main__': n=5 #要改! allFile = open("your path\\datasets\\sipakmedPics\\pics.txt",'r') #get all data files = [] for file in allFile.readlines(): files.append(file) total = len(files) #打乱顺序 random.shuffle(files f = func(files,(int)(total/n)) #把平均分成的5份转化成list f = list(f) #现在f是一个列表,每一个元素是一个长度为3239的列表 #每一个元素是txt文件的一行 for index,i in enumerate(f): #由于不能所有的数据集/5不能整除,最后是有六份,所以这里判断一下 if index !=5: #要改路径!!! trainFile = open("your path\\datasets\\sipakmedPics\\train"+str(index)+".txt", 'w+') testFile = open("your path\\datasets\\sipakmedPics\\test"+str(index)+".txt",'w+') for k in range(0,n): if k == index: for j in i: testFile.write(j) else: for j in i: trainFile.write(j)
运行完是这样的(这个时候train_test文件夹是没有的)
3. 将testX.txt trainX.txt里面对应的图片放到train_test文件夹下的对应文件夹里。
先手动创建train_test文件夹,我代码里没写
import os
from shutil import copyfile
n = 5
class_to_index = {"0":"im_Dyskeratotic","1":"im_Koilocytotic","2":"im_Metaplastic","3":"im_Parabasal","4":"im_Superficial-Intermediate",}
#改路
path = "your path\\datasets\\sipakmedPics"
data = [txt for txt in os.listdir(path) if txt.endswith('.txt')]
print(data)
#改路径
img_path = "your path\\datasets\\sipakmedPics\\train_test"
for txt in data:
if txt != "pics.txt":
os.mkdir(img_path+"\\"+txt[0:txt.index('.')])
#改路径
file = open("your path\\datasets\\sipakmedPics\\"+txt,'r')
files = []
for line in file.readlines():
files.append(line)
for eachImg in files:
img = eachImg.split(' ',1)
print(img)
if os.path.exists(img_path+"\\"+txt[0:txt.index('.')]+"\\"+class_to_index[img[1][0]]) == False:
os.mkdir(img_path+"\\"+txt[0:txt.index('.')]+"\\"+class_to_index[img[1][0]])
copyfile(img[0],img_path+"\\"+txt[0:txt.index('.')]+"\\"+class_to_index[img[1][0]]+"\\"+img[0].split("\\",6)[6])
这样,训练测试集的划分数据就完成了