Repository: pytorch
Issue: Optimizer warning when parameters "change"
Labels: module: optimizer,triaged,enhancement

## 🚀 Feature
I vote for a slight change in the architecture of the 'communication' between the optimizer and the actual model. The optimizer should know the parameters of the 'actual' model and if the parameters the optimizer knows about do not match the ones of the model then it should spit out an error or at least a warning. Also when trying to interpret the setup of the optimizer one does not get the names of the parameters the optimizer works on... it should remember that as well.

## Motivation

I played around with a simple RNN for learning the 'bracket language', i.e. valid expressions involving the start symbol '<', the end symbol '>', normal characters 'a','b','c' and brackets '(' and ')'. A word is valid if it starts with '<', ends in '>' and every opening bracket has a matching closing bracket. Example: <aab()c((c)ba)> is valid while <<aa()>, (), <aa(b> are not. I played around with different infrastructures (with memory, without memory, etc) so at first I created different classes for the different infrastructures. Then I came to realise that much of the code is being repeated. That is not good. So I refactored a little bit: I created an RNN class that just leaves the "forwardFancaShmancyStuff()" function unimplemented, i.e. it looked like this (pseudo code):

```
class RNN(torch.nn):
  def __init__(self, hiddenSize, ...):
    # translate a single character integer 0=<,1=>,2=a,...,7=) into real vectors
    # that we can put into GRU or any other fanca-shmancy stuff
    self.encoder = nn.Embedding(7, hiddenSize)
    # turn hidenSize-vectors into vectors of length of the alphabet in order to sample
    # next character
    self.decoder = nn.Linear(hiddenSize, 7)
    self.optimizer = torch.optim.Adadelta(self.parameters(), lr=someLearningRate)

  def fit(...):
    # train

  def sample(...):
    # sample a new word

  def forward(...):
    # apply self.encoder
    self.forwardFancaShmancyStuff(...)
    # apply decoder and return

  def forwardFancaShmancyStuff(...)
    # not implemented
```

Every new infrastructure I wanted to try out was then just inheriting everything from RNN and was just implementing "forwardFancaShmancyStuff()".

**All of a sudden the performance of the models dropped from 90% valid expressions to 50% valid expressions although I did not change a single thing (same training set, same hyperparameters, same random seeding... literally everything was exactly the same), I just refactored the code!!! How can that be??**

So I searched for quite some time. The reason is that in the inheriting class there are new parameters being created like this:

```
class VaniallaGRU(RNN):
  def __init__(...):
    call super constructor in order to setup encoder and decoder
    self.gru = torch.nn.GRU(hiddenSize, hiddenSize, amountLayers)

  def forwardFancaShmancyStuff(...):
    call gru
```

However, when calling "fit()" now then the optimizer was created at the time the superclass (RNN) has been created and *not* within "VaniallaGRU", i.e. the optimizer will now silently optimize only the encoder and the decoder but not the GRU and that was causing the extreme drop in performance.

## Pitch

In the setting above where one develops NN architectures in a clean software architectural way the optimizer should check whether the models parameters are the same as the ones when it was initialized. If not (as is the case above) then it should respond with an error or at least a warning like "Warning: optimizer will not optimize all parameters of the neural net". One could also introduce a parameter like "warnIfNotAllParamsAreOptimized=True" which one can set to False deliberately in order to allow that (maybe one loads a complicated old model and just wants to retrain a part of it).

## Alternatives

One could clearly reinitialize or re-setup the optimizer in every class that inherits from RNN. However, one tends to forget that :-)

## Additional context

None.

cc @vincentqb @iramazanli