Why aren't torch.nn.Parameter listed when net is printed?

When you call print(net), the __repr__ method is called. __repr__ gives the “official” string representation of an object.

In PyTorch's nn.Module (base class of your MyNet model), the __repr__ is implemented like this:

def __repr__(self):
        # We treat the extra repr like the sub-module, one item per line
        extra_lines = []
        extra_repr = self.extra_repr()
        # empty string will be split into list ['']
        if extra_repr:
            extra_lines = extra_repr.split('\n')
        child_lines = []
        for key, module in self._modules.items():
            mod_str = repr(module)
            mod_str = _addindent(mod_str, 2)
            child_lines.append('(' + key + '): ' + mod_str)
        lines = extra_lines + child_lines

        main_str = self._get_name() + '('
        if lines:
            # simple one-liner info, which most builtin Modules will use
            if len(extra_lines) == 1 and not child_lines:
                main_str += extra_lines[0]
            else:
                main_str += '\n  ' + '\n  '.join(lines) + '\n'

        main_str += ')'
        return main_str

Note that the above method returns main_str which contains call to only _modules and extra_repr, thus it prints only modules by default.


PyTorch also provides extra_repr() method which you can implement yourself for extra representation of the module.

To print customized extra information, you should reimplement this method in your own modules. Both single-line and multi-line strings are acceptable.


According to nn.Parameter docs:

Parameters are :class:~torch.Tensor subclasses, that have a very special property when used with :class:Module s - when they're assigned as Module attributes they are automatically added to the list of its parameters, and will appear e.g. in :meth:~Module.parameters iterator.

So you can find it in net.parameters. Let's look at the following example:

Code:

import torch
import torch.nn as nn

torch.manual_seed(42)

class MyNet(nn.Module):
    def __init__(self):
        super(MyNet, self).__init__()
        self.layer = nn.Linear(4, 4)
        self.parameter = nn.Parameter(torch.zeros(4, 4, requires_grad=True))
        self.tensor = torch.ones(4, 4)
        self.module = nn.Module()

net = MyNet()
print(net)

Output:

MyNet(
  (layer): Linear(in_features=4, out_features=4, bias=True)
  (module): Module()
)

As you can see, there is no tensor or 'parameter' object (because parameter is subclass of tensor), only Modules.

Now let's try to get our net parameters:

Code:

for p in net.parameters():
    print(p)

Output:

Parameter containing:
tensor([[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]], requires_grad=True)
Parameter containing:
tensor([[ 0.3823,  0.4150, -0.1171,  0.4593],
        [-0.1096,  0.1009, -0.2434,  0.2936],
        [ 0.4408, -0.3668,  0.4346,  0.0936],
        [ 0.3694,  0.0677,  0.2411, -0.0706]], requires_grad=True)
Parameter containing:
tensor([ 0.3854,  0.0739, -0.2334,  0.1274], requires_grad=True)

Ok, so the first one is your net.parameter. Next two is weights and bias of net.layer. Let's verify it:

Code:

print(net.layer.weight)
print(net.layer.bias)

Output:

Parameter containing:
tensor([[ 0.3823,  0.4150, -0.1171,  0.4593],
        [-0.1096,  0.1009, -0.2434,  0.2936],
        [ 0.4408, -0.3668,  0.4346,  0.0936],
        [ 0.3694,  0.0677,  0.2411, -0.0706]], requires_grad=True)
Parameter containing:
tensor([ 0.3854,  0.0739, -0.2334,  0.1274], requires_grad=True)

Tags:

Python

Pytorch