How to repeat a tensor and get an nn.parameter while keeping gradient

username: YuanSnowing
cooked: <p>I want to repeat a tensor like this:</p>
<pre><code class="lang-auto">import torch
import torch.nn as nn

pos = [0.1, 0.2, 0.3]
pos_tens = torch.Tensor(pos)
pos_pm = nn.Parameter(pos_tens, requires_grad=True)
xyz = nn.Parameter(pos_tens.repeat(10, 1), requires_grad=True)

trans = pos_pm.repeat(10, 1) 
# &lt;class 'torch.Tensor'&gt; hope it can pass grad to pos_pm，and it must be an nn.parameter
trans_n = nn.Parameter(pos_pm.repeat(10, 1))
trans.retain_grad()
new = xyz + trans_n

y = new.sum()
y.backward()

print(xyz.grad) # tensor([[1., 1., 1.],...,[1., 1., 1.]])
print(trans.grad) # None
print(pos_pm.grad) # None, hope it not none
</code></pre>
<p>For some reason, I want make B an nn.parameter , and when running “B.backward()”, “A.grad” is not none.<br>
I tried this above, but not work.<br>
What should I do?</p>

username: YuanSnowing
cooked: <aside class="quote no-group" data-username="rtwolfe94022" data-post="2" data-topic="196249">
<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/rtwolfe94022/48/67286_2.png" class="avatar"> rtwolfe94022:</div>
<blockquote>
<pre><code class="lang-auto"># If you need trans as an nn.Parameter for some reason, consider wrapping operations
# in a module or function where trans is computed dynamically from pos_pm
</code></pre>
</blockquote>
</aside>
<p>Thank you very much for your patient answer, which is very helpful for beginners like me.</p>
<p>I have tried the advice you provided, but there are still some things I don’t understand. Because this is my first time asking a question here, the description of the question is somewhat unclear.</p>
<ol>
<li>
<p>I have tried using <code>trans=pos_pm. repeat (10,1)</code> , which can be used for <code>pos_ pm</code> preserves gradients, so I don’t understand why should I use <code>pos_pm.unsqueeze(0).repeat(10, 1)</code>.</p>
</li>
<li>
<p>I made some mistakes in my statement. I hope the final result is an <code>nn.Parameter</code>, which is the <code>new</code> in the code. This section of code was abstracted from my actual code, but I made some mistakes that led to confusion in the problem.</p>
</li>
</ol>
<p>Actually, this is how I implemented it:</p>
<pre><code class="lang-auto">class Transformation(nn.Module):
    def __init__(self, trans):
        '''
        trans(1*3)
        '''
        super(Transformation, self).__init__()
        self.trans = nn.Parameter(trans, requires_grad=True)
        
    def apply_transform(self, xyz: nn.Parameter):
        '''
        input xyz(n*3): nn.parameter
        output: (n*3)nn.parameter
        '''
        xyz_n = xyz.data.shape[0]
        trans = self.trans.repeat(xyz_n, 1).cuda()
        xyz_new = torch.nn.Parameter(xyz + trans)
        print(f"types {type(xyz_new)}")
        return xyz_new
    
</code></pre>
<p>But here’s <code>xyz_new</code> is a tensor and cannot be assigned to <code>nn.Parameter</code> like this:</p>
<pre><code class="lang-auto">postrans = Transformation([0.1,0.1,0.1])
self.mean = postrans.apply_transform(self.mean)
</code></pre>
<p>Will get <code>TypeError: cannot assign 'torch.cuda.FloatTensor' as parameter 'mean' (torch.nn.Parameter or None expected)</code>.</p>