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
相关产品推荐
相关产品推荐

