佳木斯湛栽影视文化发展公司

主頁(yè) > 知識(shí)庫(kù) > 解決pytorch讀取自制數(shù)據(jù)集出現(xiàn)過的問題

解決pytorch讀取自制數(shù)據(jù)集出現(xiàn)過的問題

熱門標(biāo)簽:銀行業(yè)務(wù) 智能手機(jī) 服務(wù)器配置 鐵路電話系統(tǒng) 網(wǎng)站文章發(fā)布 美圖手機(jī) 檢查注冊(cè)表項(xiàng) 呼叫中心市場(chǎng)需求

問題1

問題描述:

TypeError: default_collate: batch must contain tensors, numpy arrays, numbers, dicts or lists; found class 'PIL.Image.Image'>

解決方式

數(shù)據(jù)格式不對(duì), 把image轉(zhuǎn)成tensor,參數(shù)transform進(jìn)行如下設(shè)置就可以了:transform=transform.ToTensor()。注意檢測(cè)一下transform

問題2

問題描述:

TypeError: append() takes exactly one argument (2 given)

出現(xiàn)問題的地方

imgs.append(words[0], int(words[1]))

解決方式

加括號(hào),如下

imgs.append((words[0], int(words[1])))

問題3

問題描述

RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same

解決方式

數(shù)據(jù)和模型不在同一設(shè)備上,應(yīng)該要么都在GPU運(yùn)行,要么都在CPU

問題4

問題描述

RuntimeError: Given groups=1, weight of size [64, 1, 3, 3], expected input[1, 3, 512, 512] to have 1 channels, but got 3 channels instead

解決方式

圖像竟然是RGB,但我的訓(xùn)練圖像是一通道的灰度圖,所以得想辦法把 mode 轉(zhuǎn)換成灰度圖L

補(bǔ)充:神經(jīng)網(wǎng)絡(luò) pytorch 數(shù)據(jù)集讀取(自動(dòng)讀取數(shù)據(jù)集,手動(dòng)讀取自己的數(shù)據(jù))

對(duì)于pytorch,我們有現(xiàn)成的包裝好的數(shù)據(jù)集可以使用,也可以自己創(chuàng)建自己的數(shù)據(jù)集,大致來說有三種方法,這其中用到的兩個(gè)包是datasets和DataLoader

datasets:用于將數(shù)據(jù)和標(biāo)簽打包成數(shù)據(jù)集

DataLoader:用于對(duì)數(shù)據(jù)集的高級(jí)處理,比如分組,打亂,處理等,在訓(xùn)練和測(cè)試中可以直接使用DataLoader進(jìn)行處理

第一種 現(xiàn)成的打包數(shù)據(jù)集

這種比較簡(jiǎn)答,只需要現(xiàn)成的幾行代碼和一個(gè)路徑就可以完成,但是一般都是常用比如cifar-10

對(duì)于常用數(shù)據(jù)集,可以使用torchvision.datasets直接進(jìn)行讀取,這是對(duì)其常用的處理,該類也是繼承于torch.utils.data.Dataset。

#是第一次運(yùn)行的話會(huì)下載數(shù)據(jù)集 現(xiàn)成的話可以使用root參數(shù)指定數(shù)據(jù)集位置
# 存放的格式如下圖
 
# 根據(jù)接口讀取默認(rèn)的CIFAR10數(shù)據(jù) 進(jìn)行訓(xùn)練和測(cè)試
#預(yù)處理
transform = transform.Compose([transform.ToTensor(), transform.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
#讀取數(shù)據(jù)集
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=False, transform=transform)
#打包成DataLoader
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=1)
 
#同上
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=False, transform=transform)
testloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=False, num_workers=1)
classes = (1,2,3,4,5,6,7,8,9,10)  #類別定義
 
#使用
 for epoch in range(3):
        running_loss = 0.0 #清空loss
        for i, data in enumerate(trainloader, 0):
            # get the inputs
            inputs, labels = data #trainloader返回:id,image,labels
 
            # 將inputs與labels裝進(jìn)Variable中
            inputs, labels = Variable(inputs), Variable(labels)
            
            #使用print代替輸出
            print("epoch:", epoch, "的第", i, "個(gè)inputs", inputs.data.size(), "labels", labels.data.size())
 

第二種 自己的圖像分類

這也是一個(gè)方便的做法,在pytorch中提供了torchvision.datasets.ImageFolder讓我們訓(xùn)練自己的圖像。

要求:創(chuàng)建train和test文件夾,每個(gè)文件夾下按照類別名字存儲(chǔ)圖像就可以實(shí)現(xiàn)dataloader

這里還是拿上個(gè)舉例子吧,實(shí)際上也可以是我們的數(shù)據(jù)集

每個(gè)下面的布局是這樣的

# 預(yù)處理
transform = transform.Compose([transform.ToTensor(), transform.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
 
#使用torchvision.datasets.ImageFolder讀取數(shù)據(jù)集 指定train 和 test文件夾
img_data = torchvision.datasets.ImageFolder('data/cifar-10/train/', transform=transform)
data_loader = torch.utils.data.DataLoader(img_data, batch_size=4, shuffle=True, num_workers=1)
 
testset = torchvision.datasets.ImageFolder('data/cifar-10/test/', transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=True, num_workers=1)
 
 for epoch in range(3):
        for i, data in enumerate(trainloader, 0):
            # get the inputs
            inputs, labels = data #trainloader返回:id,image,labels
            # 將inputs與labels裝進(jìn)Variable中
            inputs, labels = Variable(inputs), Variable(labels)
 
            #使用print代替輸出
            print("epoch:", epoch, "的第", i, "個(gè)inputs", inputs.data.size(), "labels", labels.data.size())

第三種 一維向量數(shù)據(jù)集

這個(gè)是比較尷尬的,首先我們

假設(shè)將數(shù)存儲(chǔ)到txt等文件中,先把他讀取出來,讀取的部分就不仔細(xì)說了,讀到一個(gè)列表里就可以

常用的可以是列表等,舉例子

trainlist = []  # 保存特征的列表
 
targetpath = 'a/b/b'
filelist = os.listdir(targetpath) #列出文件夾下所有的目錄與文件
filecount = len(filelist)
# 根據(jù)根路徑 讀取所有文件名 循環(huán)讀取文件內(nèi)容 添加到list
for i in range(filecount):
     filepath = os.path.join(targetpath, filelist[j])
     with open(filepath, 'r') as f:
         line = f.readline()
         # 例如存儲(chǔ)格式為 1,2,3,4,5,6 數(shù)字之間以逗號(hào)隔開
         templist = list(map(int, line.split(',')))
         trainlist.append(templist)
 
# 數(shù)據(jù)讀取完畢 現(xiàn)在為維度為filecount的列表 我們需要轉(zhuǎn)換格式和類型
# 將數(shù)據(jù)轉(zhuǎn)換為Tensor
 
# 假如我們的兩類數(shù)據(jù)分別存在list0 和 list1中
split = len(list0) # 用于記錄標(biāo)簽的分界
 
#使用numpy.array 和 torch.from_numpy 連續(xù)將其轉(zhuǎn)換為tensor  使用torch.cat拼接
train0_numpy = numpy.array(list0)
train1_numpy = numpy.array(list1)
train_tensor = torch.cat([torch.from_numpy(train0_numpy), torch.from_numpytrain1_numpy)], 0)
#現(xiàn)在的尺寸是【樣本數(shù),長(zhǎng)度】 然而在使用神 經(jīng)網(wǎng)絡(luò)處理一維數(shù)據(jù)要求【樣本數(shù),維度,長(zhǎng)度】
# 這個(gè)維度指的像一個(gè)圖像實(shí)際上是一個(gè)二維矩陣 但是有三個(gè)RGB通道 實(shí)際就為【3,行,列】 那么需要處理三個(gè)矩陣
# 我們需要在我們的數(shù)據(jù)中加上這個(gè)維度信息
# 注意類型要一樣 可以轉(zhuǎn)換
shaper = train_tensor.shape  #獲取維度 【樣本數(shù),長(zhǎng)度】
aa = torch.ones((shaper[0], 1, shaper[1])) # 生成目標(biāo)矩陣
for i in range(shaper[0]):  # 將所有樣本復(fù)制到新矩陣
·    aa[i][0][:] = train_tensor[i][:]
train_tensor = aa  # 完成了數(shù)據(jù)集的轉(zhuǎn)換 【樣本數(shù),維度,長(zhǎng)度】
 
# 注 意 如果是讀取的圖像 我們需要的目標(biāo)維度是【樣本數(shù),維度,size_w,size_h】
# 卷積接受的輸入是這樣的四維度 最后的兩個(gè)是圖像的尺寸 維度表示是通道數(shù)量 
  
# 下面是生成標(biāo)簽 標(biāo)簽注意類別之間的分界 split已經(jīng)在上文計(jì)算出來
# 訓(xùn)練標(biāo)簽的
total = len(list0) + len(list1)
train_label = numpy.zeros(total)
train_label[split+1:total] = 1
train_label_tensor = torch.from_numpy(train_label).int()
# print(train_tensor.size(),train_label_tensor.size())
 
# 搭建dataloader完畢
train_dataset = TensorDataset(train_tensor, train_label_tensor)
train_loader = DataLoader(dataset=train_dataset, batch_size=4, shuffle=True)
 
for epoch in range(3):
    for i, data in enumerate(trainloader, 0):
        # get the inputs
        inputs, labels = data #trainloader返回:id,image,labels
        # 將inputs與labels裝進(jìn)Variable中
        inputs, labels = Variable(inputs), Variable(labels)
 
        #使用print代替輸出
        print("epoch:", epoch, "的第", i, "個(gè)inputs", inputs.data.size(), "labels", labels.data.size())

第四種 保存路徑和標(biāo)簽的方式創(chuàng)建數(shù)據(jù)集

該方法需要略微的麻煩一些,首先你有一個(gè)txt,保存了文件名和對(duì)應(yīng)的標(biāo)簽,大概是這個(gè)意思

然后我們?cè)诔绦蛑?,根?jù)給定的根目錄找到文件,并將標(biāo)簽對(duì)應(yīng)保存

class Dataset(object):
"""An abstract class representing a Dataset.
All other datasets should subclass it. All subclasses should override
``__len__``, that provides the size of the dataset, and ``__getitem__``,
supporting integer indexing in range from 0 to len(self) exclusive.
"""
def __getitem__(self, index):
	raise NotImplementedError
def __len__(self):
	raise NotImplementedError
def __add__(self, other):
	return ConcatDataset([self, other])

這是dataset的原本內(nèi)容,getitem就是獲取元素的部分,用于返回對(duì)應(yīng)index的數(shù)據(jù)和標(biāo)簽。那么大概需要做的是我們將txt的內(nèi)容讀取進(jìn)來,使用程序處理標(biāo)簽和數(shù)據(jù)

# coding: utf-8
from PIL import Image
from torch.utils.data import Dataset
class MyDataset(Dataset):
# 初始化讀取txt 可以設(shè)定變換
def __init__(self, txt_path, transform = None, target_transform = None):
	fh = open(txt_path, 'r')
	imgs = []
	for line in fh:
		line = line.rstrip()
		words = line.split()
         # 保存列表 其中有圖像的數(shù)據(jù) 和標(biāo)簽
		imgs.append((words[0], int(words[1])))
		self.imgs = imgs 
		self.transform = transform
		self.target_transform = target_transform
def __getitem__(self, index):
	fn, label = self.imgs[index]
	img = Image.open(fn).convert('RGB') 
	if self.transform is not None:
		img = self.transform(img) 
    # 返回圖像和標(biāo)簽
    
	return img, label
def __len__(self):
	return len(self.imgs)
 
# 當(dāng)然也可以創(chuàng)建myImageFloder 其txt格式在下圖顯示 
import os
import torch
import torch.utils.data as data
from PIL import Image 
def default_loader(path):
    return Image.open(path).convert('RGB')
 
class myImageFloder(data.Dataset):
    def __init__(self, root, label, transform = None, target_transform=None, loader=default_loader):
        fh = open(label) #打開label文件
        c=0
        imgs=[]  # 保存圖像的列表
        class_names=[]
        for line in  fh.readlines(): #讀取每一行數(shù)據(jù)
            if c==0:
                class_names=[n.strip() for n in line.rstrip().split('	')] 
            else:
                cls = line.split() #分割為列表
                fn = cls.pop(0)  #彈出最上的一個(gè)
                if os.path.isfile(os.path.join(root, fn)):  # 組合路徑名 讀取圖像
                    imgs.append((fn, tuple([float(v) for v in cls])))  #添加到列表
            c=c+1
 
        # 設(shè)置信息
        self.root = root
        self.imgs = imgs
        self.classes = class_names
        self.transform = transform
        self.target_transform = target_transform
        self.loader = loader
 
    def __getitem__(self, index):  # 獲取圖像 給定序號(hào)
        fn, label = self.imgs[index]  #讀取圖像的內(nèi)容和對(duì)應(yīng)的label
        img = self.loader(os.path.join(self.root, fn))
        if self.transform is not None:  # 是否變換
            img = self.transform(img)
        return img, torch.Tensor(label) # 返回圖像和label
 
    def __len__(self):
        return len(self.imgs)
    
    def getName(self):
        return self.classes
# 

# 而后使用的時(shí)候就可以正常的使用
trainset = MyDataset(txt_path=pathFile,transform = None, target_transform = None)
# trainset = torch.utils.data.DataLoader(myFloder.myImageFloder(root = "../data/testImages/images", label = "../data/testImages/test_images.txt", transform = mytransform ), batch_size= 2, shuffle= False, num_workers= 2)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True, num_workers=8)

它的要點(diǎn)是,繼承dataset,在初始化中處理txt文本數(shù)據(jù),保存對(duì)應(yīng)的數(shù)據(jù),并實(shí)現(xiàn)對(duì)應(yīng)的功能。

這其中的原理就是如此,但是注意可能有些許略微不恰當(dāng)?shù)牡胤?,可能就需要到時(shí)候現(xiàn)場(chǎng)調(diào)試了。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • pytorch 如何把圖像數(shù)據(jù)集進(jìn)行劃分成train,test和val
  • Pytorch中的數(shù)據(jù)集劃分&正則化方法
  • pytorch學(xué)習(xí)教程之自定義數(shù)據(jù)集
  • pytorch加載語音類自定義數(shù)據(jù)集的方法教程
  • pytorch加載自己的圖像數(shù)據(jù)集實(shí)例
  • pytorch VGG11識(shí)別cifar10數(shù)據(jù)集(訓(xùn)練+預(yù)測(cè)單張輸入圖片操作)

標(biāo)簽:樂山 滄州 紅河 上海 長(zhǎng)治 新疆 河南 沈陽

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《解決pytorch讀取自制數(shù)據(jù)集出現(xiàn)過的問題》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    菏泽市| 秦皇岛市| 张家口市| 奉新县| 丽江市| 甘洛县| 宁海县| 泾源县| 石首市| 秭归县| 石门县| 宜春市| 弥渡县| 鄢陵县| 瑞丽市| 扬州市| 团风县| 景谷| 曲水县| 丘北县| 盐池县| 尼勒克县| 佳木斯市| 即墨市| 宿松县| 焉耆| 邵东县| 资阳市| 松溪县| 山西省| 西安市| 北海市| 安图县| 永清县| 茶陵县| 巴林左旗| 枣阳市| 格尔木市| 车致| 新乐市| 科技|