How to copy NN models?

username: QFuser
cooked: <p>I tried for a while now but no matter what the parameters seems not to be copied over .<br>
pulling the model from a central one</p>
<p>void ThreadHandler::updateNet(MyNet extern_net)<br>
{<br>
m_net.lock();<br>
// MyNet cloned_net = MyNet(options.input_size, options.hidden_size, options.hidden_size2, options.hidden_size3, options.output_size);// should change the parameters to be dynamic</p>
<pre><code>// auto temp = *std::dynamic_pointer_cast&lt;MyNet&gt;(main_net-&gt;clone());//just a pointer
auto paramsA = main_net-&gt;named_parameters(true);
auto paramsB = extern_net-&gt;named_parameters(true);

extern_net-&gt;to(options.device);
torch::manual_seed(options.seed);

bool brek = false;
</code></pre>
<p>torch::autograd::GradMode::set_enabled(false);<br>
for (auto&amp; paramA : paramsA) {<br>
for (auto&amp; paramB : paramsB) {<br>
if (paramA.key() == paramB.key()) {<br>
if (!paramA.value().grad().defined()) {<br>
std::cout &lt;&lt; “Error: Main Net” &lt;&lt; paramA.key() &lt;&lt; " is not defined" &lt;&lt; std::endl;<br>
brek = true;<br>
break;<br>
}<br>
if (!paramB.value().grad().defined()) {<br>
std::cout &lt;&lt; “Error: Extern Net” &lt;&lt; paramB.key() &lt;&lt; " is not defined" &lt;&lt; std::endl;<br>
brek = true;<br>
break;<br>
}<br>
<a href="//paramB.value" rel="noopener nofollow ugc">//paramB.value</a>().data().copy_(paramA.value().data().clone());</p>
<pre><code>            paramB.value().grad().data() = paramA.value().grad().data().clone();
            
            break;
        }
    }
    if (brek)
    {
        break;
    }
}
</code></pre>
<p>torch::autograd::GradMode::set_enabled(true);</p>
<p>// std::cout &lt;&lt; "Seed is : " &lt;&lt; options.seed &lt;&lt; std::endl;<br>
m_net.unlock();<br>
}</p>
<p>Just a primitive try to average between multiply models</p>
<p>void ThreadHandler::average(MyNet extern_net)<br>
{<br>
std::cout &lt;&lt; “Averaging” &lt;&lt; std::endl;<br>
// MyNet mainnet = MyNet(options.input_size, options.hidden_size, options.hidden_size2, options.hidden_size3, options.output_size);<br>
// cloneNet(mainnet);<br>
m_net.lock();<br>
auto paramsA = extern_net-&gt;named_parameters(true);<br>
auto paramsB = main_net-&gt;named_parameters(true);</p>
<pre><code>bool brek = false;
</code></pre>
<p>torch::autograd::GradMode::set_enabled(false);<br>
for (auto&amp; paramA : paramsA) {<br>
for (auto&amp; paramB : paramsB) {<br>
if (paramA.key() == paramB.key()) {<br>
if (!paramA.value().grad().defined()) {<br>
std::cout &lt;&lt; “Error: Main Net” &lt;&lt; paramA.key() &lt;&lt; " is not defined" &lt;&lt; std::endl;<br>
brek = true;<br>
break;<br>
}<br>
if (!paramB.value().grad().defined()) {<br>
std::cout &lt;&lt; “Error: Extern Net” &lt;&lt; paramB.key() &lt;&lt; " is not defined" &lt;&lt; std::endl;<br>
brek = true;<br>
break;<br>
}<br>
<a href="//paramB.value" rel="noopener nofollow ugc">//paramB.value</a>().data().copy_((paramA.value().data() + paramB.value().data()) / 2.0);<br>
paramB.value().grad().data() = (paramA.value().grad().data()+ paramB.value().grad().data()) / 2.0;<br>
break;<br>
}<br>
}<br>
if (brek)<br>
{<br>
break;<br>
}<br>
}</p>
<p>// main_net = mainnet;<br>
torch::autograd::GradMode::set_enabled(true);</p>
<pre><code>m_net.unlock();
</code></pre>
<p>}</p>
<p>maybe my train method helps</p>
<p>void ThreadHandler::train(MyNet extern_net, Options options)<br>
{</p>
<pre><code>// for Debugging only
std::vector&lt;int64_t&gt; expected_size = { 29, 1, 4 };
extern_net-&gt;train();
auto train_set = ClimateDataset(data).map(torch::data::transforms::Stack&lt;&gt;());
torch::manual_seed(options.seed);
extern_net-&gt;to(options.device);

torch::optim::Adam optimizer(extern_net-&gt;parameters(), torch::optim::AdamOptions(options.learning_rate));

auto train_loader = torch::data::make_data_loader&lt;torch::data::samplers::DistributedRandomSampler&gt;(
    std::move(train_set),
    torch::data::DataLoaderOptions().batch_size(options.train_batch_size));

for (int i = 0; i &lt; options.iterations; i++) {
    for (auto&amp; batch : *train_loader) {

        optimizer.zero_grad();


        auto inputs = batch.data.to(options.device);
        auto targets = batch.target.to(options.device);
        std::vector&lt;int64_t&gt; input_size = inputs.sizes().vec();
        std::vector&lt;int64_t&gt; target_size = targets.sizes().vec();
        //for debugging and condinal breaks only
        int64_t ist = input_size.operator[](2);
        int64_t tes = target_size.operator[](2);
        TORCH_CHECK(input_size == expected_size);

        torch::Tensor prediction = extern_net-&gt;forward(inputs);

        auto loss = torch::l1_loss(prediction, targets);
        std::cout &lt;&lt; "Loss: " &lt;&lt; loss.item&lt;float&gt;() &lt;&lt; std::endl;
        loss.backward();
        optimizer.step();
    }
}

if (options.notwhole) {
	average(extern_net);
}
else {
	averageWhole(extern_net);
}

stop();
//monitor();
</code></pre>
<p>}</p>

username: QFuser
cooked: <p>Since half of it is just coping the modul (in pytorch terminology).<br>
I done following by following older threads :</p>
<p><span class="hashtag-raw">#pragma</span> once<br>
<span class="hashtag-raw">#include</span> <br>
<span class="hashtag-raw">#include</span> &lt;torch/torch.h&gt;<br>
<span class="hashtag-raw">#include</span> </p>
<p>struct MyNetImpl : public torch::nn::Cloneable {</p>
<pre><code>int64_t input_size, hidden_size, hidden_size2, hidden_size3, output_size;
torch::nn::Linear i2h, h2h, h2h2, h2h3, h2o;
std::string name = "MyNet";


MyNetImpl(int64_t input_size, int64_t hidden_size, int64_t hidden_size2, int64_t hidden_size3, int64_t output_size) :
    i2h(register_module("i2h", torch::nn::Linear(input_size, hidden_size))),
    h2h(register_module("h2h", torch::nn::Linear(hidden_size, hidden_size2))),
    h2h2(register_module("h2h2", torch::nn::Linear(hidden_size2, hidden_size3))),
    h2h3(register_module("h2h3", torch::nn::Linear(hidden_size3, hidden_size3))),
    h2o(register_module("h2o", torch::nn::Linear(hidden_size3, output_size))) {
    
    this-&gt;input_size = input_size;
    this-&gt;hidden_size = hidden_size;
    this-&gt;hidden_size2 = hidden_size2;
    this-&gt;hidden_size3 = hidden_size3;

}
    
void reset() override {
    // Re-construct the layers
    i2h = torch::nn::Linear(input_size, hidden_size);
    h2h = torch::nn::Linear(hidden_size, hidden_size2);
    h2h2 = torch::nn::Linear(hidden_size2, hidden_size3);
    h2h3 = torch::nn::Linear(hidden_size3, hidden_size3);
    h2o = torch::nn::Linear(hidden_size3, output_size);

    // Re-register the layers to the module
    register_module("i2h", i2h);
    register_module("h2h", h2h);
    register_module("h2h2", h2h2);
    register_module("h2h3", h2h3);
    register_module("h2o", h2o);

}

torch::Tensor forward(torch::Tensor x1) {
    std::vector&lt;int64_t&gt; expected_size = { 29, 1, 4 };
    std::vector&lt;int64_t&gt; input_size = x1.sizes().vec();
  //  std::cout &lt;&lt; "Input tensor x1: " &lt;&lt; x1 &lt;&lt; std::endl;
    TORCH_CHECK(input_size == expected_size);
    
    //  torch::Tensor xi = torch::cat({ x1, x2, x3 }, 1);
   // std::cout &lt;&lt; "Input tensor x1: " &lt;&lt; x1 &lt;&lt; std::endl;
    torch::Tensor xm = torch::relu(i2h-&gt;forward(x1));
    //std::cout &lt;&lt; "Input tensor xm: " &lt;&lt; xm &lt;&lt; std::endl;
    torch::Tensor xm2 = torch::relu(h2h-&gt;forward(xm));
    torch::Tensor xm3 = torch::relu(h2h2-&gt;forward(xm2));
    torch::Tensor xo = torch::relu(h2h3-&gt;forward(xm3));
    //std::cout &lt;&lt; "Input tensor xo: " &lt;&lt; xo &lt;&lt; std::endl;
    torch::Tensor x = h2o-&gt;forward(xo);
    // std::cout &lt;&lt; "Input tensor x: " &lt;&lt; x &lt;&lt; std::endl;

    return x;
}
</code></pre>
<p>};<br>
TORCH_MODULE(MyNet);</p>
<p>And then try to use it with :</p>
<p>void ThreadHandler::cloneNet(MyNet extern_net)<br>
{<br>
m_net.lock();</p>
<pre><code>main_net-&gt;name = " main_net";
std::cout &lt;&lt; "cloning main "&lt;&lt;  main_net-&gt;name &lt;&lt; std::endl;
auto clone = main_net-&gt;clone();
std::shared_ptr&lt;MyNetImpl&gt; myNetImplPtr = std::dynamic_pointer_cast&lt;MyNetImpl&gt;(clone);
extern_net = MyNet(std::move(myNetImplPtr));
std::cout &lt;&lt; "cloned main " &lt;&lt; extern_net-&gt;name &lt;&lt; std::endl;
extern_net-&gt;name = "extern_net";
m_net.unlock();
</code></pre>
<p>}</p>
<p>The result is  a “Unhandled exception at 0x00007FFDC6BBCF19 in ClimaMultithreadedDebug.exe: Microsoft C++ exception: c10::Error at memory location 0x000000F3A8BBB6C0.”</p>
<p>Following the error code brought me to many forum thread here and else where a few say project settings are to cause but since I done everything human possible that they are correct.</p>
<p>So is this a bug or what is going on ?</p>