鱼C论坛

 找回密码
 立即注册
查看: 1178|回复: 2

[已解决]TypeError: 'DataLoader' object is not callable

[复制链接]
发表于 2023-5-20 16:43:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
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=[0.5,0.5,0.5],std=[0.5,0.5,0.5])])
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[28], 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[26], 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
最佳答案
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  函数中,将这些变量的值改为列表类型即可。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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  函数中,将这些变量的值改为列表类型即可。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 2

使用道具 举报

发表于 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,以避免冲突。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-23 03:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表