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

PyTorch训练孪生网络时loss.backward()报TypeError错误求助

PyTorch孪生网络训练中loss.backward()触发TypeError问题

错误信息

Traceback (most recent call last):  
  File "/home/xxx/PyProject/image_similarity/Grad_CAM_Siamese/01.Train_Siamese_model.py", line 250, in <module>  
    loss.backward()  
  File "/home/xxx/anaconda3/envs/pytorch_siamese/lib/python3.8/site-packages/torch/_tensor.py", line 487, in backward  
    torch.autograd.backward(  
  File "/home/xxx/anaconda3/envs/pytorch_siamese/lib/python3.8/site-packages/torch/autograd/__init__.py", line 200, in backward  
    Variable._execution_engine.run_backward(  # Calls into the C++ engine to run the backward pass  
TypeError: 'NoneType' object is not callable

相关代码片段

训练循环代码(错误发生行)

for epoch in range(params['hyperparameters']['epochs']):
    torch.cuda.empty_cache()
    model.train()
    loop = tqdm(train_dl, leave=True, ncols=120)
    metrics = {'losses': []}
    for step, (img1, img2, img3) in enumerate(loop):
        img1, img2, img3 = img1.to(device), img2.to(device), img3.to(device)
        optimizer.zero_grad()
        loss = model(img1, img2, img3)

        # 此处尝试获取loss相关信息

        loss.backward()  # Line250
        torch.nn.utils.clip_grad_norm_(parameters=model.parameters(), max_norm=params['hyperparameters']['max_norm'])
        optimizer.step()

loss相关信息(backward调用前)

tensor(1.0018, device='cuda:3', grad_fn=<MeanBackward0>)  # loss值
Loss type: <class 'torch.Tensor'>  # loss类型
torch.float32  # loss数据类型

loss计算逻辑

模型内定义损失函数并计算:

self.loss_fnc = TripletLoss(margin=1.0)

loss = self.loss_fnc(embeddings_anchor, embeddings_positive, embeddings_negative)  

TripletLoss类实现

class TripletLoss(torch.nn.Module):
    def __init__(self, margin=1.0):
        super(TripletLoss, self).__init__()
        self.margin = margin

    def forward(self, anchor, positive, negative):
        distance_positive = F.pairwise_distance(anchor, positive)
        distance_negative = F.pairwise_distance(anchor, negative)
        losses = torch.mean(F.relu(distance_positive - distance_negative + self.margin))
        return losses

环境信息

  • Python版本:3.8.17
  • PyTorch版本:pytorch2.0.0,torchvision0.15.0,torchaudio==2.0.0,pytorch-cuda=11.7
  • CUDA版本:11.7(nvcc -V验证)
  • 训练设备:GPU

问题排查与解决方法

针对这个TypeError: 'NoneType' object is not callable错误,结合你的代码和环境,可按以下方向排查:

1. 检查模型中的inplace操作

inplace操作会直接修改张量内存,破坏反向传播的计算图。排查模型所有层:

  • 若使用了F.relu(inplace=True)、torch.nn.ReLU(inplace=True)或其他带inplace=True的操作,改为inplace=False。
  • 检查是否有手动修改张量的操作(比如x += y这种inplace赋值),替换为x = x + y。

2. 验证模型参数与设备一致性

确认模型所有参数都已正确移动到GPU:

  • 在初始化模型后,执行model = model.to(device),确保所有层的参数都在cuda:3上(和loss的设备一致)。
  • 检查数据加载时,是否所有输入张量都正确转移到指定设备。

3. 检查PyTorch版本兼容性

PyTorch 2.0.0存在部分已知的反向传播bug,可尝试:

  • 降级到PyTorch 1.13.1(兼容CUDA11.7):
    pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu117
    
  • 或升级到PyTorch 2.0.1及以上版本,修复已知问题。

4. 确认优化器绑定的参数正确

检查优化器初始化代码,确保传入的是model.parameters(),没有传入无关参数或未注册的张量:

optimizer = torch.optim.Adam(model.parameters(), lr=params['hyperparameters']['lr'])

5. 排查计算图是否被意外中断

虽然loss有grad_fn,但仍需确认模型前向传播中没有意外断开计算图:

  • 检查是否在模型前向传播中使用了detach()或torch.no_grad()(除非是刻意冻结部分层)。
  • 确认TripletLoss中的所有张量操作都在计算图内,没有手动脱离梯度追踪。

6. 重置PyTorch的execution_engine

若上述方法无效,可尝试在代码开头添加以下代码,重置execution_engine:

import torch
torch._C._jit_set_profiling_executor(False)
torch._C._jit_set_profiling_mode(False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:05:18