Emerging 2 different models to create a multi-model

username: tnguyen87
cooked: <p>Greetings,</p>
<p>I have 2 different models - A (GNN) and B (LSTM). I am trying to combine these models to predict the same output “y”. These models only share the same input and output only. I found 2 different posts (<a href="https://discuss.pytorch.org/t/merging-two-models/45637" class="inline-onebox">Merging two models</a> &amp; <a href="https://discuss.pytorch.org/t/combining-trained-models-in-pytorch/28383/2" class="inline-onebox">Combining Trained Models in PyTorch - #2 by ptrblck</a>) and noticed that they are different. I wonder which one would everyone recommend to follow.</p>
<p>About defining “optimizer = optim.X” where X can be SGD or Adam, if I follow the a post from <a class="mention" href="/u/ptrblck">@ptrblck</a> (Merging two models), then does “optimizer” need to be "optimizer = optim.Adam(modelA.parameters()+modelB.parameters()) ?</p>
<p>About the model.train(), would a post from <a class="mention" href="/u/ptrblck">@ptrblck</a> (Merging two models) take care? <code>loss.backward()</code> would depends on each model.</p>
<p>I have just started learning pytorch recently, so I am very new to this field. I’d really appreciate any input! Thank you for the help! - Tom</p>

username: ptrblck
cooked: <p>The linked use cases are a bit different as the first one (merging two models) seems to pass features from one model to the other and could train these models in an end2end manner.<br>
The “ensemble” approach uses two pretrained models to combine their output features (often from the penultimate layer) to train a new classifier, which could boost the performance compared to each model standalone. However, if you want to train all models from scratch, take a look at <a href="https://en.wikipedia.org/wiki/Ensemble_learning">the Stacking section</a> of <code>ensemble learning</code> as the training procedure is using “stages” and differs from the “standard” training routine.<br>
In particular the classifier expects the stage0 models to be trained already and expects to see their <em>predictions</em> while bein trained.<br>
This would mean that an end2end training might yield a worse performance and you would have to create separate training and validation splits to train each stage.</p>

username: tnguyen87
cooked: <p>Hello <a class="mention" href="/u/ptrblck">@ptrblck</a>, thank you for your thoughts and recommendations.</p>
<p>May I ask you for each scenario?</p>
<p>I did not think about the case where an end2end training can possibly yield a worse performance. Based on your comments, I think I will need to write an additional nn.Module class to combine 2 models as you showed in a post; but can I write it without passing features from one model to another? Also, do you have any suggestion on dealing with an optimizer and def train() function (what I am looking for is whether there is an additional step to write for optimizer and train(); I am stuck at looking for a way to deal with combining y_pred = mol(features_from_A) and y_pred = mol(features_from_B));  Because each model works well (but still not great), I want to boost a prediction performance by combining 2 models to predict output.</p>
<p>In a case the “ensemble” approach where I want to train 2 models from the scratch (based on your provided link) along with reading several papers observing authors combined their models (a type of models does not matter) at the FC layer. May I ask whether I still need to write a new “nn.Module class” to do this work?</p>

username: ptrblck
cooked: <aside class="quote no-group" data-username="tnguyen87" data-post="3" data-topic="146924">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/t/a698b9/48.png" class="avatar"> tnguyen87:</div>
<blockquote>
<p>but can I write it without passing features from one model to another?</p>
</blockquote>
</aside>
<p>Yes, you do not need to combine the “base models” together and could pass their features to a final classifier.</p>
<aside class="quote no-group" data-username="tnguyen87" data-post="3" data-topic="146924">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/t/a698b9/48.png" class="avatar"> tnguyen87:</div>
<blockquote>
<p>May I ask whether I still need to write a new “nn.Module class” to do this work?</p>
</blockquote>
</aside>
<p>Not necessarily, but a custom <code>nn.Module</code> might be more convenient.<br>
You can directly pass the outputs of any module to another module, e.g. as:</p>
<pre data-code-wrap="python"><code class="lang-python">modelA = MyModelA()
modelB = MyModelB()
classifer = MyClassifier()

outA = modelA(x)
outB = modelB(x)
out = torch.stack((outA, outB), dim=1)
out = classifier(out)
</code></pre>
<p>However, your code might be cleaner if you are wrapping this logic into a custom module.</p>

username: tnguyen87
cooked: <p>Wonderful! Thank you for a snippet code example. I will try this out to see which direction fits my approach better!</p>

username: tnguyen87
cooked: <p>Hello <a class="mention" href="/u/ptrblck">@ptrblck</a> ,<br>
May I ask whether outA is a predicted value obtained from model A in this case? I am think that outA is a feature at the fully-connected layer of model A; however, I am not quite sure. Could you please confirm whether it is correct?</p>
<p>Finally, I have two models (A&amp;B) are trained with different approaches (one with dataloader/bucketIteractor and another with a traditional batch). May I ask whether I need to use the same approach to train both models in order to stack their outputs for a combined model? I think that an answer might be no, but I still want to hear thoughts from an expert.</p>

username: tnguyen87
cooked: <p>Based on this link (<a href="https://discuss.pytorch.org/t/combining-trained-models-in-pytorch/28383/66" class="inline-onebox">Combining Trained Models in PyTorch - #66 by rudascience</a>), outA and outB are collected after FC layer. Because of this, my first question is answered.</p>
<p>Following with this post (<a href="https://discuss.pytorch.org/t/combining-trained-models-in-pytorch/28383/68" class="inline-onebox">Combining Trained Models in PyTorch - #68 by rudascience</a>), it seems like I only need to define an optimizer and push to <code>classifer.cuda()</code> for <code>classifer</code> instead for both 3 models (i.e., <code>modelA</code>, <code>modelB</code> and <code> classifier</code>) ? Is this true or am I missing something in the post?</p>

username: ptrblck
cooked: <p>You can define the models as you want, so can return the activation outputs (features) from the penultimate layer or the logit prediction.</p>
<p>For the optimizer: it also depends on your actual use case. If you want to only train the classifier, push only its parameters to the optimizer. On the other hand, if you want to train all models, use different optimizers, a combined one etc.</p>