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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。