For a required Tensor, RuntimeError: One of the differentiated Tensors does not require grad

naz.ga: <p>I’m getting the following error message <strong>"For a required Tensor, RuntimeError: One of the differentiated Tensors does not require grad "</strong> I don’t think I should add requires_grad = False for this or the other tensors. I think there might be an error elsewhere that I can’t notice. Any suggestions? Or am I wrong?</p>
<p>The error arise from “u_t = torch.autograd.grad(u.sum(), t, create_graph=True)[0]” which is towards the end of the displayed code. Below is a snippet of my code</p>
<pre><code class="lang-auto">&gt; class PhysicsInformedNN:
&gt;         # Initialize the class
&gt;         def __init__(self, X, u, X_f, X_val, u_val, layers, lb, ub):
&gt;             
&gt;             self.lb = lb
&gt;             self.ub = ub
&gt;             self.layers = layers
&gt; 
&gt;             # Initialize NNs
&gt;             self.weights, self.biases = self.initialize_NN(layers)
&gt; 
&gt;             # Initialize parameters
&gt;             self.lambda1 = torch.zeros((16, 1), dtype=torch.float32, requires_grad=True)
&gt; 
&gt;             # Specify the list of trainable variables 
&gt;             var_list_1 = self.biases + self.weights
&gt;             var_list_Pretrain = self.biases + self.weights + [self.lambda1]
&gt;             #var_list_Pretrain.append(self.lambda1)
&gt; 
&gt;             ######### Training data ################
&gt;             #either keep placeholders like the author or work directly with tensors
&gt;             self.x = X[:, 0:1]
&gt;             self.t = X[:, 1:2]
&gt;             self.u = u
&gt;             self.x_f = X_f[:, 0:1]
&gt;             self.t_f = X_f[:, 1:2]
&gt; 
&gt;             self.x_pt = torch.empty((self.x.shape[0], self.x.shape[1]), dtype=torch.float32)
&gt;             self.t_pt = torch.empty((self.t.shape[0], self.t.shape[1]), dtype=torch.float32)
&gt;             self.u_pt = torch.empty((self.u.shape[0], self.u.shape[1]), dtype=torch.float32)
&gt;             self.x_f_pt = torch.empty((self.x_f.shape[0], self.x_f.shape[1]), dtype=torch.float32)
&gt;             self.t_f_pt = torch.empty((self.t_f.shape[0], self.t_f.shape[1]), dtype=torch.float32)
&gt; 
&gt;             self.u_pred = self.net_u(self.x_pt, self.t_pt)
&gt;             self.f_pred, self.Phi_pred, self.u_t_pred = self.net_f(self.x_f_pt, self.t_f_pt, self.x_f.shape[0])
&gt; 
&gt;             self.loss_u = torch.mean((self.u_pt - self.u_pred)**2)
&gt;             self.loss_f_coeff_pt = torch.empty(1, dtype=torch.float32)
&gt;             self.loss_f = self.loss_f_coeff_pt * torch.mean(self.f_pred**2)
&gt; 
&gt;             self.loss_lambda = 1e-7 * torch.norm(self.lambda1, p=1)
&gt;             self.loss = torch.log(self.loss_u + self.loss_f + self.loss_lambda)  # log loss
&gt; 
&gt;             ######### Validation data ################
&gt;             self.x_val = X_val[:, 0:1]
&gt;             self.t_val = X_val[:, 1:2]
&gt;             self.u_val = u_val
&gt; 
&gt;             # Create tensors for placeholder-like behavior (not a common practice in PyTorch)
&gt;             self.x_val_pt = torch.empty((self.x_val.shape[0], self.x_val.shape[1]), dtype=torch.float32)
&gt;             self.t_val_pt = torch.empty((self.t_val.shape[0], self.t_val.shape[1]), dtype=torch.float32)
&gt;             self.u_val_pt = torch.empty((self.u_val.shape[0], self.u_val.shape[1]), dtype=torch.float32)
&gt; 
&gt; 
&gt;             self.u_val_pred = self.net_u(self.x_val_pt, self.t_val_pt)
&gt;             self.f_val_pred, _, _ = self.net_f(self.x_val_pt, self.t_val_pt, self.x_val.shape[0])
&gt; 
&gt;             self.loss_u_val = torch.mean((self.u_val_pt - self.u_val_pred)**2)
&gt;             self.loss_f_val = torch.mean(self.f_val_pred**2)
&gt;             self.loss_val = torch.log(self.loss_u_val + self.loss_f_val)  # log loss
&gt; 
&gt;             ######### Optimizer #########################
&gt;             self.optimizer = optim.LBFGS(self.loss,var_list=var_list_1, max_iter=1000,max_eval=1000,history_size=50,line_search_fn='strong_wolfe',ftol=1.0*torch.finfo(torch.float32).eps)
&gt;             self.optimizer = optim.LBFGS(self.loss,var_list=var_list_Pretrain, max_iter=1000,max_eval=1000,history_size=50,line_search_fn='strong_wolfe',ftol=1.0*torch.finfo(torch.float32).eps)
&gt; 
&gt;            
&gt;             self.global_step = torch.tensor(0, dtype=torch.long, requires_grad=False)
&gt;             starter_learning_rate = 1e-3
&gt;             self.learning_rate = starter_learning_rate * (0.75 ** (self.global_step // 1000))
&gt;             
&gt;             self.optimizer_Adam = optim.Adam(var_list = var_list_1, lr=starter_learning_rate, betas=(0.99, 0.9), eps=1e-8)
&gt; 
&gt;             def closure():
&gt;                 self.optimizer_Adam.zero_grad()
&gt;                 self.loss.backward()
&gt;                 return self.loss
&gt; 
&gt;             self.train_op_Adam = closure
&gt;             self.global_step += 1 #needed?
&gt;             self.learning_rate.step() #needed?
&gt;             
&gt;             self.torch_dict = {self.x_pt: self.x, self.t_pt: self.t, self.u_pt: self.u, 
&gt;                        self.x_f_pt: self.x_f, self.t_f_pt: self.t_f,
&gt;                        self.x_val_pt: self.x_val, self.t_val_pt: self.t_val, self.u_val_pt: self.u_val}
&gt; 
&gt;         def initialize_NN(self, layers):
&gt;             weights = []
&gt;             biases = []
&gt;             num_layers = len(layers)
&gt;             for l in range(0, num_layers - 1):
&gt;                 W = self.xavier_init(size=[layers[l], layers[l+1]])
&gt;                 b = torch.zeros([1, layers[l+1]], dtype=torch.float64, requires_grad=True)
&gt;                 weights.append(W)
&gt;                 biases.append(b)
&gt;             return weights, biases
&gt; 
&gt;         def xavier_init(self, size):
&gt;             in_dim = size[0]
&gt;             out_dim = size[1]
&gt;             xavier_stddev = np.sqrt(2 / (in_dim + out_dim))
&gt;             return torch.randn([in_dim, out_dim], dtype=torch.float64) * xavier_stddev
&gt; 
&gt;         def neural_net(self, X, weights, biases):
&gt;             num_layers = len(weights) + 1
&gt; 
&gt;             H = 2.0 * (X - self.lb) / (self.ub - self.lb) - 1.0
&gt;             for l in range(0, num_layers - 2):
&gt;                 W = weights[l]
&gt;                 b = biases[l]
&gt;                 H = torch.tanh(torch.add(torch.matmul(H, W), b))
&gt;             W = weights[-1]
&gt;             b = biases[-1]
&gt;             Y = torch.add(torch.matmul(H, W), b)
&gt;             return Y
&gt; 
&gt;         def net_u(self, x, t):
&gt;             u = self.neural_net(torch.cat([x, t], 1), self.weights, self.biases)
&gt;             return u
&gt; 
&gt;         def net_f(self, x, t, N_f):
&gt;             u = self.net_u(x, t)
&gt;             u_t = torch.autograd.grad(u.sum(), t, create_graph=True)[0] #error starts here
&gt;             u_x = torch.autograd.grad(u.sum(), x, create_graph=True)[0]
&gt;             u_xx = torch.autograd.grad(u_x.sum(), x, create_graph=True)[0]
&gt;             u_xxx = torch.autograd.grad(u_xx.sum(), x, create_graph=True)[0]
&gt; 
&gt;             Phi = torch.cat([torch.ones(N_f, 1, dtype=torch.float32),
&gt;                             u, u**2, u**3, u_x, u*u_x, u**2*u_x,
&gt;                             u**3*u_x, u_xx, u*u_xx, u**2*u_xx,
&gt;                             u**3*u_xx, u_xxx, u*u_xxx, u**2*u_xxx,
&gt;                             u**3*u_xxx], 1)
&gt; 
&gt;             self.library_description = ['1',
&gt;                                         'u', 'u**2', 'u**3',
&gt;                                         'u_x', 'u*u_x', 'u**2*u_x', 'u**3*u_x',
&gt;                                         'u_xx', 'u*u_xx', 'u**2*u_xx', 'u**3*u_xx',
&gt;                                         'u_xxx', 'u*u_xxx', 'u**2*u_xxx', 'u**3*u_xxx']
&gt; 
&gt;             f = torch.matmul(Phi, self.lambda1) - u_t
&gt;             return f, Phi, u_t
</code></pre>
<p>Thank you in advance</p>

ptrblck: <p><code>u_t</code> expects <code>t</code> to be the inputs, however <code>self.net_f</code> is called with:</p>
<pre><code class="lang-python">self.f_pred, self.Phi_pred, self.u_t_pred = self.net_f(self.x_f_pt, self.t_f_pt, self.x_f.shape[0])
</code></pre>
<p>where <code>self.t_f_pt</code> was initialized as:</p>
<pre><code class="lang-python">self.t_f_pt = torch.empty((self.t_f.shape[0], self.t_f.shape[1]), dtype=torch.float32)
</code></pre>
<p>two lines before that call and this wasn’t used to create <code>self.x_f_pt</code> (which is also just an <code>empty</code> tensor). Let me know if I’m missing something.</p>

naz.ga: <p>I’m new to PyTorch and am converting a TensorFlow code to PyTorch.</p>
<p>The <code>t</code> inputs for <code>u_t</code> is coming from <code>self.t = X[:, 1:2]</code>. Are you saying <code>self.net_f</code> needs to be called with other variables?<br>
I’m sorry, if can’t seem to pinpoint the error from what your comment.</p>

ptrblck: <p>I might have misunderstood your model, so could you post a properly formatted minimal and executable code snippet reproducing the error, please?</p>