PyTorch NotImplementedError in forward

donparker1: <p>I am receiving a forward_unimplemented raise NotImplementedError<br>
NotImplementedError</p>
<pre><code class="lang-auto">class Start_RN50(torch.nn.Module):
    def __init__(self, rn50):
    super(Start_RN50, self).__init__()
        self.start = torch.nn.Sequential(rn50.conv1, rn50.relu, rn50.maxpool)

    def forward(self, x):
        x = self.start(x)
        return x

class Middle_RN50(torch.nn.Module):
    def __init__(self, model):
    super(Middle_RN50, self).__init__()
        self.start = torch.nn.Sequential(rn50.conv1, rn50.relu, rn50.maxpool,rn50.layer1, rn50.layer2,rn50.layer3, rn50.layer4)

    def forward(self, x):
        x = self.start(x)
        return x

class End_RN50(torch.nn.Module):
    def __init__(self, rn50):
    super(End_RN50, self).__init__()
        self.avgpool = rn50.avgpool
        self.fc = rn50.fc

      
    def forward(self, x):
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.fc(x)
        return x</code></pre>

ptrblck: <p>This error is usually raised e.g. if the <code>forward</code> method isn’t defined which can be the case if you have a typo or a wrong indentation in the code.<br>
Your code is unfortunately not formatted properly (you can add code snippets by wrapping them into three backticks ```) so I don’t know what’s exactly failing.</p>

donparker1: <p>Thank you! I have properly formatted the code snippet</p>

AlphaBetaGamma96: <aside class="quote no-group" data-username="donparker1" data-post="1" data-topic="154996">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/d/e495f1/48.png" class="avatar"> donparker1:</div>
<blockquote>
<pre><code class="lang-auto">    super(Start_RN50, self).__init__()
</code></pre>
</blockquote>
</aside>
<p>Are your <code>super().__init__()</code> lines indented properly? Perhaps you’re not initializing the parent class and hence <code>forward</code> will be undefined!</p>

donparker1: <aside class="quote no-group" data-username="AlphaBetaGamma96" data-post="4" data-topic="154996">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/a/3da27b/48.png" class="avatar"> AlphaBetaGamma96:</div>
<blockquote>
<p><code>super().__init__()</code></p>
</blockquote>
</aside>
<p>I can execute Start_RN50 without issue. Only when Middle_RN50 forward function is stating it is “NotImplementedError”</p>

AlphaBetaGamma96: <p>Yes there’s no problem with creating the class, but if your <code>super</code> isn’t indented it will be an <code>Object</code> and not an <code>nn.Module</code> object. Is your class like,</p>
<pre><code class="lang-auto">class Start_RN50(torch.nn.Module):
    def __init__(self, rn50):
    super(Start_RN50, self).__init__()
        self.start = torch.nn.Sequential(rn50.conv1, rn50.relu, rn50.maxpool)

    def forward(self, x):
        x = self.start(x)
        return x
</code></pre>
<p>OR</p>
<pre><code class="lang-auto">class Start_RN50(torch.nn.Module):
    def __init__(self, rn50):
        super(Start_RN50, self).__init__() #&lt;&lt;&lt;&lt;&lt;&lt; this line 
        self.start = torch.nn.Sequential(rn50.conv1, rn50.relu, rn50.maxpool)

    def forward(self, x):
        x = self.start(x)
        return x
</code></pre>
<p>(notice the ident on the <code>super</code>)</p>

donparker1: <p>Yes, my apologies, the super(Start_RN50, self).<strong>init</strong>() is idented from the constructor; the probelem still persists.</p>

donparker1: <aside class="quote no-group" data-username="donparker1" data-post="1" data-topic="154996">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/d/e495f1/48.png" class="avatar"> donparker1:</div>
<blockquote>
<pre><code class="lang-auto">class Middle_RN50(torch.nn.Module):
    def __init__(self, model):
        super(Middle_RN50, self).__init__()
        self.start = torch.nn.Sequential(rn50.conv1, rn50.relu, rn50.maxpool,rn50.layer1, rn50.layer2,rn50.layer3, rn50.layer4)

    def forward(self, x):
        x = self.start(x)
        return x
</code></pre>
</blockquote>
</aside>
<pre><code class="lang-auto">def calibrate_end(model,cal_loader):
  
    rn50_middle = Middle_RN50(model)
    rn50_middle.eval()
  

    rn50_end = End_RN50(model)
    rn50_end.eval()
 
    
    for i, (images, target) in enumerate(cal_loader):
            temp = rn50_middle(images)
            output = rn50_end(temp)
</code></pre>
<p>The error, NotImplementedError  stems from this forward</p>

ptrblck: <p>This module works properly:</p>
<pre><code class="lang-python">class Middle_RN50(torch.nn.Module):
    def __init__(self, rn50):
        super(Middle_RN50, self).__init__()
        self.start = torch.nn.Sequential(rn50.conv1, rn50.relu, rn50.maxpool,rn50.layer1, rn50.layer2,rn50.layer3, rn50.layer4)

    def forward(self, x):
        x = self.start(x)
        return x
    
model = Middle_RN50(models.resnet50())
x = torch.randn(1, 3, 224, 224)
out = model(x)
print(out.shape)
# torch.Size([1, 2048, 7, 7])
</code></pre>
<p>I had to replace the unused <code>model</code> input argument with <code>rn50</code> as this parameter was missing.<br>
Given that I guess you are posting modified code here (as the execution would yield an error complaining about an undefined variable), which might not represent your error.</p>

donparker1: <p>For some reason, I am still receving the NotImplementedError, so I have displayed the complete source. Thanks so much in advance</p>
<pre><code class="lang-auto">class Middle_RN50(torch.nn.Module):
    def __init__(self, rn50):
        super(Middle_RN50, self).__init__()
        self.start = torch.nn.Sequential(rn50.conv1, rn50.relu, rn50.maxpool,rn50.layer1, rn50.layer2,rn50.layer3, rn50.layer4)


    def forward(self, x):
        x = self.start(x)
        return x

class End_RN50(torch.nn.Module):
    def __init__(self, rn50):
        super(End_RN50, self).__init__()
        self.avgpool = rn50.avgpool
        self.fc = rn50.fc

    def forward(self, x):
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.fc(x)
        return x


def calibrate_end(model,cal_loader):
    
    rn50_middle = Middle_RN50(model)

    rn50_middle.eval()
    rn50_end = End_RN50(model)
    rn50_end.eval()

    for i, (images, target) in enumerate(cal_loader):
            temp = rn50_middle(images)
            output = rn50_end(temp)


   
model = models.__dict__['resnet50'](pretrained=False)

state_dict = torch.load('resnet50-19c8e357.pth', map_location=lambda storage, loc: storage)
model.load_state_dict(state_dict)
model.eval()

normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                       std=[0.229, 0.224, 0.225])

cal_loader = torch.utils.data.DataLoader(datasets.ImageFolder("calibration_dataset/", transforms.Compose([
                transforms.Resize(256),
                transforms.CenterCrop(224),
                transforms.ToTensor(),
                normalize,
            ])),

            batch_size=1, shuffle=False,
            num_workers=4, pin_memory=True)



calibrate_end(model, cal_loader)

</code></pre>

donparker1: <p>I have shared the complete source code. Thanks in advance.</p>

ptrblck: <p>Your code still works after removing the undefined parts:</p>
<pre><code class="lang-python">class Middle_RN50(torch.nn.Module):
    def __init__(self, rn50):
        super(Middle_RN50, self).__init__()
        self.start = torch.nn.Sequential(rn50.conv1, rn50.relu, rn50.maxpool,rn50.layer1, rn50.layer2,rn50.layer3, rn50.layer4)

    def forward(self, x):
        x = self.start(x)
        return x

class End_RN50(torch.nn.Module):
    def __init__(self, rn50):
        super(End_RN50, self).__init__()
        self.avgpool = rn50.avgpool
        self.fc = rn50.fc

    def forward(self, x):
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.fc(x)
        return x

def calibrate_end(model):
    rn50_middle = Middle_RN50(model)
    rn50_middle.eval()
    rn50_end = End_RN50(model)
    rn50_end.eval()

    images = torch.randn(2, 3, 224, 224)
    temp = rn50_middle(images)
    output = rn50_end(temp)
    return output

model = models.__dict__['resnet50'](pretrained=False)
model.eval()
output = calibrate_end(model)
print(output.shape)
# torch.Size([2, 1000])
</code></pre>
<p>Generally, a minimal and executable code snippet can be simply copy-pasted to another environment, executed, and should reproduce the issue.<br>
Your current code snippets still use undefined checkpoints, datasets etc. and removing them works fine.</p>

donparker1: <p>Thank you so much! I realized when trying to fuse layers that was causing the ‘NotImplementedError’</p>
<pre><code class="lang-auto">import torch.fx.experimental.optimization as optimization
class Middle_RN50(torch.nn.Module):
    def __init__(self, rn50):
        super(Middle_RN50, self).__init__()
        with torch.no_grad():
            rn50 = optimization.fuse(rn50, inplace=False) # ADDED
        self.start = torch.nn.Sequential(rn50.conv1, rn50.relu, rn50.maxpool,rn50.layer1, rn50.layer2,rn50.layer3, rn50.layer4)

    def forward(self, x):
        x = self.start(x)
        return x

class End_RN50(torch.nn.Module):
    def __init__(self, rn50):
        super(End_RN50, self).__init__()
        self.avgpool = rn50.avgpool
        self.fc = rn50.fc

    def forward(self, x):
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.fc(x)
        return x

def calibrate_end(model):
    rn50_middle = Middle_RN50(model)
    rn50_middle.eval()
    rn50_end = End_RN50(model)
    rn50_end.eval()

    images = torch.randn(2, 3, 224, 224)
    temp = rn50_middle(images)
    output = rn50_end(temp)
    return output

model = models.__dict__['resnet50'](pretrained=False)
model.eval()
output = calibrate_end(model)
print(output.shape)
# torch.Size([2, 1000])
</code></pre>

ptrblck: <p>Thanks for the update.<br>
I would guess your use case fails since you are first fusing the entire model and are later trying to rip out smaller modules to create <code>self.start</code>.<br>
Creating the <code>nn.Sequential</code> container with raw and fused modules should work:</p>
<pre><code class="lang-python">        self.start = torch.nn.Sequential(
            rn50.conv1,
            rn50.relu,
            rn50.maxpool,
            optimization.fuse(rn50.layer1),
            optimization.fuse(rn50.layer2),
            optimization.fuse(rn50.layer3),
            optimization.fuse(rn50.layer4)
        )
</code></pre>