Legacy autograd function with non-static forward method is deprecated and will be removed in 1.3

Hi,

Do you know why a have this warning, and what I need to modify so that it doesn’t appear:

/pytorch/torch/csrc/autograd/python_function.cpp:622: UserWarning: Legacy autograd function with non-static forward method is deprecated and will be removed in 1.3. Please use new-style autograd function with static forward method. (Example: https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function)

The code is

class BinActive(torch.autograd.Function):
    '''
    Binarize the input activations and calculate the mean across channel dimension.
    '''
    #@staticmethod
    def forward(self, input):
        self.save_for_backward(input)
        size = input.size()
        mean = torch.mean(input.abs(), 1, keepdim=True)
        input = input.sign()
        return input, mean
    #@staticmethod
    def backward(self, grad_output, grad_output_mean):
        input, = self.saved_tensors
        grad_input = grad_output.clone()
        #grad_input[input.ge(1)] = 0
        #grad_input[input.le(-1)] = 0
        return grad_input

Thanks for your help,

Remove the comments before @staticmethod (#) and the warning should not be raised anymore.

Thanks for your reply, I have removed the comments before @staticmethod (#) :

class BinActive(torch.autograd.Function):
    '''
    Binarize the input activations and calculate the mean across channel dimension.
    '''   
    @staticmethod
    def forward(self, input):
        self.save_for_backward(input)
        size = input.size()
        mean = torch.mean(input.abs(), 1, keepdim=True)
        input = input.sign()
        return input, mean
    @staticmethod
    def backward(self, grad_output, grad_output_mean):
        input, = self.saved_tensors
        grad_input = grad_output.clone()
        #grad_input[input.ge(1)] = 0
        #grad_input[input.le(-1)] = 0
        return grad_input

however, when I try to train the network I have this problem:

---> 21         x, mean = BinActive()(x)
     22 
     23         x = self.conv(x)

TypeError: forward() missing 1 required positional argument: 'input'

Try to use:

x, mean = BinActive.apply(x)
1 Like

Thanks, It worked :smiley:

1 Like

hey i am getting error: Legacy autograd function with non-static forward method is deprecated. Please use new-style autograd function with static forward method. (Example: https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function)
how to solve it?

import torch

from torch.autograd import Variable

import cv2

from data import BaseTransform, VOC_CLASSES as labelmap

from ssd import build_ssd

import imageio

Defining a function that will do the detections

def detect(frame, net, transform): # We define a detect function that will take as inputs, a frame, a ssd neural network, and a transformation to be applied on the images, and that will return the frame with the detector rectangle.

height, width = frame.shape[:2] # We get the height and the width of the frame.

frame_t = transform(frame)[0] # We apply the transformation to our frame.

x = torch.from_numpy(frame_t).permute(2, 0, 1) # We convert the frame into a torch tensor.

x = Variable(x.unsqueeze(0)) # We add a fake dimension corresponding to the batch.

y = net(x) # We feed the neural network ssd with the image and we get the output y.

detections = y.data # We create the detections tensor contained in the output y.

scale = torch.Tensor([width, height, width, height]) # We create a tensor object of dimensions [width, height, width, height].

for i in range(detections.size(1)): # For every class:

    j = 0 # We initialize the loop variable j that will correspond to the occurrences of the class.

    while detections[0, i, j, 0] >= 0.6: # We take into account all the occurrences j of the class i that have a matching score larger than 0.6.

        pt = (detections[0, i, j, 1:] * scale).numpy() # We get the coordinates of the points at the upper left and the lower right of the detector rectangle.

        cv2.rectangle(frame, (int(pt[0]), int(pt[1])), (int(pt[2]), int(pt[3])), (255, 0, 0), 2) # We draw a rectangle around the detected object.

        cv2.putText(frame, labelmap[i - 1], (int(pt[0]), int(pt[1])), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 2, cv2.LINE_AA) # We put the label of the class right above the rectangle.

        j += 1 # We increment j to get to the next occurrence.

return frame # We return the original frame with the detector rectangle and the label around the detected object.

Creating the SSD neural network

net = build_ssd(‘test’) # We create an object that is our neural network ssd.

net.load_state_dict(torch.load(‘ssd300_mAP_77.43_v2.pth’, map_location = lambda storage, loc: storage)) # We get the weights of the neural network from another one that is pretrained (ssd300_mAP_77.43_v2.pth).

Creating the transformation

transform = BaseTransform(net.size, (104/256.0, 117/256.0, 123/256.0)) # We create an object of the BaseTransform class, a class that will do the required transformations so that the image can be the input of the neural network.

Doing some Object Detection on a video

reader = imageio.get_reader(‘funny_dog.mp4’) # We open the video.

fps = reader.get_meta_data()[‘fps’] # We get the fps frequence (frames per second).

writer = imageio.get_writer(‘output.mp4’, fps = fps) # We create an output video with this same fps frequence.

for i, frame in enumerate(reader): # We iterate on the frames of the output video:

frame = detect(frame, net.eval(), transform) # We call our detect function (defined above) to detect the object on the frame.

writer.append_data(frame) # We add the next frame in the output video.

print(i) # We print the number of the processed frame.

writer.close() # We close the process that handles the creation of the output video.

getting this error: Legacy autograd function with non-static forward method is deprecated. Please use new-style autograd function with static forward method. (Example: https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function)

1 Like

Somewhere in your code you are defining a torch.autograd.Function in the deprecated format and you would have to use the new-style autograd function with the static methods. The link in the error message gives you an example.

Hi Sir,

Same Problem i am also facing as Muhammad_Hasan. here is the below code. I include @Staticmethod in above of forward funtion but still i am getting forward() missing 1 required positional argument: ‘x’.

CODE:

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
from layers import *
from data import v2
import os

class SSD(nn.Module,x):
“”"Single Shot Multibox Architecture
The network is composed of a base VGG network followed by the
added multibox conv layers. Each multibox layer branches into
1) conv2d for class conf scores
2) conv2d for localization predictions
3) associated priorbox layer to produce default bounding
boxes specific to the layer’s feature map size.
See: https://arxiv.org/pdf/1512.02325.pdf for more details.

Args:
    phase: (string) Can be "test" or "train"
    base: VGG16 layers for input, size of either 300 or 500
    extras: extra layers that feed to multibox loc and conf layers
    head: "multibox head" consists of loc and conf conv layers
"""

def __init__(self, phase, base, extras, head, num_classes):
    super(SSD, self).__init__()
    self.phase = phase
    self.num_classes = num_classes
    # TODO: implement __call__ in PriorBox
    self.priorbox = PriorBox(v2)
    self.priors = Variable(self.priorbox.forward(), volatile=True)
    self.size = 300

    # SSD network
    self.vgg = nn.ModuleList(base)
    # Layer learns to scale the l2 normalized features from conv4_3
    self.L2Norm = L2Norm(512, 20)
    self.extras = nn.ModuleList(extras)

    self.loc = nn.ModuleList(head[0])
    self.conf = nn.ModuleList(head[1])
   

    if phase == 'test':
        self.softmax = nn.Softmax()
        self.detect = Detect(num_classes, 0, 200, 0.01, 0.45)
    
    
@staticmethod    
def forward(self, x):
    """Applies network layers and ops on input image(s) x.

    Args:
        x: input image or batch of images. Shape: [batch,3*batch,300,300].

    Return:
        Depending on phase:
        test:
            Variable(tensor) of output class label predictions,
            confidence score, and corresponding location predictions for
            each object detected. Shape: [batch,topk,7]

        train:
            list of concat outputs from:
                1: confidence layers, Shape: [batch*num_priors,num_classes]
                2: localization layers, Shape: [batch,num_priors*4]
                3: priorbox layers, Shape: [2,num_priors*4]
    """
    sources = list()
    loc = list()
    conf = list()

    # apply vgg up to conv4_3 relu
    for k in range(23):
        x = self.vgg[k](x)

    s = self.L2Norm(x)
    sources.append(s)

    # apply vgg up to fc7
    for k in range(23, len(self.vgg)):
        x = self.vgg[k](x)
    sources.append(x)

    # apply extra layers and cache source layer outputs
    for k, v in enumerate(self.extras):
        x = F.relu(v(x), inplace=True)
        if k % 2 == 1:
            sources.append(x)

    # apply multibox head to source layers
    for (x, l, c) in zip(sources, self.loc, self.conf):
        loc.append(l(x).permute(0, 2, 3, 1).contiguous())
        conf.append(c(x).permute(0, 2, 3, 1).contiguous())

    loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1)
    conf = torch.cat([o.view(o.size(0), -1) for o in conf], 1)
    if self.phase == "test":
        output = self.detect(
            loc.view(loc.size(0), -1, 4),                   # loc preds
            self.softmax(conf.view(-1, self.num_classes)),  # conf preds
            self.priors.type(type(x.data))                  # default boxes
        )
  
    else:
        output = (
            loc.view(loc.size(0), -1, 4),
            conf.view(conf.size(0), -1, self.num_classes),
            self.priors
        )
        
    
    return output


def load_weights(self, base_file):
    other, ext = os.path.splitext(base_file)
    if ext == '.pkl' or '.pth':
        print('Loading weights into state dict...')
        self.load_state_dict(torch.load(base_file, map_location=lambda storage, loc: storage))
        print('Finished!')
    else:
        print('Sorry only .pth and .pkl files supported.')

This function is derived from torchvision VGG make_layers()

https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py

def vgg(cfg, i, batch_norm=False):
layers = []
in_channels = i
for v in cfg:
if v == ‘M’:
layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
elif v == ‘C’:
layers += [nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)]
else:
conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
if batch_norm:
layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
else:
layers += [conv2d, nn.ReLU(inplace=True)]
in_channels = v
pool5 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)
conv6 = nn.Conv2d(512, 1024, kernel_size=3, padding=6, dilation=6)
conv7 = nn.Conv2d(1024, 1024, kernel_size=1)
layers += [pool5, conv6,
nn.ReLU(inplace=True), conv7, nn.ReLU(inplace=True)]
return layers

def add_extras(cfg, i, batch_norm=False):
# Extra layers added to VGG for feature scaling
layers = []
in_channels = i
flag = False
for k, v in enumerate(cfg):
if in_channels != ‘S’:
if v == ‘S’:
layers += [nn.Conv2d(in_channels, cfg[k + 1],
kernel_size=(1, 3)[flag], stride=2, padding=1)]
else:
layers += [nn.Conv2d(in_channels, v, kernel_size=(1, 3)[flag])]
flag = not flag
in_channels = v
return layers

def multibox(vgg, extra_layers, cfg, num_classes):
loc_layers = []
conf_layers = []
vgg_source = [24, -2]
for k, v in enumerate(vgg_source):
loc_layers += [nn.Conv2d(vgg[v].out_channels,
cfg[k] * 4, kernel_size=3, padding=1)]
conf_layers += [nn.Conv2d(vgg[v].out_channels,
cfg[k] * num_classes, kernel_size=3, padding=1)]
for k, v in enumerate(extra_layers[1::2], 2):
loc_layers += [nn.Conv2d(v.out_channels, cfg[k]
* 4, kernel_size=3, padding=1)]
conf_layers += [nn.Conv2d(v.out_channels, cfg[k]
* num_classes, kernel_size=3, padding=1)]
return vgg, extra_layers, (loc_layers, conf_layers)

base = {
‘300’: [64, 64, ‘M’, 128, 128, ‘M’, 256, 256, 256, ‘C’, 512, 512, 512, ‘M’,
512, 512, 512],
‘512’: [],
}
extras = {
‘300’: [256, ‘S’, 512, 128, ‘S’, 256, 128, 256, 128, 256],
‘512’: [],
}
mbox = {
‘300’: [4, 6, 6, 6, 4, 4], # number of boxes per feature map location
‘512’: [],
}

def build_ssd(phase, size=300, num_classes=21):
if phase != “test” and phase != “train”:
print(“Error: Phase not recognized”)
return
if size != 300:
print(“Error: Sorry only SSD300 is supported currently!”)
return

return SSD(phase, *multibox(vgg(base[str(size)], 3),
                            add_extras(extras[str(size)], 1024),
                            mbox[str(size)], num_classes), num_classes)

It seems you are writing a module, not a custom autograd.Function, so you won’t need the @staticmethod decorator.

thanks for your reply, if i not use @staticmethod decorator, then its showing runtime error:

Legacy autograd function with non-static forward method is deprecated. Please use new-style autograd function with static forward method. (Example: https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function ).

so that i followed your suggestion which you have given to jhonpool4 to include @staticmethor before the forward function, but i am getting another new issue : forward() missing 1 required positional argument, “x”.

If you are writing a custom autograd.Function, then you would need the decorator.
However, base on your code it seems you might be able to just write an nn.Module and let Autograd figure out the backward pass. In this approach you wouldn’t need the @staticmethod decorator.

thanks, i removed @staticmethod in my code then i am facing below error

Legacy autograd function with non-static forward method is deprecated. Please use new-style autograd function with static forward method. (Example: https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function ).

Could you post your model, which yields this error by wrapping it into three backticks ``` please?

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
from layers import *
from data import v2
import os


class SSD(nn.Module):
    """Single Shot Multibox Architecture
    The network is composed of a base VGG network followed by the
    added multibox conv layers.  Each multibox layer branches into
        1) conv2d for class conf scores
        2) conv2d for localization predictions
        3) associated priorbox layer to produce default bounding
           boxes specific to the layer's feature map size.
    See: https://arxiv.org/pdf/1512.02325.pdf for more details.

    Args:
        phase: (string) Can be "test" or "train"
        base: VGG16 layers for input, size of either 300 or 500
        extras: extra layers that feed to multibox loc and conf layers
        head: "multibox head" consists of loc and conf conv layers
    """

    def __init__(self, phase, base, extras, head, num_classes):
        super(SSD, self).__init__()
        self.phase = phase
        self.num_classes = num_classes
        # TODO: implement __call__ in PriorBox
        self.priorbox = PriorBox(v2)
        self.priors = Variable(self.priorbox.forward(), volatile=True)
        self.size = 300

        # SSD network
        self.vgg = nn.ModuleList(base)
        # Layer learns to scale the l2 normalized features from conv4_3
        self.L2Norm = L2Norm(512, 20)
        self.extras = nn.ModuleList(extras)

        self.loc = nn.ModuleList(head[0])
        self.conf = nn.ModuleList(head[1])
       

        if phase == 'test':
            self.softmax = nn.Softmax()
            self.detect = Detect(num_classes, 0, 200, 0.01, 0.45)
        
        
    @staticmethod    
    def forward(self, x):
        """Applies network layers and ops on input image(s) x.

        Args:
            x: input image or batch of images. Shape: [batch,3*batch,300,300].

        Return:
            Depending on phase:
            test:
                Variable(tensor) of output class label predictions,
                confidence score, and corresponding location predictions for
                each object detected. Shape: [batch,topk,7]

            train:
                list of concat outputs from:
                    1: confidence layers, Shape: [batch*num_priors,num_classes]
                    2: localization layers, Shape: [batch,num_priors*4]
                    3: priorbox layers, Shape: [2,num_priors*4]
        """
        sources = list()
        loc = list()
        conf = list()

        # apply vgg up to conv4_3 relu
        for k in range(23):
            x = self.vgg[k](x)

        s = self.L2Norm(x)
        sources.append(s)

        # apply vgg up to fc7
        for k in range(23, len(self.vgg)):
            x = self.vgg[k](x)
        sources.append(x)

        # apply extra layers and cache source layer outputs
        for k, v in enumerate(self.extras):
            x = F.relu(v(x), inplace=True)
            if k % 2 == 1:
                sources.append(x)

        # apply multibox head to source layers
        for (x, l, c) in zip(sources, self.loc, self.conf):
            loc.append(l(x).permute(0, 2, 3, 1).contiguous())
            conf.append(c(x).permute(0, 2, 3, 1).contiguous())

        loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1)
        conf = torch.cat([o.view(o.size(0), -1) for o in conf], 1)
        if self.phase == "test":
            output = self.detect(
                loc.view(loc.size(0), -1, 4),                   # loc preds
                self.softmax(conf.view(-1, self.num_classes)),  # conf preds
                self.priors.type(type(x.data))                  # default boxes
            )
      
        else:
            output = (
                loc.view(loc.size(0), -1, 4),
                conf.view(conf.size(0), -1, self.num_classes),
                self.priors
            )
            
        
        return output
    

    def load_weights(self, base_file):
        other, ext = os.path.splitext(base_file)
        if ext == '.pkl' or '.pth':
            print('Loading weights into state dict...')
            self.load_state_dict(torch.load(base_file, map_location=lambda storage, loc: storage))
            print('Finished!')
        else:
            print('Sorry only .pth and .pkl files supported.')


# This function is derived from torchvision VGG make_layers()
# https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py
def vgg(cfg, i, batch_norm=False):
    layers = []
    in_channels = i
    for v in cfg:
        if v == 'M':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        elif v == 'C':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)]
        else:
            conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
            if batch_norm:
                layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
            else:
                layers += [conv2d, nn.ReLU(inplace=True)]
            in_channels = v
    pool5 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)
    conv6 = nn.Conv2d(512, 1024, kernel_size=3, padding=6, dilation=6)
    conv7 = nn.Conv2d(1024, 1024, kernel_size=1)
    layers += [pool5, conv6,
               nn.ReLU(inplace=True), conv7, nn.ReLU(inplace=True)]
    return layers


def add_extras(cfg, i, batch_norm=False):
    # Extra layers added to VGG for feature scaling
    layers = []
    in_channels = i
    flag = False
    for k, v in enumerate(cfg):
        if in_channels != 'S':
            if v == 'S':
                layers += [nn.Conv2d(in_channels, cfg[k + 1],
                           kernel_size=(1, 3)[flag], stride=2, padding=1)]
            else:
                layers += [nn.Conv2d(in_channels, v, kernel_size=(1, 3)[flag])]
            flag = not flag
        in_channels = v
    return layers


def multibox(vgg, extra_layers, cfg, num_classes):
    loc_layers = []
    conf_layers = []
    vgg_source = [24, -2]
    for k, v in enumerate(vgg_source):
        loc_layers += [nn.Conv2d(vgg[v].out_channels,
                                 cfg[k] * 4, kernel_size=3, padding=1)]
        conf_layers += [nn.Conv2d(vgg[v].out_channels,
                        cfg[k] * num_classes, kernel_size=3, padding=1)]
    for k, v in enumerate(extra_layers[1::2], 2):
        loc_layers += [nn.Conv2d(v.out_channels, cfg[k]
                                 * 4, kernel_size=3, padding=1)]
        conf_layers += [nn.Conv2d(v.out_channels, cfg[k]
                                  * num_classes, kernel_size=3, padding=1)]
    return vgg, extra_layers, (loc_layers, conf_layers)


base = {
    '300': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'C', 512, 512, 512, 'M',
            512, 512, 512],
    '512': [],
}
extras = {
    '300': [256, 'S', 512, 128, 'S', 256, 128, 256, 128, 256],
    '512': [],
}
mbox = {
    '300': [4, 6, 6, 6, 4, 4],  # number of boxes per feature map location
    '512': [],
}


def build_ssd(phase, size=300, num_classes=21):
    if phase != "test" and phase != "train":
        print("Error: Phase not recognized")
        return
    if size != 300:
        print("Error: Sorry only SSD300 is supported currently!")
        return

    return SSD(phase, *multibox(vgg(base[str(size)], 3),
                                add_extras(extras[str(size)], 1024),
                                mbox[str(size)], num_classes), num_classes)

The posted code still has the @staticmethod defined and is an nn.Module.
I cannot find any usage of torch.autograd.Function, so the posted code should not raise the “legacy function error”.

Hi, version of colab is PyTorch1.5.0, I modified detection.py and ssd.py
so that it works without warning and error.

Since detection.py have torch.autograd.Function, I delete def init () and add @staticmethod.
I also add output = self.detect.apply() in ssd.py.

I share my code and you can find in ‘# PyTorch1.5.0 support new-style autograd function’ in source.

1 Like

i am getting diferent error
TypeError: super(type, obj): obj must be an instance or subtype of type
what should i do to solve that issue

earlier i got the legacy autogard… but now i am getting this new error just after visiting the function.py for legacy but i didn’t done any changes
File “C:\Users\hp\Anaconda3\lib\site-packages\torch\autograd\function.py”, line 101, in init
return super(FunctionMeta, cls).init(name, bases, attrs)

TypeError: super(type, obj): obj must be an instance or subtype of type

Hey guys Check out my GITHUB for the updated SSD Code for Latest Version of PyTorch

SSD and detection Python Codes updated to make it compatible with the latest version of PyTorch

Hey guys Check out my GITHUB for the updated SSD Code for Latest Version of PyTorch

SSD.py and detection Python Codes updated to make it compatible with the latest version of PyTorch