【调试】错误 RuntimeError: Legacy autograd function with non-static forward method is deprecated.

一、错误

  运行pytorch版SSD目标检测网络:https://github.com/amdegroot/ssd.pytorch,使用训练好的模型执行目标检测时(执行demo.py)。出现错误:
RuntimeError: Legacy autograd function with non-static forward method is deprecated. Please use new-style autograd function with static forward method.

二、分析错误原因

在这里插入图片描述

  (1)demo.py中出错语句为y = net(xx)
  (2)demo.py中出现y = net(xx)错误的原因是ssd.py中下列语句——(使用Detect类创建对象self.detect执行检测)

在这里插入图片描述

  (3)查看Detect类,既detection.py文件。因为Detect类继承自Function类,在pytorch1.3及以后的版本需要规定forward方法为静态方法,所以在pytorch1.3以上的版本执行出错。

在这里插入图片描述

三、解决方法

  (1)网上的方法:说要将pytorch的版本降低为1.2及以下的版本。但是我的cuda是10.2,目前不支持1.2及其以下的GPU版的pytorch,为了运行这个代码还要重装cuda、pytorch太麻烦了!!!!!!

  (2)自己的方法:修改代码

在这里插入图片描述

        '''检测模式下的网络输出'''
        if self.phase == "test":
            # output = self.detect(loc.view(loc.size(0), -1, 4), # 将网络的位置预测表示为(-1,4)形式torch.Size([1, 8732, 4])
            #     self.softmax(conf.view(conf.size(0), -1,self.num_classes)), # 将网络的置信度预测表示为(-1,5)形式torch.Size([1, 8732, 5])
            #     self.priors.type(type(x.data))                  # 先验anchor box,格式(x,y,w,h)
            # )
            ###########################################################修改代码################################################################
            #Detect类不支持静态方法的前向传播,因此使用类直接调用方法
            output=self.detect.forward(loc.view(loc.size(0), -1, 4),
                                       self.softmax(conf.view(conf.size(0), -1,self.num_classes)),
                                       self.priors.type(type(x.data)) )
            ###########################################################修改代码################################################################

  box_utils.py文件中的nms函数还需要作相应的修改,否则出错RuntimeError: index_select(): functions with out=… arguments don’t support automatic differentiation, but one of the arguments requires grad.错误

'''nms()函数:非极大值抑制函数。对每一类别分别执行该函数'''
def nms(boxes, scores, overlap=0.5, top_k=200):##参数:边界框精确位置,边界框类别的分数、nms阈值、前200个边界框
    '''(1)构建keep张量:初始值为0,形状与预测框的数量相同(预测框的数量为该类,类别置信度大于阈值的预测边界框的数量)'''
    keep = scores.new(scores.size(0)).zero_().long()

    if boxes.numel() == 0:
        return keep

    '''(2)计算预测边界框的面积'''
    x1 = boxes[:, 0]
    y1 = boxes[:, 1]
    x2 = boxes[:, 2]
    y2 = boxes[:, 3]
    area = torch.mul(x2 - x1, y2 - y1)

    '''(3)获取 类别置信度分数最高的top_k个 预测边界框的索引'''
    v, idx = scores.sort(0)  #对类别置信度分数升序排序,返回 按照类别置信度分数排序后的   预测边界框的索引
    # I = I[v >= 0.01]
    '''类别置信度分数最高的前top_k个预测框的索引:idx '''
    idx = idx[-top_k:]  # indices of the top-k largest vals
    xx1 = boxes.new()
    yy1 = boxes.new()
    xx2 = boxes.new()
    yy2 = boxes.new()
    w = boxes.new()
    h = boxes.new()
    '''(4)将nms后的预测边界框的索引,存入keep'''
    count = 0
    while idx.numel() > 0:
        ''''#1.类别置信度分数最高的预测边界框————————索引逐一写入keep'''
        i = idx[-1]  # index of current largest val
        # keep.append(i)
        keep[count] = i
        count += 1

        if idx.size(0) == 1:
            break
        '''#2.剩余预测边界框的索引'''
        idx = idx[:-1]  # remove kept element from view
        '''#3.计算剩余预测边界框与,分数最高的边界框之间的iou值'''
        #####################################添加代码##########################################
        #否者出错RuntimeError: index_select(): functions with out=... arguments don't support automatic differentiation, but one of the arguments requires grad.
        idx= torch.autograd.Variable(idx, requires_grad=False)
        idx = idx.data
        x1 = torch.autograd.Variable(x1, requires_grad=False)
        x1 = x1.data
        y1 = torch.autograd.Variable(y1, requires_grad=False)
        y1 = y1.data
        x2 = torch.autograd.Variable(x2, requires_grad=False)
        x2 = x2.data
        y2 = torch.autograd.Variable(y2, requires_grad=False)
        y2 = y2.data
        ######################################添加代码#################################################
        torch.index_select(x1, 0, idx, out=xx1)
        torch.index_select(y1, 0, idx, out=yy1)
        torch.index_select(x2, 0, idx, out=xx2)
        torch.index_select(y2, 0, idx, out=yy2)
        # store element-wise max with next highest score
        xx1 = torch.clamp(xx1, min=x1[i])
        yy1 = torch.clamp(yy1, min=y1[i])
        xx2 = torch.clamp(xx2, max=x2[i])
        yy2 = torch.clamp(yy2, max=y2[i])
        w.resize_as_(xx2)
        h.resize_as_(yy2)
        w = xx2 - xx1
        h = yy2 - yy1
        # check sizes of xx1 and xx2.. after each iteration
        w = torch.clamp(w, min=0.0)
        h = torch.clamp(h, min=0.0)
        inter = w*h
        # IoU = i / (area(a) + area(b) - i)
        #####################################添加代码##########################################
        #否者出错RuntimeError: index_select(): functions with out=... arguments don't support automatic differentiation, but one of the arguments requires grad.
        area = torch.autograd.Variable(area, requires_grad=False)
        area = area.data
        idx= torch.autograd.Variable(idx, requires_grad=False)
        idx = idx.data
        ######################################添加代码#################################################
        rem_areas = torch.index_select(area, 0, idx)  # load remaining areas)
        union = (rem_areas - inter) + area[i]
        IoU = inter/union  # store result in iou
        # keep only elements with an IoU <= overlap
        '''4.保留iou值小于nms阈值的预测边界框的索引'''
        idx = idx[IoU.le(overlap)]#保留交并比小于阈值的预测边界框的id
    return keep, count

四、运行结果

在这里插入图片描述

版权声明:本文为CSDN博主「不断进步的咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36926037/article/details/108419899

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

yolov5训练数据集划分

yolov5训练数据集划分 按照默认8:1:1划分训练集,测试集,验证集。 txt文件出现在imageset文件夹。 import os import randomtrainval_pe