Error when I use torch.save() and torch.load()

username: vishak_bharadwaj
cooked: <pre><code class="lang-auto">torch.save(model, 'model.pth')

model = torch.load('model.pth')
</code></pre>
<p>The docs say</p>
<blockquote>
<p>This approach uses Python <a href="https://docs.python.org/3/library/pickle.html" rel="noopener nofollow ugc">pickle</a> module when serializing the model, thus it relies on the actual class definition to be available when loading the model.</p>
</blockquote>
<p>What exactly does available mean? Where should it be available? In which directory or path do I need to have it stored?</p>
<p>I’ve provided a little more detail here.</p><aside class="quote quote-modified" data-post="3" data-topic="119818">
  <div class="title">
    <div class="quote-controls"></div>
    <img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/vishak_bharadwaj/48/18796_2.png" class="avatar">
    <a href="https://discuss.pytorch.org/t/error-when-i-use-torch-save-and-torch-load/119818/3">Error when I use torch.save() and torch.load()</a> 
  </div>
  <blockquote>
    The code and weights are pretty standard. Just a regular network on jupyter notebook 
I wrote this model that converts an image into a vector, on colab 
class ConvEncoder(nn.Module):
    def __init__(self):
        super().__init__()

        self.conv1 = nn.Conv2d(3, 16, (3, 3), padding=(1, 1))
        self.bn1 = nn.BatchNorm2d(16)
        self.relu1 = nn.ReLU()
        self.maxpool1 = nn.MaxPool2d((2, 2))

        self.conv2 = nn.Conv2d(16, 32, (3, 3), padding=(1, 1))
        self.bn2 = nn.Bat…
  </blockquote>
</aside>


username: JuanFMontesinos
cooked: <p>You should provide the code and the weights rather than the model.</p>

username: vishak_bharadwaj
cooked: <p>The code and weights are pretty standard. Just a regular network on jupyter notebook<br>
I wrote this model that converts an image into a vector, on colab</p>
<pre><code class="lang-auto">class ConvEncoder(nn.Module):
    def __init__(self):
        super().__init__()

        self.conv1 = nn.Conv2d(3, 16, (3, 3), padding=(1, 1))
        self.bn1 = nn.BatchNorm2d(16)
        self.relu1 = nn.ReLU()
        self.maxpool1 = nn.MaxPool2d((2, 2))

        self.conv2 = nn.Conv2d(16, 32, (3, 3), padding=(1, 1))
        self.bn2 = nn.BatchNorm2d(32)
        self.relu2 = nn.ReLU()
        self.maxpool2 = nn.MaxPool2d((2, 2))

        self.conv3 = nn.Conv2d(32, 64, (3, 3), padding=(1, 1))
        self.bn3 = nn.BatchNorm2d(64)
        self.relu3 = nn.ReLU()
        self.maxpool3 = nn.MaxPool2d((2, 2))

    def forward(self, x):

        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu1(x)
        x = self.maxpool1(x)

        x = self.conv2(x)
        x = self.bn2(x)
        x = self.relu2(x)
        x = self.maxpool2(x)

        x = self.conv3(x)
        x = self.bn3(x)
        x = self.relu3(x)
        x = self.maxpool3(x)

        return x
</code></pre>
<p>Then I did</p>
<pre><code class="lang-auto">model = ConvEncoder()
torch.save(model, 'enc.pth')
</code></pre>
<p>But when I download that to my local system, and run</p>
<pre><code class="lang-auto">model = torch.load('enc.pth')
</code></pre>
<p>I get an error saying Model not found. However if save and load it in the same place, like a colab notebook,it <em>does</em> work. So I’m trying to figure out what is breaking here.</p>

username: JuanFMontesinos
cooked: <p>Pickle serialises the instances. It is supposed to provide minimal information to recover the object. Pytorch works using several modules and inheritances and I simply think the state serialised fails. Cannot tell you why without deeply stuying it.</p>
<p>That is why I still suggest to provide code + weights as the weights depends in an Ordered Dict and has much less dependencies that the nn.Modules.</p>

username: vishak_bharadwaj
cooked: <p>Thanks. It’s just that the API I’m building <em>needs</em> Pytorch to save and load the whole thing at once.</p>
<p>I’m building an explanation API that takes in a model, and an image and produces a Class activation map( CAM).</p>
<p>I want the API to work for any model that is supplied, this works for tf models, since you can save and load them quite simply,  but not for Pytorch models, because I need to instantiate the model definition “before” I fire my API up, which is very inconvenient.</p>

username: JuanFMontesinos
cooked: <p>Although you could do that, you still need to provide the code so that pickle can reconstruct the object. In the end (in your case) it’s a matter of just instantiating that object generically with *args and **kwargs.</p>