Difference between torch.Tensor.requires_grad and torch.nn.parameter.Parameter

mcorange: <p>Here is a short code snippet.</p>
<pre data-code-wrap="Python"><code class="lang-plaintext">In [1]: import torch                                                                                                                                                                                                                        
                                                                                                                                                                                                                                            
In [2]: t1 = torch.rand(2,4)                                                                                                                                                                                                                
                                                                                                                                                                                                                                            
In [3]: t1.requires_grad                                                                                                                                                                                                                    
Out[3]: False                                                                                                                                                                                                                               
                                                                                                                                                                                                                                            
In [4]: t1.requires_grad = True                                                                                                                                                                                                             
                                                                                                                                                                                                                                            
In [5]: t1.requires_grad                                                                                                                                                                                                                    
Out[5]: True                                                                                                                                                                                                                                
                                                                                                                                                                                                                                            
In [6]: l = torch.nn.Linear(4,2)                           
                                                                                                                      
In [7]: l.weight.data.requires_grad                        
Out[7]: False                                              
                                                                                                                      
In [8]: l.weight.data.requires_grad = True                 

In [9]: l.weight.data.requires_grad                                                                                   
Out[9]: False                                              
                                                           
In [10]: l.weight.requires_grad                            
Out[10]: True                                              

In [11]: print(type(t1), type(l.weight), type(l.weight.data))                                                         
&lt;class 'torch.Tensor'&gt; &lt;class 'torch.nn.parameter.Parameter'&gt; &lt;class 'torch.Tensor'&gt;
</code></pre>
<p>I am confused about some output of the code in terms of these things:</p>
<ol>
<li>What’s the difference between <code>torch.Tensor.requires_grad</code>(<code>t1</code>) and <code> torch.nn.parameter.Parameter</code>(<code>l</code>)? E.g., How do they influence behaviors in calculating the gradients?</li>
<li>Why setting <code>t1.requires_grad</code> to <code>True</code> works but setting <code>l.weight.data.requires_grad</code> to <code>True</code> does not, considering that <code>t1</code> and <code>l.weight.data</code> are both an object of class <code>torch.Tensor</code>?</li>
<li>What the relationship between <code>l.weight.data.requires_grad</code> and <code>l.weight.requires_grad</code>? The two seems not synchronized.</li>
</ol>
<p>I read related documents, source codes and forum discussions, but I found it hard to form a comprehensive understandings in mind to perfectly explain the questions mentioned above.</p>
<p>I really appreciate it if someone helps.</p>

ptrblck: <ol>
<li>
<p><code>nn.Parameter</code> just wraps a tensor and sets its <code>.requires_grad</code> attribute to <code>True</code> as seen <a href="https://github.com/pytorch/pytorch/blob/0617f7fa75c40e037731af202a0669793188dbeb/torch/nn/parameter.py#L42">here</a>.</p>
</li>
<li>
<p>Don’t use or depend on the internal <code>.data</code> attribute as it’s user-facing usage is deprecated and it’s only used internally.</p>
</li>
<li>
<p>Same as 2.</p>
</li>
</ol>

mcorange: <p>Thank you <a class="mention" href="/u/ptrblck">@ptrblck</a> and with your help I’m not confused anymore.</p>