Clone a Module?

zacharynew: <p>Hi all,</p>
<p>I’m working on a implementation of MAML (<a href="https://arxiv.org/pdf/1703.03400.pdf" rel="nofollow noopener">paper link</a>). There’s a few implementations out there but from what can see they all rely on the functional form of a model. I have a requirement to make this as general as possible so it can be used with a variety of underlying models. To that end I would like to be able to copy a nn.Module instance in the same way one can copy a variable or parameter. The key is that the gradients need to be able to get back to the copied nn.Module.</p>
<p>I’ve tried to hack something together via state-dicts and hooks but I keep running into cases where I need to copy a nn.Module without removing it from the computational graph.</p>
<p>Any thoughts on the problem would be appreciated!</p>
<p>Thanks!</p>

zacharynew: <p>And just after I post it I find a similar discussion: <a href="https://discuss.pytorch.org/t/are-there-any-recommended-methods-to-clone-a-model/483/16" class="inline-onebox">Are there any recommended methods to clone a model?</a></p>
<p>Edit: after reading through the other discussion I think its not what I am after. It focuses on how to properly copy a model and continue training with it. My use case is a little different as I want to properly clone the model and leave that cloning process in the computational graph so that I can differentiate all the way back to the original model.</p>

ptrblck: <p><code>tensor.clone()</code> is a differentiable operation, which could be used on your parameters.<br>
However, I’m not sure, if that would be suitable for your approach or not.</p>

zacharynew: <p>Hey <a class="mention" href="/u/ptrblck">@ptrblck</a>,</p>
<p>I’ve been trying to use the tensor.clone() operation but am not sure how to load the cloned tensors into a new nn.Module without using load_state_dict() which appears to disconnect parameters from the computation graph. I think you’re right that individually cloning the parameters is the way to go but I’m not sure how to pull this off and connect them to a new nn.Module without this detach from the computation graph occurring.</p>
<p>Thoughts?</p>

zacharynew: <p>After playing around a little more I think it comes down to being able to do the following:</p>
<p>Let <code>f</code> and <code>g</code> both be instances of the same <code>nn.Module</code>. Throw some input values through <code>g</code> when <code>g</code> is in training mode. Now the parameters in <code>g</code> have gradients and are part of a computation graph. Let <code>A</code> be a parameter in <code>f</code> and <code>B</code> be the corresponding parameter in <code>g</code>. Now set <code>C=B.clone()</code>. Here’s the bit I don’t know how to do, reassign <code>A</code> to be <code>C</code>.</p>
<p>This seems like a use-case that should be possible with PyTorch without being too hacky. Anyone have a path forward?</p>
<p>Thanks!</p>

albanD: <p>Hi,</p>
<p>Yes this is quite far from what nn.Modules were built for so it’s not super easy <img src="https://discuss.pytorch.org/images/emoji/apple/confused.png?v=9" title=":confused:" class="emoji" alt=":confused:"></p>
<p>The thing to keep in mind here is that the original Module and the cloned one should NOT be the same.<br>
In particular, the cloned one cannot use <code>nn.Parameter()</code> because these can only contain leaf Tensors (that don’t have history).<br>
So you most likely want to make sure that you delete each parameter and re-assign the field with a clone of the value in the other module.</p>

Dieblitzen: <p>Hi, did you manage to solve this? I am running into the same issues as you</p>

Pieterkii: <p>I’m using the deepcopy operation, works just fine</p>

seba-1511: <p>We have an implementation of clone_module in learn2learn (and used it for our MAML wrappers):</p>
<p><a href="https://github.com/learnables/learn2learn/blob/752200384c3ca8caeb8487b5dd1afd6568e8ec01/learn2learn/utils/__init__.py#L51" rel="noopener nofollow ugc">https://github.com/learnables/learn2learn/blob/752200384c3ca8caeb8487b5dd1afd6568e8ec01/learn2learn/utils/<strong>init</strong>.py#L51</a></p>