0
votes

I got an error while running pytorch I train artificial intelligence with ResNet, and I wrote my own custom dataset for the dataset. After loading the data set from ResnNet, training data and test data were set separately by learning with artificial intelligence. But even though I ran it, an error occurred, but I don't know what kind of problem occurred. Next, I will attach my ResNet.py code and my own data set CustomDataset.py code.

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torchvision import transforms, datasets, models
    from customDataset import CatsAndDogsDataset
    
    USE_CUDA = torch.cuda.is_available()
    DEVICE = torch.device("cuda" if USE_CUDA else "cpu")
    
    EPOCHS = 3
    BATCH_SIZE = 10
    
    dataset = CatsAndDogsDataset(csv_file = 'cats_dogs.csv', root_dir = 'cats_dogs_resized',transform = transforms.ToTensor())
    
    train_set, test_set = torch.utils.data.random_split(dataset, [28,4])
    train_loader = DataLoader(dataset=train_set, batch_size=BATCH_SIZE, shuffle=True)
    test_loader = DataLoader(dataset=test_set, batch_size=BATCH_SIZE, shuffle=True)
    
    class BasicBlock(nn.Module):
    def __init__(self, in_planes, planes, stride=1):
    super(BasicBlock, self).__init__()
    self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3,stride=stride, padding=1, bias=False)
    self.bn1 = nn.BatchNorm2d(planes)
    self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,stride=1, padding=1, bias=False)
    self.bn2 = nn.BatchNorm2d(planes)
    
    self.shortcut = nn.Sequential()
    if stride != 1 or in_planes != planes:
    self.shortcut = nn.Sequential(nn.Conv2d(in_planes, planes,kernel_size=1, stride=stride, bias=False),
    nn.BatchNorm2d(planes))
    
    def forward(self, x):
    out = F.relu(self.bn1(self.conv1(x)))
    out = self.bn2(self.conv2(out))
    out += self.shortcut(x)
    out = F.relu(out)
    return out
    
    class ResNet(nn.Module):
    def __init__(self, num_classes=10):
    super(ResNet, self).__init__()
    self.in_planes = 16
    
    self.conv1 = nn.Conv2d(3, 16, kernel_size=3,stride=1, padding=1, bias=False)
    self.bn1 = nn.BatchNorm2d(16)
    self.layer1 = self._make_layer(16, 2, stride=1)
    self.layer2 = self._make_layer(32, 2, stride=2)
    self.layer3 = self._make_layer(64, 2, stride=2)
    self.linear = nn.Linear(64, num_classes)
    
    def _make_layer(self, planes, num_blocks, stride):
    strides = [stride] + [1] * (num_blocks - 1)
    layers = []
    for stride in strides:
    layers.append(BasicBlock(self.in_planes, planes, stride))
    self.in_planes = planes
    return nn.Sequential(*layers)
    
    def forward(self, x):
    out = F.relu(self.bn1(self.conv1(x)))
    out = self.layer1(out)
    out = self.layer2(out)
    out = self.layer3(out)
    out = F.avg_pool2d(out, 8)
    out = out.view(out.size(0), -1)
    out = self.linear(out)
    return out
    
    
    model = ResNet().to(DEVICE)
    optimizer = optim.SGD(model.parameters(), lr=0.1,momentum=0.9, weight_decay=0.0005)
    scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.1)
    
    print(model)
    
    
    def train(model, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
    data, target = data.to(DEVICE), target.to(DEVICE)
    optimizer.zero_grad()
    output = model(data)
    loss = F.cross_entropy(output, target)
    loss.backward()
    optimizer.step()
    
    
    def evaluate(model, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
    for data, target in test_loader:
    data, target = data.to(DEVICE), target.to(DEVICE)
    output = model(data)
    
    test_loss += F.cross_entropy(output, target,reduction='sum').item()
    
    pred = output.max(1, keepdim=True)[1]
    correct += pred.eq(target.view_as(pred)).sum().item()
    
    test_loss /= length(test_loader.dataset)
    test_accuracy = 100. * correct / length(test_loader.dataset)
    return test_loss, test_accuracy
    
    
    
    for epoch in range(1, EPOCHS + 1):
    scheduler.step()
    train(model, train_loader, optimizer, epoch)
    test_loss, test_accuracy = evaluate(model, test_loader)
    
    print('[{}] Test Loss: {:.4f}, Accuracy: {:.2f}%'.format(
    epoch, test_loss, test_accuracy))


import os
import pandas as pd
import torch
from torch.utils.data import Dataset
from skimage import io

    class CatsAndDogsDataset(Dataset):
    def __init__(self, csv_file, root_dir, transform=None):
    self.annotations = pd.read_csv(csv_file)
    self.root_dir = root_dir
    self.transform = transform
    
    def __length__(self):
    return length(self.annotations)
    
    def __getitem__(self, index):
    img_path = os.path.join(self.root_dir, self.annotations.iloc[index, 0])
    image = io.imread(img_path)
    y_label = torch.tensor(int(self.annotations.iloc[index, 1]))
    
    if self.transform:
    image = self.transform(image)
    
    return (image, ylabel)

In this way, if I write the code and then run it TypeError: object of type'CatsAndDogsDataset' has no len() I wonder why I can't have len(). In addition, an error occurred in the result of running Backend.ai instead of pycharm, but the error content is

Cannot verify that dataset is Sized

if sum(lengths) != len(dataset): It is raise ValueError("sum of input lengths does not equal the length of the input dataset!"). Error appears. Is there a workaround? help me plz

1

1 Answers

0
votes

You need to define the function __len__ for your custom dataset (which you seem to have currently incorrectly defined as __length__).

This documentation provides details. Relevant excerpt:

torch.utils.data.Dataset is an abstract class representing a dataset. Your custom dataset should inherit Dataset and override the following methods:

  • __len__ so that len(dataset) returns the size of the dataset.
  • __getitem__ to support the indexing such that dataset[i] can be used to get i th sample.