Gradiant cusom variables

Mohammed_Alruqimi: <p>I have a pytorch nn, as shown below. I want my neural network to calobirate the variables (sigma and lam).</p>
<pre><code class="lang-auto">class SDE(nn.Module):
    def __init__(self,lam,sigma):
        super().__init__()
        self.lam = lam
        self.sigma = sigma

    def forward(self, T, steps, Npaths):
        np.random.seed(4)
        lam = self.lam.detach().numpy()
        sigma= self.sigma.detach().numpy()
         .....
        return sigma * lam * xx
</code></pre>
<p>My main nn is:</p>
<pre><code class="lang-auto">class MyModel(nn.Module):
    def __init__(self, args):
        super(MyModel, self).__init__()
        self.lam = nn.Parameter(torch.tensor(1.0), requires_grad=True)
        self.sigma = nn.Parameter(torch.tensor(0.2), requires_grad=True)
        # GRU layers
        self.gru = nn.GRU(
            self.input_dim, self.hidden_dim, self.layer_dim, batch_first=True, 
                                                dropout=args.dropout, bidirectional=True)

        # SDE 
         levy = SDE(self.lam, self.sigma) 
        # Fully connected layer
        self.fc = nn.Linear(self.hidden_dim * 2, self.output_dim)
   
    def forward(self, x):
            lev = torch.from_numpy(levy(1.0, 16, 1))
            .....
            h0 = torch.zeros(self.args['num_layers']* 2, x.size(0), self.args['n_hidden_units'], 
                                                                                     device=x.device).requires_grad_()
            out, _ = self.gru(x, h0.detach())
            out = out[:, -1, :]
            out = self.fc(out)
            out_m = torch.mul(out, lev)
            return out
</code></pre>
<p>Does this netwok calibirate the sigma and lam variables?<br>
I’m a beginner and don’t know if I’m doing it wright.</p>
<p>The train will besomething like this:</p>
<pre><code class="lang-auto">    # Makes predictions
      yhat = self.model(x)
      # Computes loss
      loss = self.loss_fn(y, yhat)
      # Computes gradients
      #loss.requires_grad = True
      loss.backward()
      # Updates parameters and zeroes gradients
      self.optimizer.step()
      self.optimizer.zero_grad()
</code></pre>

AlphaBetaGamma96: <p>Hi <a class="mention" href="/u/mohammed_alruqimi">@Mohammed_Alruqimi</a>,</p>
<p>So, to get the gradients to work within pytorch, you need to use only pytorch functions (so, don’t use <code>numpy</code> for example). When you call <code>.detach()</code>, you delete the history of all operations on that variable, so you can’t compute gradients.</p>
<aside class="quote no-group" data-username="Mohammed_Alruqimi" data-post="1" data-topic="201996">
<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/mohammed_alruqimi/48/62632_2.png" class="avatar"> Mohammed_Alruqimi:</div>
<blockquote>
<pre><code class="lang-auto">        np.random.seed(4)
        lam = self.lam.detach().numpy()
        sigma= self.sigma.detach().numpy()
</code></pre>
</blockquote>
</aside>
<p>Likewise here as well, calling <code>.requires_grad_()</code> and <code>.detach()</code> will delete the history of operations and will stop backprop.</p>
<aside class="quote no-group" data-username="Mohammed_Alruqimi" data-post="1" data-topic="201996">
<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/mohammed_alruqimi/48/62632_2.png" class="avatar"> Mohammed_Alruqimi:</div>
<blockquote>
<pre><code class="lang-auto">            h0 = torch.zeros(self.args['num_layers']* 2, x.size(0), self.args['n_hidden_units'], 
                                                                                     device=x.device).requires_grad_()
            out, _ = self.gru(x, h0.detach())
</code></pre>
</blockquote>
</aside>
<p>If you want to define a custom function (which uses numpy operations), you must define a <code>torch.autograd.Function</code> object where you manually define the forward and backward methods, the docs can be found here: <a href="https://pytorch.org/docs/stable/notes/extending.html#extending-autograd" class="inline-onebox" rel="noopener nofollow ugc">Extending PyTorch — PyTorch 2.3 documentation</a></p>

Mohammed_Alruqimi: <p>Thank you <a class="mention" href="/u/alphabetagamma96">@AlphaBetaGamma96</a><br>
That is helpful.<br>
However, it would be easier to use pure tensor calculation instead of defining custom torch.autogard.function.<br>
If i can extend this question, my fumction that includes the numpu calculation is:</p>
<pre><code class="lang-auto">def merton_jump_paths_numpy( T, r, sigma,  lam, m, v, steps, Npaths):
    size=(steps,Npaths)
    dt = T/steps
    poi_rv = np.multiply(np.random.poisson( lam*dt, size=size),
                     np.random.normal(m,v, size=size)).cumsum(axis=0)
    geo = np.cumsum(((r -  sigma**2/2 -lam*(m  + v**2*0.5))*dt +\
                          sigma*np.sqrt(dt) * \
                          np.random.normal(size=size)), axis=0)

    return np.exp(geo+poi_rv)
</code></pre>
<p>So, I think I need to find tensor-based alternatives to np.cumsum, np.random.poisson, np.sqrt, np.random.normal and np.multiply.<br>
Can you help in this regard?</p>

AlphaBetaGamma96: <p>Most of these functions require replacing <code>numpy.X</code> with <code>torch.X</code> where X is the given function within a given namespace, you can check for the equivalents in the docs here: <a href="https://pytorch.org/docs/stable/index.html" class="inline-onebox" rel="noopener nofollow ugc">PyTorch documentation — PyTorch 2.3 documentation</a></p>