Search code examples
deep-learningpytorchneural-network

Why does my dynamic neural network have 0 parameters?


I have defined the following neural network:

class Q_function(nn.Module):

    def __init__(self, input_size=3, hidden_size=5, num_layers=3, learning_rate=0.01):
        super(Q_function, self).__init__()
        self.input_size = input_size
        self.layers = []
        for i in num_layers:
            self.layers.append(nn.Linear(input_size, hidden_size)) 
            self.append(nn.ReLU())
        self.layers.append(nn.Linear(hidden_size,1))
    
    def forward(self, x):
        out = self.layers[0](x)
        for lay in range(1,len(self.layers)):
            out = self.layers[lay](out)
        return out

When I run:

net = Q_function()
list(net.parameters())

I get the output as an empty list []. Can someone explain why the network has no parameters? How to register the parameters? How to fix this issue?


Solution

  • Pytorch tracks parameters through specific constructor classes. It has no visibility into arbitrary lists.

    To track your list of modules, you need to wrap it in a nn.Sequential or nn.ModuleList

    class Q_function(nn.Module):
    
        def __init__(self, input_size=3, hidden_size=5, num_layers=3, learning_rate=0.01):
            super(Q_function, self).__init__()
            self.input_size = input_size
            self.layers = []
            for i in num_layers:
                self.layers.append(nn.Linear(input_size, hidden_size)) 
                self.append(nn.ReLU())
            self.layers.append(nn.Linear(hidden_size,1))
            self.layers = nn.ModuleList(self.layers)
        
        def forward(self, x):
            out = self.layers[0](x)
            for lay in range(1,len(self.layers)):
                out = self.layers[lay](out)
            return out
    

    That said, there are also a number of errors in your model code. You probably want something like this:

    class Q_function(nn.Module):
    
        def __init__(self, input_size=3, hidden_size=5, num_layers=3, learning_rate=0.01):
            super(Q_function, self).__init__()
            self.input_size = input_size
            self.layers = [nn.Linear(input_size, hidden_size), nn.ReLU()]
            for i in range(num_layers-1):
                self.layers.append(nn.Linear(hidden_size, hidden_size)) 
                self.layers.append(nn.ReLU())
            self.layers.append(nn.Linear(hidden_size,1))
            self.layers = nn.Sequential(*self.layers)
        
        def forward(self, x):
            x = self.layers(x)
            return x