You can copy into a Tensor in a differentiable way with param.copy_(pi).
The problem is that Parameters are leafs (they never have history) so you won’t be allowed to do this.
If you don’t want them to be Parameters anymore and want them to have history, you can simply delete the existing parameter del net.foo and set a plain Tensor to replace it net.foo = your_tensor.
When you do net.paramters(), you only get the Parameter, not the parent Module.
You can check the named_parameters() to get both the Parameter and the name to access it.
You can do something that looks like the following:
def del_obj(mod, name):
names = name.split(".")
for n in names[:-1]:
mod = mod[n]
del mod[names[-1]]
def set_obj(mod, name, new_val):
names = name.split(".")
for n in names[:-1]:
mod = mod[n]
mod[names[-1]] = new_val
for (name, _), pi in zip(net.named_parameters(), p_new):
del_obj(net, name)
set_obj(net, name, pi)