You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch训练数据加载器遍历时报TypeError错误排查

问题:训练CNN时触发TypeError

我尝试在.npy格式的图像数据集上训练CNN模型,但训练循环中出现了TypeError: 'module' object is not callable错误,错误定位在for data, target in tqdm(trainloader):这一行。我尝试编写自定义Dataset类MyDataset,但问题仍未解决。

导入模块

import torch
from torchvision import datasets, transforms
import torch.nn as nn
import torch.optim as optim
import tqdm

CNN模型定义

class CNN(nn.Module):
    def __init__(self) -> None:
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)

        self.fc1 = nn.Linear(64*64*64, 128)
        self.fc2 = nn.Linear(128, 3)

        self.relu = nn.ReLU()

        self.pool = nn.MaxPool2d(2, 2)
        self.dropout = nn.Dropout(p=0.2)
    
    def forward(self, image: torch.Tensor) -> torch.Tensor:
        image = self.pool(self.relu(self.conv1(image)))
        image = self.pool(self.relu(self.conv2(image)))
        image = self.pool(self.relu(self.conv3(image)))
        image = image.view(-1, 64*64*64)
        image = self.dropout(self.relu(self.fc1(image)))
        image = self.fc2(image)
        return image

超参数配置

train_path = 'dataset/train'
val_path = 'dataset/val'
num_epochs = 11
num_classes = 3
batch_size = 64
learning_rate = 0.002
train_test_ratio = 0.9

device = torch.device('mps' if torch.backends.mps.is_available() else 'cpu')

训练数据加载逻辑

import numpy as np

def npy_loader(path):
    sample = torch.from_numpy(np.load(path))
    return sample

transform = transforms.Compose([transforms.ToPILImage(), transforms.ToTensor()])
dataset = datasets.DatasetFolder(
    root=train_path,
    loader=npy_loader,
    extensions='.npy',
    transform=transform
)

trainloader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True)

训练循环代码

model = CNN()
model.to(device)
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
criterion = nn.CrossEntropyLoss()
model.train()
for epoch in range(num_epochs):
    train_loss = 0.0
    for data, target in tqdm(trainloader):
        data = data.to(device)
        target = target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()
        train_loss += loss.item() * data.size(0)
    train_loss = train_loss/len(trainloader.dataset)
    print(f'Epoch: {epoch+1} \tTraining Loss: {train_loss:.6f}')

自定义Dataset尝试(未解决问题)

from torch.utils.data import Dataset

class MyDataset(Dataset):
    def __init__(self, np_file_paths, transform=None):
        self.files = np_file_paths
        self.transform = transform
    
    def __getitem__(self, index):
        x = np.load(self.files[index])
        x = torch.from_numpy(x).float()
        if self.transform is not None:
            image = self.transform(image)
        return x
    
    def __len__(self):
        return len(self.files)

错误信息

TypeError: 'module' object is not callable

错误触发于训练循环的for data, target in tqdm(trainloader):行。


问题解决方法

1. 修复tqdm的调用方式

错误核心原因是tqdm是一个模块,直接调用tqdm(trainloader)会导致“模块不可调用”的错误。有两种修正方式:

  • 方式一:导入tqdm的核心函数

    # 替换原导入语句中的import tqdm
    from tqdm import tqdm
    

    之后保持训练循环中的for data, target in tqdm(trainloader):不变即可。

  • 方式二:直接调用模块内的tqdm对象
    修改训练循环中的迭代行:

    for data, target in tqdm.tqdm(trainloader):
    

2. 自定义Dataset的潜在bug修复(可选)

你编写的MyDataset存在变量未定义的问题,需修正__getitem__方法:

def __getitem__(self, index):
    x = np.load(self.files[index])
    x = torch.from_numpy(x).float()
    if self.transform is not None:
        x = self.transform(x)  # 原代码中误用了未定义的image变量
    return x

使用该自定义Dataset时,还需自行收集所有.npy文件路径:

import glob
train_files = glob.glob(f'{train_path}/**/*.npy', recursive=True)
dataset = MyDataset(train_files, transform=transform)

内容的提问来源于stack exchange,提问作者dimicorn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 11:45:06