spflmm 发表于 2023-5-20 16:43:51

TypeError: 'DataLoader' object is not callable

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
import torchvision
from torchvision import transforms
import os
import shutilimg_dir = r'./dataset2'
base_dir = r"./dataset/4weather"specises = ['cloudy', 'rain', 'shine', 'sunrise']
if not os.path.isdir(base_dir):
    os.mkdir(base_dir)
    train_dir = os.path.join(base_dir,'train')
    test_dir = os.path.join(base_dir, 'test')
    os.mkdir(train_dir)
    os.mkdir(test_dir)
    for train_or_test in['train','test']:
      for spec in specises:
            os.mkdir(os.path.join(base_dir,train_or_test,spec))for i,img in enumerate(os.listdir(img_dir)):#img_dir = r'./dataset2'
    for spec in specises:#specises = ['cloudy', 'rain', 'shine', 'sunrise']
      if spec in img:
            s = os.path.join(img_dir,img)
            if i % 5 == 0:
                d = os.path.join(base_dir,'test',spec,img)
            else:
                d = os.path.join(base_dir, 'train', spec, img)
            shutil.copy(s,d)transform = transforms.Compose([transforms.Resize((96,96)),transforms.ToTensor(),
                              transforms.Normalize(mean=,std=)])
train_ds = torchvision.datasets.ImageFolder(train_dir,transform = transform)
test_ds = torchvision.datasets.ImageFolder(test_dir,transform = transform)
BATCH_SIZE = 16
train_dl = torch.utils.data.DataLoader(train_ds,batch_size =BATCH_SIZE,shuffle=True)
test_dl = torch.utils.data.DataLoader(test_ds,batch_size =BATCH_SIZE)class Net(nn.Module):
    def __init__(self):
      super(Net,self).__init__()
      self.conv1 = nn.Conv2d(3, 16, 3)
      self.conv2 = nn.Conv2d(16, 32, 3)
      self.conv3 = nn.Conv2d(32, 64, 3)
      self.pool = nn.MaxPool2d(2,2)
      self.fc1 = nn.Linear(64*10*10,1024)
      self.fc2 = nn.Linear(1024,4)
    def forward(self,x):
      x = F.relu(self.conv1(x))
      x = self.pool(x)
      x = F.relu(self.conv2(x))
      x = self.pool(x)
      x = F.relu(self.conv3(x))
      x = self.pool(x)
      x = x.view(-1,64*10*10)
      x = F.relu(self.fc1(x))
      x = self.fc2(x)
      return x
model = Net()
if torch.cuda.is_available():
    model.to('cuda')
loss_fn = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(),lr = 0.001)
def fit(epoch, model, train_dl, test_dl,loss_fn, optimizer):
    correct = 0
    total = 0
    running_loss = 0
    for x, y in train_dl:
      if torch.cuda.is_available():
            x, y = x.to('cuda'), y.to('cuda')
      y_pred = model(x)
      loss = loss_fn(y_pred, y)
      optimizer.zero_grad()
      loss.backward()
      optimizer.step()
      with torch.no_grad():
            y_pred = torch.argmax(y_pred, dim=1)
            correct += (y_pred == y).sum().item()
            total += y.size(0)
            running_loss += loss.item()

    epoch_loss = running_loss / len(train_dl)
    epoch_acc = correct / total

    test_correct = 0
    test_total = 0
    test_running_loss = 0

    with torch.no_grad():
      for x, y in test_dl:
            if torch.cuda.is_available():
                x, y = x.to('cuda'), y.to('cuda')
            y_pred = model(x)
            loss = loss_fn(y_pred, y)
            y_pred = torch.argmax(y_pred, dim=1)
            test_correct += (y_pred == y).sum().item()
            test_total += y.size(0)
            test_running_loss += loss.item()

    epoch_test_loss = test_running_loss / len(test_dl)
    epoch_test_acc = test_correct / test_total

    print('epoch: ', epoch,
          'loss: ', round(epoch_loss, 3),
          'accuracy:', round(epoch_acc, 3),
          'test_loss: ', round(epoch_test_loss, 3),
          'test_accuracy:', round(epoch_test_acc, 3)
          )
    return epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc
from torch.utils.data import DataLoaderepochs = 30
train_loss = []
train_acc = []
test_loss = []
test_acc = []
train_dl = torch.utils.data.DataLoader(train_ds,batch_size =BATCH_SIZE,shuffle=True)
test_dl = torch.utils.data.DataLoader(test_ds,batch_size =BATCH_SIZE)#test不用乱序
for epoch in range(epochs):
    train_loss, train_acc, test_loss, test_acc = fit(epoch, train_dl, test_dl, model, loss_fn, optimizer)
    train_loss.append(epoch_loss)
    train_acc.append(epoch_acc)
    test_loss.append(epoch_test_loss)
    test_acc.append(epoch_test_acc)
    template = ("epoch:{:2d},train_loss:{:.5f},train_acc:{:.1f},test_loss:{:.5f}, test_acc:{:.1f}")
    print(template.format(epoch, epoch_loss, epoch_acc * 100, epoch_test_loss, epoch_test_acc * 100))

print(train_loss, train_acc, test_loss, test_acc)
请大神指点,为什么运行后会出现下面的情况,该如何解决,谢谢!
TypeError                                 
Traceback (most recent call last)
Cell In, line 9
      7 test_dl = torch.utils.data.DataLoader(test_ds,batch_size =BATCH_SIZE)
      8 for epoch in range(epochs):
----> 9   train_loss, train_acc, test_loss, test_acc = fit(epoch, train_dl, test_dl, model, loss_fn, optimizer)
   10   train_loss.append(epoch_loss)
   11   train_acc.append(epoch_acc)

Cell In, line 8, in fit(epoch, model, train_dl, test_dl, loss_fn, optimizer)
      6 if torch.cuda.is_available():
      7   x, y = x.to('cuda'), y.to('cuda')
----> 8 y_pred = model(x)
      9 loss = loss_fn(y_pred, y)
   10 optimizer.zero_grad()

TypeError: 'DataLoader' object is not callable

isdkz 发表于 2023-5-20 16:44:21

这个错误提示是因为在调用fit函数时,参数顺序不正确,导致train_dl和test_dl的位置颠倒,应该将train_dl放在第三个位置,将test_dl放在第四个位置。修改后的代码如下:

train_loss, train_acc, test_loss, test_acc = fit(epoch, model, train_dl, test_dl, loss_fn, optimizer)


另外,还需要将train_loss 、 train_acc 、 test_loss和test_acc的初始值改为列表类型,因为在后面的代码中,这些变量会被用作列表,而原来的变量名与列表名相同,会导致变量名被覆盖,无法使用。修改后的代码如下:

train_loss_list = []
train_acc_list = []
test_loss_list = []
test_acc_list = []


然后在fit函数中,将这些变量的值改为列表类型即可。

sfqxx 发表于 2023-5-20 16:45:29

这个错误提示是因为你在 fit 函数的第一行中调用了 train_dl 和 test_dl,但其实这两个变量是 torch.utils.data.DataLoader 类型的对象,而不是函数,所以不能被调用。你需要把 train_dl 和 test_dl 改成 train_ds 和 test_ds,这样才能正确运行 fit 函数。修改后的代码如下:

epochs = 30
train_loss = []
train_acc = []
test_loss = []
test_acc = []
for epoch in range(epochs):
    train_loss_epoch, train_acc_epoch, test_loss_epoch, test_acc_epoch = fit(epoch, model, train_ds, test_ds, loss_fn, optimizer)
    train_loss.append(train_loss_epoch)
    train_acc.append(train_acc_epoch)
    test_loss.append(test_loss_epoch)
    test_acc.append(test_acc_epoch)
    template = ("epoch:{:2d},train_loss:{:.5f},train_acc:{:.1f},test_loss:{:.5f}, test_acc:{:.1f}")
    print(template.format(epoch, train_loss_epoch, train_acc_epoch * 100, test_loss_epoch, test_acc_epoch * 100))

print(train_loss, train_acc, test_loss, test_acc)
此外,由于你定义了一个 train_loss 的列表作为存储每个 epoch 训练损失的变量,所以在上面的代码中也需要把变量名 train_loss 改成 train_loss_epoch,以避免冲突。
页: [1]
查看完整版本: TypeError: 'DataLoader' object is not callable