pytorch从csv加载自定义数据模板的操作
整理了一套模板,全注释了,这个难点终于克服了
fromPILimportImage importpandasaspd importnumpyasnp importtorchvision.transformsastransforms fromtorch.utils.dataimportDataset,DataLoader importos #放文件的路径 dir_path='./97/train/' csv_path='./97/train.csv' classMydataset(Dataset): #传递数据路径,csv路径,数据增强方法 def__init__(self,dir_path,csv,transform=None,target_transform=None): super(Mydataset,self).__init__() #一个个往列表里面加绝对路径 self.path=[] #读取csv self.data=pd.read_csv(csv) #对标签进行硬编码,例如01234,把字母变成这个 colorMap={elem:index+1forindex,eleminenumerate(set(self.data["label"]))} self.data['label']=self.data['label'].map(colorMap) #创造空的label准备存放标签 self.num=int(self.data.shape[0])#一共多少照片 self.label=np.zeros(self.num,dtype=np.int32) #迭代得到数据路径和标签一一对应 forindex,rowinself.data.iterrows(): self.path.append(os.path.join(dir_path,row['filename'])) self.label[index]=row['label']#将数据全部读取出来 #训练数据增强 self.transform=transform #验证数据增强在这里没用 self.target_transform=target_transform #最关键的部分,在这里使用前面的方法 def__getitem__(self,index): img=Image.open(self.path[index]).convert('RGB') labels=self.label[index] #在这里做数据增强 ifself.transformisnotNone: img=self.transform(img)#转化tensor类型 returnimg,labels def__len__(self): returnlen(self.data) #数据增强的具体内容 transform=transforms.Compose( [transforms.ToTensor(), transforms.Resize(150), transforms.CenterCrop(150), transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))] ) #加载数据 train_data=Mydataset(dir_path=dir_path,csv=csv_path,transform=transform) trainloader=DataLoader(train_data,batch_size=16,shuffle=True,num_workers=0) #迭代训练 fori_batch,batch_datainenumerate(trainloader): image,label=batch_data
补充:pytorch—定义自己的数据集及加载训练
笔记:pytorchConv2d的宽高公式理解,pytorch使用自己的数据集并且加载训练
一、pypi镜像使用帮助
pypi镜像每5分钟同步一次。
临时使用
pipinstall-ihttps://pypi.tuna.tsinghua.edu.cn/simplesome-package
注意,simple不能少,是https而不是http
设为默认
修改~/.config/pip/pip.conf(Linux),%APPDATA%\pip\pip.ini(Windows10)或$HOME/Library/ApplicationSupport/pip/pip.conf(macOS)(没有就创建一个),修改index-url至tuna,例如
[global] index-url=https://pypi.tuna.tsinghua.edu.cn/simple
pip和pip3并存时,只需修改~/.pip/pip.conf。
二、pytorchConv2d的宽高公式理解
三、pytorch使用自己的数据集并且加载训练
importos importsys importnumpyasnp importcv2 importtorch importtorch.nnasnn importtorchvision.transformsastransforms fromtorch.utils.dataimportDataLoader,Dataset importtime importrandom importcsv fromPILimportImage defcreateImgIndex(dataPath,ratio): ''' 读取目录下面的图片制作包含图片信息、图片label的train.txt和val.txt dataPath:图片目录路径 ratio:val占比 return:label列表 ''' fileList=os.listdir(dataPath) random.shuffle(fileList) classList=[]#label列表 #val数据集制作 withopen('data/val_section1015.csv','w')asf: writer=csv.writer(f) foriinrange(int(len(fileList)*ratio)): row=[] if'.jpg'infileList[i]: fileInfo=fileList[i].split('_') sectionName=fileInfo[0]+'_'+fileInfo[1]#切面名+标准与否 row.append(os.path.join(dataPath,fileList[i]))#图片路径 ifsectionNamenotinclassList: classList.append(sectionName) row.append(classList.index(sectionName)) writer.writerow(row) f.close() #train数据集制作 withopen('data/train_section1015.csv','w')asf: writer=csv.writer(f) foriinrange(int(len(fileList)*ratio)+1,len(fileList)): row=[] if'.jpg'infileList[i]: fileInfo=fileList[i].split('_') sectionName=fileInfo[0]+'_'+fileInfo[1]#切面名+标准与否 row.append(os.path.join(dataPath,fileList[i]))#图片路径 ifsectionNamenotinclassList: classList.append(sectionName) row.append(classList.index(sectionName)) writer.writerow(row) f.close() print(classList,len(classList)) returnclassList defdefault_loader(path): '''定义读取文件的格式''' returnImage.open(path).resize((128,128),Image.ANTIALIAS).convert('RGB') classMyDataset(Dataset): '''Dataset类是读入数据集数据并且对读入的数据进行索引''' def__init__(self,txt,transform=None,target_transform=None,loader=default_loader): super(MyDataset,self).__init__()#对继承自父类的属性进行初始化 fh=open(txt,'r')#按照传入的路径和txt文本参数,以只读的方式打开这个文本 reader=csv.reader(fh) imgs=[] forrowinreader: imgs.append((row[0],int(row[1])))#(图片信息,lable) self.imgs=imgs self.transform=transform self.target_transform=target_transform self.loader=loader def__getitem__(self,index): '''用于按照索引读取每个元素的具体内容''' #fn是图片path#fn和label分别获得imgs[index]也即是刚才每行中row[0]和row[1]的信息 fn,label=self.imgs[index] img=self.loader(fn) ifself.transformisnotNone: img=self.transform(img)#数据标签转换为Tensor returnimg,label def__len__(self): '''返回数据集的长度''' returnlen(self.imgs) classModel(nn.Module): def__init__(self,classNum=31): super(Model,self).__init__() #torch.nn.Conv2d(in_channels,out_channels,kernel_size,stride,padding) #torch.nn.MaxPool2d(kernel_size,stride,padding) #input维度[3,128,128] self.cnn=nn.Sequential( nn.Conv2d(3,64,3,1,1),#[64,128,128] nn.BatchNorm2d(64), nn.ReLU(), nn.MaxPool2d(2,2,0),#[64,64,64] nn.Conv2d(64,128,3,1,1),#[128,64,64] nn.BatchNorm2d(128), nn.ReLU(), nn.MaxPool2d(2,2,0),#[128,32,32] nn.Conv2d(128,256,3,1,1),#[256,32,32] nn.BatchNorm2d(256), nn.ReLU(), nn.MaxPool2d(2,2,0),#[256,16,16] nn.Conv2d(256,512,3,1,1),#[512,16,16] nn.BatchNorm2d(512), nn.ReLU(), nn.MaxPool2d(2,2,0),#[512,8,8] nn.Conv2d(512,512,3,1,1),#[512,8,8] nn.BatchNorm2d(512), nn.ReLU(), nn.MaxPool2d(2,2,0),#[512,4,4] ) self.fc=nn.Sequential( nn.Linear(512*4*4,1024), nn.ReLU(), nn.Linear(1024,512), nn.ReLU(), nn.Linear(512,classNum) ) defforward(self,x): out=self.cnn(x) out=out.view(out.size()[0],-1) returnself.fc(out) deftrain(train_set,train_loader,val_set,val_loader): model=Model() loss=nn.CrossEntropyLoss()#因为是分类任务,所以lossfunction使用CrossEntropyLoss optimizer=torch.optim.Adam(model.parameters(),lr=0.001)#optimizer使用Adam num_epoch=10 #开始训练 forepochinrange(num_epoch): epoch_start_time=time.time() train_acc=0.0 train_loss=0.0 val_acc=0.0 val_loss=0.0 model.train()#trainmodel会开放Dropout和BN fori,datainenumerate(train_loader): optimizer.zero_grad()#用optimizer將model參數的gradient歸零 train_pred=model(data[0])#利用model的forward函数返回预测结果 batch_loss=loss(train_pred,data[1])#计算loss batch_loss.backward()#tensor(item,grad_fn=) optimizer.step()#以optimizer用gradient更新参数 train_acc+=np.sum(np.argmax(train_pred.data.numpy(),axis=1)==data[1].numpy()) train_loss+=batch_loss.item() model.eval() withtorch.no_grad():#不跟踪梯度 fori,datainenumerate(val_loader): #data=[imgData,labelList] val_pred=model(data[0]) batch_loss=loss(val_pred,data[1]) val_acc+=np.sum(np.argmax(val_pred.data.numpy(),axis=1)==data[1].numpy()) val_loss+=batch_loss.item() #打印结果 print('[%03d/%03d]%2.2fsec(s)TrainAcc:%3.6fLoss:%3.6f|ValAcc:%3.6floss:%3.6f'%\ (epoch+1,num_epoch,time.time()-epoch_start_time,\ train_acc/train_set.__len__(),train_loss/train_set.__len__(),val_acc/val_set.__len__(), val_loss/val_set.__len__())) if__name__=='__main__': dirPath='/data/Matt/QC_images/test0916'#图片文件目录 createImgIndex(dirPath,0.2)#创建train.txt,val.txt root=os.getcwd()+'/data/' train_data=MyDataset(txt=root+'train_section1015.csv',transform=transforms.ToTensor()) val_data=MyDataset(txt=root+'val_section1015.csv',transform=transforms.ToTensor()) train_loader=DataLoader(dataset=train_data,batch_size=6,shuffle=True,num_workers=4) val_loader=DataLoader(dataset=val_data,batch_size=6,shuffle=False,num_workers=4) #开始训练模型 train(train_data,train_loader,val_data,val_loader)
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。