Max pooling encoder
State: closed | Pull request: yes

This PR introduces a max-pooling and average-pooling encoders.
Each block halves the steps of the encoder using max pooling / average pooling over steps dimension.

In addition, a control parameter `MTBottleneckModel.deterministic_translate` can be used for deterministic translation for VAE and MIM ( i.w., using the mean of latent code instead a sample). This change affects all bottleneck encoders. Default behaviour is on.

# YAML Configuration

The following configurations in YAML config allows to control the learning framework and architecture:

```
model:
...
  encoder:
    library: nemo
    ...
    arch: max_pool # avg_pool (NEW), max_pool (NEW), seq2seq, bridge, perceiver (see description above)
    hidden_steps: 32 # fixed number of hidden steps for bottleneck, minimal steps for reduction otherwise
    hidden_blocks: 1 # number of repeat blocks (see classes for description)
    hidden_init_method: default # see classes for available values
```

Detailed description of config parameters:

* **model.encoder.arch=avg_pool** `<== NEW`
    * *model.encoder.hidden_steps:* minimal number of steps to halve (must be > 2) 
    * *model.encoder.hidden_blocks:* number of (encoder + average pooling)  blocks to repeat (each encoder with `num_layers` layers)
    * *model.encoder.hidden_init_method:*
         *  default - must be `default`
* **model.encoder.arch=max_pool** `<== NEW`
    * *model.encoder.hidden_steps:* minimal number of steps to halve (must be > 2) 
    * *model.encoder.hidden_blocks:* number of (encoder + max pooling)  blocks to repeat (each encoder with `num_layers` layers)
    * *model.encoder.hidden_init_method:*
         *  default - must be `default`
* **model.encoder.arch=seq2seq**
    * *model.encoder.hidden_steps is ignored*
    * *model.encoder.hidden_blocks is ignored*
    * *model.encoder.hidden_init_method is ignored*
* **model.encoder.arch=bridge**
    * *model.encoder.hidden_steps:* input is projected to the specified fixed steps 
    * *model.encoder.hidden_blocks:* number of encoder blocks to repeat after attention bridge projection
    * *model.encoder.hidden_init_method:*
         *  enc_shared (default) - apply encoder to inputs, than attention bridge, followed by hidden_blocks number of the same encoder (pre and post encoders share parameters)
         * identity - apply attention bridge to inputs, followed by hidden_blocks number of the same encoder
         * enc - similar to enc_shared but the initial encoder has independent parameters
* **model.encoder.arch=perceiver**
    * *model.encoder.hidden_steps:* input is projected to the specified fixed steps 
    * *model.encoder.hidden_blocks:* number of cross-attention + self-attention blocks to repeat after initialization block (all self-attention and cross-attention share parameters)
    * *model.encoder.hidden_init_method:*
         * params (default) - hidden state is initialized with learned parameters followed by cross-attention with independent parameters
         * bridge - hidden state is initialized with an attention bridge

# Usage Example

**NOTE:** ```enc_dec_nmt-bottleneck.py``` must be used. ```enc_dec_nmt.py``` does not support the required configuration to run properly and will likely fail.

```
python -- enc_dec_nmt-bottleneck.py \
      --config-path=conf \
      --config-name=aayn_bottleneck \
      ...
      model.model_type=nll \
      model.non_recon_warmup_batches=7500 \
      model.encoder.arch=max_pool \
      model.encoder.hidden_steps=32 \
      model.encoder.hidden_blocks=2 \
      model.encoder.hidden_init_method=default \
      ...
```

# Additional Info

* Classes *MaxPoolingEncoder* and *AveragePoolingEncoder* was added to ```nemo/collections/nlp/modules/common/transformer/reduction_encoders.py```