python代码中 for 循环异常中断

python代码中 for 循环异常中断

if args.deploy == 'finetune':
            print("Start selecting the best lr...")
            best_acc = 0
            for lr in [0, 0.0001, 0.0005, 0.001]:
                model.lr = lr
                test_stats = evaluate(data_loader_val, model, criterion, device, seed=1234, ep=5) #test_stats:测试结果统计信息
                acc = test_stats['acc1']
                print(f"*lr = {lr}: acc1 = {acc}")
                if acc > best_acc:
                    best_acc = acc
                    best_lr = lr
            model.lr = best_lr
            print(f"### Selected lr = {best_lr}")

在这个代码中第一个学习率0 一切正常,到了第二个学习率 就直接总时间变成0了,没有进行任何操作,直接就回到了打印阶段

img

def evaluate(data_loaders, model, criterion, device, seed=None, ep=None):
    if isinstance(data_loaders, dict):
        test_stats_lst = {}
        test_stats_glb = {}

        for j, (source, data_loader) in enumerate(data_loaders.items()):
            print(f'* Evaluating {source}:')
            seed_j = seed + j if seed else None
            test_stats = _evaluate(data_loader, model, criterion, device, seed_j)
            test_stats_lst[source] = test_stats
            test_stats_glb[source] = test_stats['acc1']

        # apart from individual's acc1, accumulate metrics over all domains to compute mean
        for k in test_stats_lst[source].keys():
            test_stats_glb[k] = torch.tensor([test_stats[k] for test_stats in test_stats_lst.values()]).mean().item()

        return test_stats_glb
    elif isinstance(data_loaders, torch.utils.data.DataLoader): # when args.eval = True
        return _evaluate(data_loaders, model, criterion, device, seed, ep)
    else:
        warnings.warn(f'The structure of {data_loaders} is not recognizable.')
        return _evaluate(data_loaders, model, criterion, device, seed)


```python
def _evaluate(data_loader, model, criterion, device, seed=None, ep=None):
    metric_logger = utils.MetricLogger(delimiter="  ")
    metric_logger.add_meter('n_ways', utils.SmoothedValue(window_size=1, fmt='{value:d}'))
    metric_logger.add_meter('n_imgs', utils.SmoothedValue(window_size=1, fmt='{value:d}'))
    metric_logger.add_meter('acc1', utils.SmoothedValue(window_size=len(data_loader.dataset)))
    metric_logger.add_meter('acc5', utils.SmoothedValue(window_size=len(data_loader.dataset)))


    header = 'Test:'

    # switch to evaluation mode
    model.eval()

    if seed is not None:
        data_loader.generator.manual_seed(seed)

    for ii, batch in enumerate(metric_logger.log_every(data_loader, 10, header)):
        if ep is not None:
            if ii > ep:
                break

        batch = to_device(batch, device)
        SupportTensor, SupportLabel, x, y = batch

        # compute output
        with torch.cuda.amp.autocast():
            output = model(SupportTensor, SupportLabel, x) #logits

        output = output.view(x.shape[0] * x.shape[1], -1)
        y = y.view(-1)
        loss = criterion(output, y)
        acc1, acc5 = accuracy(output, y, topk=(1, 5))

        batch_size = x.shape[0]
        metric_logger.update(loss=loss.item())
        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)
        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)
        metric_logger.update(n_ways=SupportLabel.max()+1)
        metric_logger.update(n_imgs=SupportTensor.shape[1] + x.shape[1])

    # gather the stats from all processes
    metric_logger.synchronize_between_processes()
    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'
          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))

    ret_dict = {k: meter.global_avg for k, meter in metric_logger.meters.items()}
    ret_dict['acc_std'] = metric_logger.meters['acc1'].std

    return ret_dict

print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}' 这一行代码中访问了 loss 属性,但是 MetricLogger 类中并没有定义对应的属性。
你可以在 update 方法中记录 loss 的逻辑改为添加一个新的 meter,然后在 getattr 方法中增加对应的属性访问器。

使用 MetricLogger 的 add_scalar() 方法添加了一个名为 'train/loss' 的标量指标,然后在每个训练步骤中调用 logger.add_scalar() 方法来记录损失。这样可以确保 MetricLogger 对象具有 loss 属性,并且可以在 TensorBoard 中查看损失值。小小示例:

from torch.utils.tensorboard import SummaryWriter  
from torch.utils.data import DataLoader  
from torch.optim import Adam  
from torch.nn import CrossEntropyLoss  
from torchvision.datasets import ImageFolder  
from torchvision.transforms import ToTensor, Normalize  
from torchvision.models import ResNet18  
  
# 定义数据集和数据加载器  
train_dataset = ImageFolder(root='./data/train', transform=transforms.Compose([ToTensor(), Normalize]))  
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)  
  
# 定义模型、损失函数和优化器  
model = ResNet18()  
criterion = CrossEntropyLoss()  
optimizer = Adam(model.parameters(), lr=0.001)  
  
# 初始化 TensorBoard 写入器和 MetricLogger  
writer = SummaryWriter()  
logger = MetricLogger(writer)  
  
# 在训练循环中使用 MetricLogger 记录损失  
for epoch in range(num_epochs):  
    for i, (inputs, targets) in enumerate(train_loader):  
        optimizer.zero_grad()  # 清除梯度  
        outputs = model(inputs)  # 前向传播计算输出  
        loss = criterion(outputs, targets)  # 计算损失  
        loss.backward()  # 反向传播计算梯度  
        optimizer.step()  # 更新权重参数  
        logger.add_scalar('train/loss', loss.item(), epoch * len(train_loader) + i)  # 使用 MetricLogger 记录损失

讯飞星火
要解决这个问题,您需要确保在MetricLogger类中定义了loss属性。您可以通过以下方式添加loss属性:

class MetricLogger:
    def __init__(self):
        self.loss = 0

    # 其他方法和属性

这样,当您尝试访问MetricLogger对象的loss属性时,就不会出现AttributeError了。


在datafile_1.read()和datafile_1.read()

with open("keywords_1","r+") as datafile_1-您键入的文件名没有文件类型,因此函数将停止,因为没有可读取的文件或目录。

尽量不要使用global变量,它只是不安全。

仅此错误而言,显示在evaluate()函数中出现了除零异常(ZeroDivisionError)。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7479761
  • 除此之外, 这篇博客: python多个虚拟环境需要共用一个包,怎么避免重复安装中的 虚拟环境的原理 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    一个虚拟环境就是一个独立的python,除了自带包使用了主环境外,第三方包(site-packages),脚本(scripts),甚至包括python解释器(python.exe)都是独立的。

    当启动虚拟环境时(通常会使用启动脚本activate.bat),系统变量PATH中与python有关的环境变量会临时切换到虚拟环境的文件路径,直到退出虚拟环境,环境变量恢复为主环境的文件路径。

    总结来说,虚拟环境,不如说就是同时安装了多个python,然后通过环境变量控制当前使用哪个python

    有了虚拟环境后,我们就可以依据用途,分别在不同的虚拟环境中安装不同的包,这样就能缓解依赖地狱问题。

  • 您还可以看一下 CSDN就业班老师的Python全栈工程师特训班第十四期-直播回放课程中的 Python全栈工程师特训班第十四期-第六周-3小节, 巩固相关知识点

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

img


错误已经明显提示你了,是一个把0作为除数的错误。应该是在你的evaluate或_evaluate函数中某一步计算出错了或者使初始化错了变量,导致某个变量的值为0了。建议调试下代码,看下每个变量执行过程中值,是否有为0的现象。

在你提供的代码中,有一个for循环用于遍历学习率列表[0, 0.0001, 0.0005, 0.001]。你的问题是在第二个学习率(0.0001)时循环异常中断,没有进行任何操作,直接回到了打印阶段。

问题可能出现在_evaluate函数内部。可以尝试在该函数内添加一些调试语句,查看是否出现了错误或异常

在65行打断点调试一下,看看相关变量值是否正常

回答部分参考、引用ChatGpt以便为您提供更准确的答案:

根据您提供的代码和错误信息,问题出现在以下代码段:

print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'
          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))

在这里,您尝试使用metric_logger.loss来访问loss属性,但是MetricLogger类本身并没有定义loss属性,因此引发了AttributeError异常。

要解决这个问题,您可以在MetricLogger类的__init__方法中添加一个对loss属性的初始化,类似于其他已定义的属性:

self.meters['loss'] = SmoothedValue()

这样,在调用update方法更新loss值时,MetricLogger类会正确创建并更新loss属性。

另外,请确保在其他地方使用metric_logger.update(loss=loss.item())来更新loss值,以便正确计算平均值和其他统计信息。

修复后的代码应如下所示:

class MetricLogger(object):
    def __init__(self, delimiter="\t"):
        self.meters = defaultdict(SmoothedValue)
        self.delimiter = delimiter
        self.meters['loss'] = SmoothedValue()

    # 其他方法和代码保持不变

通过添加对loss属性的初始化,您应该能够成功访问metric_logger.loss属性,并解决该错误。

如果您有进一步的问题,请随时提问。

答案参考ChapGPT Plus . 希望对你有帮助根据你提供的代码,错误出现在以下这行代码:

print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'
      .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))

错误信息指出 'MetricLogger' object has no attribute 'loss',即在 metric_logger 对象中找不到名为 'loss' 的属性。

从你的代码中可以看出,metric_logger 对象定义在 MetricLogger 类中,该类没有定义名为 'loss' 的属性。在 _evaluate 函数中,你使用 metric_logger.loss 来获取 'loss' 属性,但实际上该属性不存在,因此导致了错误。

要解决这个问题,你需要检查 _evaluate 函数中的逻辑并确定你想要输出的指标是否正确。如果你想输出损失值,你需要在 MetricLogger 类的 __init__ 方法中添加一个 'loss' 的 meter,类似于以下示例:

self.meters['loss'] = SmoothedValue()

然后在 _evaluate 函数中的适当位置使用 metric_logger.update(loss=loss.item()) 更新 'loss' 的值。

另外,请确保你的 SmoothedValue 类和其他辅助函数(如 accuracyto_device)的定义在代码中存在,以避免其他潜在的错误。

希望这些说明能帮助你解决问题。如果还有其他疑问,请随时提问。