我是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')
1条答案
按热度按时间zmeyuzjn1#
您将返回一个字典,而不是其余代码所需的元组。
转换后,
ToTensor
函数的return {'image': torch.from_numpy(image),'label': label}
被inputs, labels = data
部分拆分,因此inputs
和labels
包含键名而不是值(因为它是一个字典)。尝试返回一个元组:
return torch.from_numpy(image), label
如果你使用转换,你的实现应该是通用的,所以你应该改变更多的东西:
您可以看到,在您的附加教程,使用字典,他们直接访问的值与
这两种方法都可以工作,我看到元组版本使用得更多。