retain_graph=True

username: parisa71
cooked: <p>Hi<br>
I want to solve 2D Laplace equation with PINNs. I write this code but when I run the code, I faced this error “Trying to backward through the graph a second time (or directly access saved tensors after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to backward through the graph a second time or if you need to access saved tensors after calling backward.”<br>
I’ve read the other posts, but unless I’m mistaken none of them solve my problem.<br>
Here is my code:</p>
<p>import numpy as np<br>
import matplotlib.pyplot as plt</p>
<p>import torch<br>
import torch.nn as nn</p>
<p>num_points = 3 # Number of uniformly selected points for BC<br>
x_min, x_max, y_min, y_max = 0, 10000, 0, 4<br>
y_range, x_range =np.linspace(0,4,5)[1:-1] , np.linspace(0, 10000, 12)[1:-1]<br>
x_zeros = np.zeros(10)<br>
y_zeros = np.zeros(3)<br>
x_ones = np.ones(10)<br>
y_ones = np.ones(3)</p>
<p>bc_left = np.vstack([y_zeros, y_range, 5*y_ones]).T # Boundary left: h(x=0, y) = 5<br>
bc_right = np.vstack([10000 * y_ones, y_range, y_ones]).T # Boundary right: u(x=10, y) = 1</p>
<p>initial_boundary_conditions = np.vstack([bc_left, bc_right])<br>
x_initial_bc = initial_boundary_conditions[:, 0]<br>
y_initial_bc = initial_boundary_conditions[:, 1]<br>
u_initial_bc = initial_boundary_conditions[:, 2]</p>
<p>x_initial_bc = torch.autograd.Variable(torch.from_numpy(x_initial_bc).float(), requires_grad=True)   <span class="hashtag-raw">#torch</span>.Size([50000])<br>
y_initial_bc = torch.autograd.Variable(torch.from_numpy(y_initial_bc).float(), requires_grad=True)<br>
u_initial_bc = torch.autograd.Variable(torch.from_numpy(u_initial_bc).float(), requires_grad=True)<br>
x_range = torch.autograd.Variable(torch.from_numpy(x_range).float(), requires_grad=True)<br>
x_zeros = torch.autograd.Variable(torch.from_numpy(x_zeros).float(), requires_grad=True)<br>
x_ones = torch.autograd.Variable(torch.from_numpy(x_ones).float(), requires_grad=True)</p>
<p>collocation_points = 30 # Number of uniformly selected collocation points to be evaluated for the PDE-based loss<br>
class Net(nn.Module):<br>
def <strong>init</strong>(self):<br>
super(Net, self).<strong>init</strong>()<br>
self.neurons_per_layer = 20<br>
self.fc1 = nn.Linear(2, self.neurons_per_layer)<br>
self.fc2 = nn.Linear(self.neurons_per_layer, self.neurons_per_layer)<br>
self.fc3 = nn.Linear(self.neurons_per_layer, self.neurons_per_layer)<br>
self.fc4 = nn.Linear(self.neurons_per_layer, self.neurons_per_layer)<br>
self.fc5 = nn.Linear(self.neurons_per_layer, self.neurons_per_layer)<br>
self.fc6 = nn.Linear(self.neurons_per_layer, self.neurons_per_layer)<br>
self.fc7 = nn.Linear(self.neurons_per_layer, self.neurons_per_layer)<br>
self.fc8 = nn.Linear(self.neurons_per_layer, 1)<br>
self.relu = nn.ReLU()</p>
<pre><code>def forward(self, x, y):
    inputs = torch.cat([x.reshape(-1, 1), y.reshape(-1, 1)], axis=1)
    output = self.relu(self.fc1(inputs))
    output = self.relu(self.fc2(output))
    output = self.relu(self.fc3(output))
    output = self.relu(self.fc4(output))
    output = self.relu(self.fc5(output))
    output = self.relu(self.fc6(output))
    output = self.relu(self.fc7(output))
    output = self.fc8(output)
    return output
</code></pre>
<p>net = Net()<br>
epochs = 1000<br>
optimizer = torch.optim.Adam(net.parameters(), lr=1e-3)<br>
criterion = torch.nn.MSELoss()<br>
<span class="hashtag-raw">#PDE</span> loss<br>
def f(x, y, net):<br>
u = net(x, y)<br>
u_x = torch.autograd.grad(u, x, create_graph=True, retain_graph=True, grad_outputs=torch.ones_like(u))[0]<br>
u_xx = torch.autograd.grad(u_x, x, create_graph=True, retain_graph=True, grad_outputs=torch.ones_like(u_x))[0]<br>
u_y = torch.autograd.grad(u, y, create_graph=True, retain_graph=True, grad_outputs=torch.ones_like(u))[0]<br>
u_yy = torch.autograd.grad(u_y, y, create_graph=True, retain_graph=True, grad_outputs=torch.ones_like(u_y))[0]<br>
loss_f = u_xx + u_yy<br>
return loss_f</p>
<p>def neumann_bc_loss(net, x, y, target_gradient_value):<br>
u = net(x, y)<br>
u_y = torch.autograd.grad(u, y, create_graph=True, grad_outputs=torch.ones_like(u))[0]</p>
<pre><code>neumann_loss = torch.nn.functional.mse_loss(u_y, target_gradient_value * torch.ones_like(u_y))
return neumann_loss
</code></pre>
<p>neumann_loss_top = neumann_bc_loss(net, x_range, 4*x_ones, 0)<br>
neumann_loss_bottom = neumann_bc_loss(net, x_range, x_zeros, 0)</p>
<p>losses = <span class="chcklst-box fa fa-square-o fa-fw"></span><br>
for epoch in range(epochs):<br>
optimizer.zero_grad()<br>
predictions_initial_bc = net(x_initial_bc, y_initial_bc)<br>
mse_u = criterion(predictions_initial_bc.reshape(-1,), u_initial_bc) # This is the loss from boundary and initial conditions</p>
<pre><code>x_collocation = torch.FloatTensor(collocation_points, ).uniform_(x_min, x_max)
y_collocation = torch.FloatTensor(collocation_points, ).uniform_(y_min, y_max)
x_collocation = torch.autograd.Variable(x_collocation, requires_grad=True)
y_collocation = torch.autograd.Variable(y_collocation, requires_grad=True)

f_out = f(x_collocation, y_collocation, net)
mse_f = criterion(torch.zeros_like(f_out), f_out) # This is the PDE-based loss evaluated at the randomly sampled collocation points

loss = mse_u + mse_f + neumann_loss_bottom + neumann_loss_top
losses.append(loss.item())
loss.backward()
optimizer.step()
if epoch % 100 == 0:
    
    
    print(f'Epoch {epoch}/{epochs}: Loss = {loss.item()}')
</code></pre>
<p>I tried loss.backward(retain_graph=True) but I received this error “one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [20, 2]], which is output 0 of AsStridedBackward0, is at version 2; expected version 1 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).” can someone please help me to solve this problem?</p>

username: AlphaBetaGamma96
cooked: <aside class="quote no-group" data-username="parisa71" data-post="1" data-topic="202731">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/parisa71/48/77195_2.png" class="avatar"> parisa71:</div>
<blockquote>
<p>Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).</p>
</blockquote>
</aside>
<p>Have you tried running your code within a <code>torch.autograd.set_detect_anomaly(True)</code> context manager to isolate the in-place operation?</p>

username: parisa71
cooked: <p>no, I didn’t try it. where should I implement torch.autograd.set_detect_anomaly(True)?</p>

username: parisa71
cooked: <p>it should be noticed that when i added neumann_loss_bottom and neumann_loss_top to the loss this error was ocurred.</p>

username: AlphaBetaGamma96
cooked: <p>Hi <a class="mention" href="/u/parisa71">@parisa71</a>,</p>
<p>You can add this line before your training loss,</p>
<pre><code class="lang-auto">with torch.autograd.set_detect_anonmaly(True):
  for epoch in range(epochs):
    #code goes here
</code></pre>

username: parisa71
cooked: <p>thank you. I tried it but received this error again “one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [20, 2]], which is output 0 of AsStridedBackward0, is at version 2; expected version 1 instead. Hint: the backtrace further above shows the operation that failed to compute its gradient. The variable in question was changed in there or anywhere later.”</p>

username: AlphaBetaGamma96
cooked: <aside class="quote no-group" data-username="parisa71" data-post="1" data-topic="202731">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/parisa71/48/77195_2.png" class="avatar"> parisa71:</div>
<blockquote>
<p>u_y = torch.autograd.grad(u, y, create_graph=True, grad_outputs=torch.ones_like(u))[0]</p>
<pre><code class="lang-auto">
</code></pre>
</blockquote>
</aside>
<p>Should you have <code>retain_graph=True</code> in the <code>neumann_bc_loss</code> function?</p>

username: parisa71
cooked: <p>That’s right. Thank you very much.</p>