Custom implementation FC DNN, help needed with applying torch.optim

username: Alex_Postnikov
cooked: <p>Hello everyone!</p>
<p>i am trying to implement custom DNN, approx stucture can be seen at next image<br>
<img src="https://discuss.pytorch.org/uploads/default/original/3X/5/c/5c9655a37fceb08124575367b217d90842654664.png" alt="image" data-base62-sha1="dd415l0yeC1awaxaLNA1PZw2QJu" width="513" height="334"></p>
<p>The idea behind is that there is only one learnable parameter here, and it is initial state X (input tensor), all other <code>params</code> are fixed (not learnable).</p>
<p>We managed to make it work using custom nn.Module class with calculating gradients and manually applying them</p>
<pre><code class="lang-auto">class Linear(nn.Module):
   def __init__(self):                     #input_features, output_features, bias=True):
       super(Linear, self).__init__()


   def forward(self, input):
       state, cost = input

       rf, af = calc_forces(state, goals, param.pedestrians_speed, param.k, param.alpha, param.ped_radius, param.ped_mass, param.betta)
       F = rf + af
       out = pose_propagation(F, state, param.DT, param.pedestrians_speed)
       temp = calc_cost_function(param.a, param.b, param.e, goals, robot_init_pose, out, observed_state)
       cost = cost + temp.view(-1,1)
       return (out, cost) 

....
modules = []
   for i in range (0, number_of_layers):
       modules.append(Linear())

   sequential = nn.Sequential(*modules)
....
inner_data, cost = sequential((inner_data, cost))
cost = cost.sum()
cost.backward()
gradient =  inner_data.grad
with torch.no_grad():
   init_state = init_state + grad

</code></pre>
<p><strong>so, question is next:</strong><br>
<strong>May someone, point me in the right direction, how to apply torch.optim.SGD or any similar in such case?</strong><br>
The problem is that usually they operates with nn.Parameters, in mine case it is not clear how to introduce these parameter, because these parameter became defined only at first iteration.</p>
<p>i’ve tried to use</p>
<pre><code class="lang-auto">class Linear(nn.Module):
    def __init__(self):                     #input_features, output_features, bias=True):
        super(Linear, self).__init__()
        self.register_parameter('init_state', None)
        
    def forward(self, input):
        state, cost = input
        
        if self.init_state is None:
            self.init_state = nn.Parameter(state).requires_grad_(True)
            self.init_state.retain_grad()
            rf, af = calc_forces(self.init_state, goals, param.pedestrians_speed, param.k, param.alpha, param.ped_radius, param.ped_mass, param.betta)
            F = rf + af
            out = pose_propagation(F, self.init_state, param.DT, param.pedestrians_speed)
        else:
            if type(state) == type(nn.Parameter(torch.Tensor(1))):
                state = torch.tensor(state)
            rf, af = calc_forces(state, goals, param.pedestrians_speed, param.k, param.alpha, param.ped_radius, param.ped_mass, param.betta)
            F = rf + af
            out = pose_propagation(F, state, param.DT, param.pedestrians_speed)

        temp = calc_cost_function(param.a, param.b, param.e, goals, robot_init_pose, out, observed_state)
        cost = cost + temp.view(-1,1)
        return (out, cost) 
</code></pre>
<p>but it doesn`t helped much (sequential[0].init_state.grad always None)</p>