Pytorch自定义数据集未正确加载

b4lqfgs4  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(156)

我是AI/ML的新手,在创建自定义数据集时遇到了问题。我尝试按照https://pytorch.org/tutorials/beginner/data_loading_tutorial.html操作,但我的数据集没有正确创建,或者我做错了什么。我会感谢任何反馈。
当我运行这段代码时,我得到错误:TypeError: conv2d(): argument 'input' (position 1) must be Tensor, not str
这似乎是因为当animal_trainset变量被创建为所有image时,标签对现在被设置为字符串'image'和'label'。我已经检查了MyDataset函数和ToTensor函数,图像和标签似乎正确,但当组合起来时,有些东西会中断。
下面是我的代码:

import os
import torch
import pandas as pd
from skimage import io, transform
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, utils
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

class MyDataset(Dataset):

    def __init__(self, csv_file, transform=None):
        self.animals = pd.read_csv(csv_file)
        self.transform = transform

    def __len__(self):
        return len(self.animals)

    def __getitem__(self, idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()

        img_name = self.animals.iloc[idx, 0]
        if 'cat' in img_name:
            label = 'cat'
        if 'dog' in img_name:
            label = 'dog'
        if 'rat' in img_name:
            label = 'rat'
        if 'bat' in img_name:
            label = 'bat'
        else:
            label = 'lizard'
        image = io.imread(img_name)
        sample = {'image': image, 'label': label}
        print(label)

        if self.transform:
            sample = self.transform(sample)

        return sample

class ToTensor(object):
    def __call__(self, sample):
        image, label = sample['image'], sample['label']

        # swap color axis because
        # numpy image: H x W x C
        # torch image: C x H x W
        image = image.transpose((2, 0, 1))
        print(label)
        return {'image': torch.from_numpy(image),'label': label}

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = torch.flatten(x, 1) # flatten all dimensions except batch
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

fig = plt.figure()

animal_trainset = MyDataset(csv_file = '/Classifier/CombinedCSV.csv', transform=ToTensor())
animal_trainloader = DataLoader(animal_trainset, batch_size=4)

animal_testset = MyDataset(csv_file = '/Classifier/CombinedCSV.csv', transform=ToTensor())
animal_testloader = DataLoader(animal_testset, batch_size=4)

classes = ('dog', 'cat', 'bat', 'rat', 'lizard')

net = Net()

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(animal_trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        print(inputs)
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 2000:.3f}')
            running_loss = 0.0

print('Finished Training')
zmeyuzjn

zmeyuzjn1#

您将返回一个字典,而不是其余代码所需的元组。
转换后,ToTensor函数的return {'image': torch.from_numpy(image),'label': label}inputs, labels = data部分拆分,因此inputslabels包含键名而不是值(因为它是一个字典)。
尝试返回一个元组:return torch.from_numpy(image), label
如果你使用转换,你的实现应该是通用的,所以你应该改变更多的东西:

...
  def __getitem__(self, idx):
        ...
        image = io.imread(img_name)
        sample = (image, label)
        print(label)

        if self.transform:
            sample = self.transform(sample)

        return sample

class ToTensor(object):
    def __call__(self, sample):
        image, label = sample
        
        ...

        return (torch.from_numpy(image), label)

您可以看到,在您的附加教程,使用字典,他们直接访问的值与

print(i_batch, sample_batched['image'].size(),
          sample_batched['landmarks'].size())

这两种方法都可以工作,我看到元组版本使用得更多。

相关问题