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

PyTorch Clothing-1M基线模型运行时已导入dataloader仍触发NameError错误的技术问询

解决Clothing-1M基线复现中的NameError: 'dataloader' is not defined问题

我一眼就看出问题出在你代码里的导入语句位置上,咱们来一步步拆解:

问题根源

你的import dataloader和import models是放在if __name__ == '__main__':代码块里面的,但创建loader的代码却在这个块的外面。Python脚本执行时,会先从上到下运行所有全局作用域的代码,再执行if __name__ == '__main__':块里的内容。也就是说,当脚本运行到loader = dataloader.clothing_dataloader(...)这行时,dataloader模块还根本没被导入,自然就触发了NameError。

你调试时看到变量存在,应该是调试器已经执行到if __name__ == '__main__':块内部、完成导入后的状态,但实际脚本的执行顺序是先跑全局代码,这时候导入还没发生。

两种修复方案

方案一:把导入移到全局作用域

直接把import dataloader和import models移到脚本最顶部的全局导入区,这样整个脚本都能访问到这两个模块:

from __future__ import print_function
import sys
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torch.backends.cudnn as cudnn
import torchvision
import torchvision.transforms as transforms
import os
import sys
import time
import argparse
import datetime
from torch.autograd import Variable

# 移到全局作用域的导入
import dataloader as dataloader
import models as models

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='PyTorch Clothing-1M Training')
    parser.add_argument('--lr', default=0.0008, type=float, help='learning_rate')
    parser.add_argument('--start_epoch', default=2, type=int)
    parser.add_argument('--num_epochs', default=3, type=int)
    parser.add_argument('--batch_size', default=32, type=int)
    parser.add_argument('--optim_type', default='SGD')
    parser.add_argument('--seed', default=7)
    parser.add_argument('--gpuid', default=1, type=int)
    parser.add_argument('--id', default='cross_entropy')
    args = parser.parse_args()

    best_acc = 0

    # Model
    net = models.resnet50(pretrained=True)
    net.fc = nn.Linear(2048,14)
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(net.parameters(), lr=args.lr, momentum=0.9, weight_decay=1e-3)

    loader = dataloader.clothing_dataloader(batch_size=args.batch_size,num_workers=5,shuffle=True)
    train_loader,val_loader = loader.run()

    # Training
    def train(epoch):
        net.train()
        train_loss = 0
        correct = 0
        total = 0
        learning_rate = args.lr
        if epoch > args.start_epoch:
            learning_rate=learning_rate/10
        for param_group in optimizer.param_groups:
            param_group['lr'] = learning_rate
        print('\n=> %s Training Epoch #%d, LR=%.4f' %(args.id,epoch, learning_rate))
        for batch_idx, (inputs, targets) in enumerate(train_loader):
            optimizer.zero_grad()
            inputs, targets = Variable(inputs), Variable(targets)
            outputs = net(inputs)  # Forward Propagation
            loss = criterion(outputs, targets)  # Loss
            loss.backward()  # Backward Propagation
            optimizer.step()  # Optimizer update

            train_loss += loss.data[0]
            _, predicted = torch.max(outputs.data, 1)
            total += targets.size(0)
            correct += predicted.eq(targets.data).cpu().sum()

    for epoch in range(1, 1+args.num_epochs):
        train(epoch)

方案二:把所有执行代码放进if __name__ == '__main__':块

如果想保持导入在块内,那就要把所有依赖这些模块的代码也移到块里,确保导入先发生:

from __future__ import print_function
import sys
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torch.backends.cudnn as cudnn
import torchvision
import torchvision.transforms as transforms
import os
import sys
import time
import argparse
import datetime
from torch.autograd import Variable

# 训练函数可以放在外面,因为它不直接依赖导入模块(依赖的变量会在块内定义)
def train(epoch, net, optimizer, criterion, train_loader, args):
    net.train()
    train_loss = 0
    correct = 0
    total = 0
    learning_rate = args.lr
    if epoch > args.start_epoch:
        learning_rate=learning_rate/10
    for param_group in optimizer.param_groups:
        param_group['lr'] = learning_rate
    print('\n=> %s Training Epoch #%d, LR=%.4f' %(args.id,epoch, learning_rate))
    for batch_idx, (inputs, targets) in enumerate(train_loader):
        optimizer.zero_grad()
        inputs, targets = Variable(inputs), Variable(targets)
        outputs = net(inputs)  # Forward Propagation
        loss = criterion(outputs, targets)  # Loss
        loss.backward()  # Backward Propagation
        optimizer.step()  # Optimizer update

        train_loss += loss.data[0]
        _, predicted = torch.max(outputs.data, 1)
        total += targets.size(0)
        correct += predicted.eq(targets.data).cpu().sum()

if __name__ == '__main__':
    # 先导入模块
    import dataloader as dataloader
    import models as models

    parser = argparse.ArgumentParser(description='PyTorch Clothing-1M Training')
    parser.add_argument('--lr', default=0.0008, type=float, help='learning_rate')
    parser.add_argument('--start_epoch', default=2, type=int)
    parser.add_argument('--num_epochs', default=3, type=int)
    parser.add_argument('--batch_size', default=32, type=int)
    parser.add_argument('--optim_type', default='SGD')
    parser.add_argument('--seed', default=7)
    parser.add_argument('--gpuid', default=1, type=int)
    parser.add_argument('--id', default='cross_entropy')
    args = parser.parse_args()

    best_acc = 0

    # Model
    net = models.resnet50(pretrained=True)
    net.fc = nn.Linear(2048,14)
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(net.parameters(), lr=args.lr, momentum=0.9, weight_decay=1e-3)

    # 现在导入已经完成,可以创建loader了
    loader = dataloader.clothing_dataloader(batch_size=args.batch_size,num_workers=5,shuffle=True)
    train_loader,val_loader = loader.run()

    for epoch in range(1, 1+args.num_epochs):
        train(epoch, net, optimizer, criterion, train_loader, args)

我更推荐方案二,因为它能避免全局变量污染,是Python脚本的最佳实践之一。

内容的提问来源于stack exchange,提问作者ZENG LINLIN _

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:12:29