.. _modules:

Modules
=======

PyTorch uses modules to represent neural networks. Modules are:

* **Building blocks of stateful computation.**
  PyTorch provides a robust library of modules and makes it simple to define new custom modules, allowing for
  easy construction of elaborate, multi-layer neural networks.
* **Tightly integrated with PyTorch's**
  `autograd <https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html>`_
  **system.** Modules make it simple to specify learnable parameters for PyTorch's Optimizers to update.
* **Easy to work with and transform.** Modules are straightforward to save and restore, transfer between
  CPU / GPU / TPU devices, prune, quantize, and more.

This note describes modules, and is intended for all PyTorch users. Since modules are so fundamental to PyTorch,
many topics in this note are elaborated on in other notes or tutorials, and links to many of those documents
are provided here as well.

.. contents:: :local:

A Simple Custom Module
----------------------

To get started, let's look at a simpler, custom version of PyTorch's :class:`~torch.nn.Linear` module.
This module applies an affine transformation to its input.

.. code-block:: python

   import torch
   from torch import nn

   class MyLinear(nn.Module):
     def __init__(self, in_features, out_features):
       super().__init__()
       self.weight = nn.Parameter(torch.randn(in_features, out_features))
       self.bias = nn.Parameter(torch.randn(out_features))

     def forward(self, input):
       return (input @ self.weight) + self.bias

This simple module has the following fundamental characteristics of modules:

* **It inherits from the base Module class.**
  All modules should subclass :class:`~torch.nn.Module` for composability with other modules.
* **It defines some "state" that is used in computation.**
  Here, the state consists of randomly-initialized ``weight`` and ``bias`` tensors that define the affine
  transformation. Because each of these is defined as a :class:`~torch.nn.parameter.Parameter`, they are
  *registered* for the module and will automatically be tracked and returned from calls
  to :func:`~torch.nn.Module.parameters`. Parameters can be
  considered the "learnable" aspects of the module's computation (more on this later). Note that modules
  are not required to have state, and can also be stateless.
* **It defines a forward() function that performs the computation.** For this affine transformation module, the input
  is matrix-multiplied with the ``weight`` parameter (using the ``@`` short-hand notation) and added to the ``bias``
  parameter to produce the output. More generally, the ``forward()`` implementation for a module can perform arbitrary
  computation involving any number of inputs and outputs.

This simple module demonstrates how modules package state and computation together. Instances of this module can be
constructed and called:

.. code-block:: python

   m = MyLinear(4, 3)
   sample_input = torch.randn(4)
   m(sample_input)
   : tensor([-0.3037, -1.0413, -4.2057], grad_fn=<AddBackward0>)

Note that the module itself is callable, and that calling it invokes its ``forward()`` function.
This name is in reference to the concepts of "forward pass" and "backward pass", which apply to each module.
The "forward pass" is responsible for applying the computation represented by the module
to the given input(s) (as shown in the above snippet). The "backward pass" computes gradients of
module outputs with respect to its inputs, which can be used for "training" parameters through gradient
descent methods. PyTorch's autograd system automatically takes care of this backward pass computation, so it
is not required to manually implement a ``backward()`` function for each module. The process of training
module parameters through successive forward / backward passes is covered in detail in
:ref:`Neural Network Training with Modules`.

The full set of parameters registered by the module can be iterated through via a call to
:func:`~torch.nn.Module.parameters` or :func:`~torch.nn.Module.named_parameters`,
where the latter includes each parameter's name:

.. code-block:: python

   for parameter in m.named_parameters():
     print(parameter)
   : ('weight', Parameter containing:
   tensor([[ 1.0597,  1.1796,  0.8247],
           [-0.5080, -1.2635, -1.1045],
           [ 0.0593,  0.2469, -1.4299],
           [-0.4926, -0.5457,  0.4793]], requires_grad=True))
   ('bias', Parameter containing:
   tensor([ 0.3634,  0.2015, -0.8525], requires_grad=True))

In general, the parameters registered by a module are aspects of the module's computation that should be
"learned". A later section of this note shows how to update these parameters using one of PyTorch's Optimizers.
Before we get to that, however, let's first examine how modules can be composed with one another.

Modules as Building Blocks
--------------------------

Modules can contain other modules, making them useful building blocks for developing more elaborate functionality.
The simplest way to do this is using the :class:`~torch.nn.Sequential` module. It allows us to chain together
multiple modules:

.. code-block:: python

   net = nn.Sequential(
     MyLinear(4, 3),
     nn.ReLU(),
     MyLinear(3, 1)
   )

   sample_input = torch.randn(4)
   net(sample_input)
   : tensor([-0.6749], grad_fn=<AddBackward0>)

Note that :class:`~torch.nn.Sequential` automatically feeds the output of the first ``MyLinear`` module as input
into the :class:`~torch.nn.ReLU`, and the output of that as input into the second ``MyLinear`` module. As
shown, it is limited to in-order chaining of modules with a single input and output.

In general, it is recommended to define a custom module for anything beyond the simplest use cases, as this gives
full flexibility on how submodules are used for a module's computation.

For example, here's a simple neural network implemented as a custom module:

.. code-block:: python

   import torch.nn.functional as F

   class Net(nn.Module):
     def __init__(self):
       super().__init__()
       self.l0 = MyLinear(4, 3)
       self.l1 = MyLinear(3, 1)
     def forward(self, x):
       x = self.l0(x)
       x = F.relu(x)
       x = self.l1(x)
       return x

This module is composed of two "children" or "submodules" (\ ``l0`` and ``l1``\ ) that define the layers of
the neural network and are utilized for computation within the module's ``forward()`` method. Immediate
children of a module can be iterated through via a call to :func:`~torch.nn.Module.children` or
:func:`~torch.nn.Module.named_children`:

.. code-block:: python

   net = Net()
   for child in net.named_children():
     print(child)
   : ('l0', MyLinear())
   ('l1', MyLinear())

To go deeper than just the immediate children, :func:`~torch.nn.Module.modules` and
:func:`~torch.nn.Module.named_modules` *recursively* iterate through a module and its child modules:

.. code-block:: python

   class BigNet(nn.Module):
     def __init__(self):
       super().__init__()
       self.l1 = MyLinear(5, 4)
       self.net = Net()
     def forward(self, x):
       return self.net(self.l1(x))

   big_net = BigNet()
   for module in big_net.named_modules():
     print(module)
   : ('', BigNet(
     (l1): MyLinear()
     (net): Net(
       (l0): MyLinear()
       (l1): MyLinear()
     )
   ))
   ('l1', MyLinear())
   ('net', Net(
     (l0): MyLinear()
     (l1): MyLinear()
   ))
   ('net.l0', MyLinear())
   ('net.l1', MyLinear())

Sometimes, it's necessary for a module to dynamically define submodules.
The :class:`~torch.nn.ModuleList` and :class:`~torch.nn.ModuleDict` modules are useful here; they
register submodules from a list or dict:

.. code-block:: python

   class DynamicNet(nn.Module):
     def __init__(self, num_layers):
       super().__init__()
       self.linears = nn.ModuleList(
         [MyLinear(4, 4) for _ in range(num_layers)])
       self.activations = nn.ModuleDict({
         'relu': nn.ReLU(),
         'lrelu': nn.LeakyReLU()
       })
       self.final = MyLinear(4, 1)
     def forward(self, x, act):
       for linear in self.linears:
         x = linear(x)
       x = self.activations[act](x)
       x = self.final(x)
       return x

   dynamic_net = DynamicNet(3)
   sample_input = torch.randn(4)
   output = dynamic_net(sample_input, 'relu')

For any given module, its parameters consist of its direct parameters as well as the parameters of all submodules.
This means that calls to :func:`~torch.nn.Module.parameters` and :func:`~torch.nn.Module.named_parameters` will
recursively include child parameters, allowing for convenient optimization of all parameters within the network:

.. code-block:: python

   for parameter in dynamic_net.named_parameters():
     print(parameter)
   : ('linears.0.weight', Parameter containing:
   tensor([[-1.2051,  0.7601,  1.1065,  0.1963],
           [ 3.0592,  0.4354,  1.6598,  0.9828],
           [-0.4446,  0.4628,  0.8774,  1.6848],
           [-0.1222,  1.5458,  1.1729,  1.4647]], requires_grad=True))
   ('linears.0.bias', Parameter containing:
   tensor([ 1.5310,  1.0609, -2.0940,  1.1266], requires_grad=True))
   ('linears.1.weight', Parameter containing:
   tensor([[ 2.1113, -0.0623, -1.0806,  0.3508],
           [-0.0550,  1.5317,  1.1064, -0.5562],
           [-0.4028, -0.6942,  1.5793, -1.0140],
           [-0.0329,  0.1160, -1.7183, -1.0434]], requires_grad=True))
   ('linears.1.bias', Parameter containing:
   tensor([ 0.0361, -0.9768, -0.3889,  1.1613], requires_grad=True))
   ('linears.2.weight', Parameter containing:
   tensor([[-2.6340, -0.3887, -0.9979,  0.0767],
           [-0.3526,  0.8756, -1.5847, -0.6016],
           [-0.3269, -0.1608,  0.2897, -2.0829],
           [ 2.6338,  0.9239,  0.6943, -1.5034]], requires_grad=True))
   ('linears.2.bias', Parameter containing:
   tensor([ 1.0268,  0.4489, -0.9403,  0.1571], requires_grad=True))
   ('final.weight', Parameter containing:
   tensor([[ 0.2509], [-0.5052], [ 0.3088], [-1.4951]], requires_grad=True))
   ('final.bias', Parameter containing:
   tensor([0.3381], requires_grad=True))

It's also easy to move all parameters to a different device or change their precision using
:func:`~torch.nn.Module.to`:

.. code-block:: python

   # Move all parameters to a CUDA device
   dynamic_net.to(device='cuda')

   # Change precision of all parameters
   dynamic_net.to(dtype=torch.float64)

   dynamic_net(torch.randn(5, device='cuda', dtype=torch.float64))
   : tensor([6.5166], device='cuda:0', dtype=torch.float64, grad_fn=<AddBackward0>)

More generally, an arbitrary function can be applied to a module and its submodules recursively by
using the :func:`~torch.nn.Module.apply` function. For example, to apply custom initialization to parameters
of a module and its submodules:

.. code-block:: python

   # Define a function to initialize Linear weights.
   # Note that no_grad() is used here to avoid tracking this computation in the autograd graph.
   @torch.no_grad()
   def init_weights(m):
     if isinstance(m, nn.Linear):
       nn.init.xavier_normal_(m.weight)
       m.bias.fill_(0.0)

   # Apply the function recursively on the module and its submodules.
   dynamic_net.apply(init_weights)

These examples show how elaborate neural networks can be formed through module composition and conveniently
manipulated. To allow for quick and easy construction of neural networks with minimal boilerplate, PyTorch
provides a large library of performant modules within the :mod:`torch.nn` namespace that perform common neural
network operations like pooling, convolutions, loss functions, etc.

In the next section, we give a full example of training a neural network.

For more information, check out:

* Library of PyTorch-provided modules: `torch.nn <https://pytorch.org/docs/stable/nn.html>`_
* Defining neural net modules: https://pytorch.org/tutorials/beginner/examples_nn/polynomial_module.html

.. _Neural Network Training with Modules:

Neural Network Training with Modules
------------------------------------

Once a network is built, it has to be trained, and its parameters can be easily optimized with one of PyTorch’s
Optimizers from :mod:`torch.optim`:

.. code-block:: python

   # Create the network (from previous section) and optimizer
   net = Net()
   optimizer = torch.optim.SGD(net.parameters(), lr=1e-4, weight_decay=1e-2, momentum=0.9)

   # Run a sample training loop that "teaches" the network
   # to output the constant zero function
   for _ in range(10000):
     input = torch.randn(4)
     output = net(input)
     loss = torch.abs(output)
     net.zero_grad()
     loss.backward()
     optimizer.step()

   # After training, switch the module to eval mode to do inference, compute performance metrics, etc.
   # (see discussion below for a description of training and evaluation modes)
   ...
   net.eval()
   ...

In this simplified example, the network learns to simply output zero, as any non-zero output is "penalized" according
to its absolute value by employing :func:`torch.abs` as a loss function. While this is not a very interesting task, the
key parts of training are present:

* A network is created.
* An optimizer (in this case, a stochastic gradient descent optimizer) is created, and the network’s
  parameters are associated with it.
* A training loop...
    * acquires an input,
    * runs the network,
    * computes a loss,
    * zeros the network’s parameters’ gradients,
    * calls loss.backward() to update the parameters’ gradients,
    * calls optimizer.step() to apply the gradients to the parameters.

After the above snippet has been run, note that the network's parameters have changed. In particular, examining the
value of ``l1``\ 's ``weight`` parameter shows that its values are now much closer to 0 (as may be expected):

.. code-block:: python

   print(net.l1.weight)
   : Parameter containing:
   tensor([[-0.0013],
           [ 0.0030],
           [-0.0008]], requires_grad=True)

Note that the above process is done entirely while the network module is in "training mode". Modules default to
training mode and can be switched between training and evaluation modes using :func:`~torch.nn.Module.train` and
:func:`~torch.nn.Module.eval`. They can behave differently depending on which mode they are in. For example, the
:class:`~torch.nn.BatchNorm` module maintains a running mean and variance during training that are not updated
when the module is in evaluation mode. In general, modules should be in training mode during training
and only switched to evaluation mode for inference or evaluation. Below is an example of a custom module
that behaves differently between the two modes:

.. code-block:: python

   class ModalModule(nn.Module):
     def __init__(self):
       super().__init__()

     def forward(self, x):
       if self.training:
         # Add a constant only in training mode.
         return x + 1.
       else:
         return x


   m = ModalModule()
   x = torch.randn(4)

   print('training mode output: {}'.format(m(x)))
   : tensor([1.6614, 1.2669, 1.0617, 1.6213, 0.5481])

   m.eval()
   print('evaluation mode output: {}'.format(m(x)))
   : tensor([ 0.6614,  0.2669,  0.0617,  0.6213, -0.4519])

Training neural networks can often be tricky. For more information, check out:

* Using Optimizers: https://pytorch.org/tutorials/beginner/examples_nn/two_layer_net_optim.html.
* Neural network training: https://pytorch.org/tutorials/beginner/blitz/neural_networks_tutorial.html
* Introduction to autograd: https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html

Module State
------------

In the previous section, we demonstrated training a module's "parameters", or learnable aspects of computation.
Now, if we want to save the trained model to disk, we can do so by saving its ``state_dict`` (i.e. "state dictionary"):

.. code-block:: python

   # Save the module
   torch.save(net.state_dict(), 'net.pt')

   ...

   # Load the module later on
   new_net = Net()
   new_net.load_state_dict(torch.load('net.pt'))
   : <All keys matched successfully>

A module's ``state_dict`` contains state that affects its computation. This includes, but is not limited to, the
module's parameters. For some modules, it may be useful to have state beyond parameters that affects module
computation but is not learnable. For such cases, PyTorch provides the concept of "buffers", both "persistent"
and "non-persistent". Following is an overview of the various types of state a module can have:

* **Parameters**\ : learnable aspects of computation; contained within the ``state_dict``
* **Buffers**\ : non-learnable aspects of computation

  * **Persistent** buffers: contained within the ``state_dict`` (i.e. serialized when saving & loading)
  * **Non-persistent** buffers: not contained within the ``state_dict`` (i.e. left out of serialization)

As a motivating example for the use of buffers, consider a simple module that maintains a running mean. We want
the current value of the running mean to be considered part of the module's ``state_dict`` so that it will be
restored when loading a serialized form of the module, but we don't want it to be learnable.
This snippet shows how to use :func:`~torch.nn.Module.register_buffer` to accomplish this:

.. code-block:: python

   class RunningMean(nn.Module):
     def __init__(self, num_features, momentum=0.9):
       super().__init__()
       self.momentum = momentum
       self.register_buffer('mean', torch.zeros(num_features))
     def forward(self, x):
       self.mean = self.momentum * self.mean + (1.0 - self.momentum) * x
       return self.mean

Now, the current value of the running mean is considered part of the module's ``state_dict``
and will be properly restored when loading the module from disk:

.. code-block:: python

   m = RunningMean(4)
   for _ in range(10):
     input = torch.randn(4)
     m(input)

   print(m.state_dict())
   : OrderedDict([('mean', tensor([ 0.1041, -0.1113, -0.0647,  0.1515]))]))

   # Serialized form will contain the 'mean' tensor
   torch.save(m.state_dict(), 'mean.pt')

   m_loaded = RunningMean(4)
   m_loaded.load_state_dict(torch.load('mean.pt'))
   assert(torch.all(m.mean == m_loaded.mean))

As mentioned previously, buffers can be left out of the module's ``state_dict`` by marking them as non-persistent:

.. code-block:: python

   self.register_buffer('unserialized_thing', torch.randn(5), persistent=False)

Both persistent and non-persistent buffers are affected by model-wide device / dtype changes applied with
:func:`~torch.nn.Module.to`:

.. code-block:: python

   # Moves all module parameters and buffers to the specified device / dtype
   m.to(device='cuda', dtype=torch.float64)

Buffers of a module can be iterated over using :func:`~torch.nn.Module.buffers` or
:func:`~torch.nn.Module.named_buffers`.

.. code-block:: python

   for buffer in m.named_buffers():
     print(buffer)

The following class demonstrates the various ways of registering parameters and buffers within a module:

.. code-block:: python

   class StatefulModule(nn.Module):
     def __init__(self):
       super().__init__()
       # Setting a nn.Parameter as an attribute of the module automatically registers the tensor
       # as a parameter of the module.
       self.param1 = nn.Parameter(torch.randn(2))

       # Alternative string-based way to register a parameter.
       self.register_parameter('param2', nn.Parameter(torch.randn(3)))

       # Reserves the "param3" attribute as a parameter, preventing it from being set to anything
       # except a parameter. "None" entries like this will not be present in the module's state_dict.
       self.register_parameter('param3', None)

       # Registers a list of parameters.
       self.param_list = nn.ParameterList([nn.Parameter(torch.randn(2)) for i in range(3)])

       # Registers a dictionary of parameters.
       self.param_dict = nn.ParameterDict({
         'foo': nn.Parameter(torch.randn(3)),
         'bar': nn.Parameter(torch.randn(4))
       })

       # Registers a persistent buffer (one that appears in the module's state_dict).
       self.register_buffer('buffer1', torch.randn(4), persistent=True)

       # Registers a non-persistent buffer (one that does not appear in the module's state_dict).
       self.register_buffer('buffer2', torch.randn(5), persistent=False)

       # Reserves the "buffer3" attribute as a buffer, preventing it from being set to anything
       # except a buffer. "None" entries like this will not be present in the module's state_dict.
       self.register_buffer('buffer3', None)

       # Adding a submodule registers its parameters as parameters of the module.
       self.linear = nn.Linear(2, 3)

   m = StatefulModule()

   # Save and load state_dict.
   torch.save(m.state_dict(), 'state.pt')
   m_loaded = StatefulModule()
   m_loaded.load_state_dict(torch.load('state.pt'))

   # Note that non-persistent buffer "buffer2" and reserved attributes "param3" and "buffer3" do
   # not appear in the state_dict.
   print(m_loaded.state_dict())
   : OrderedDict([('param1', tensor([-0.0322,  0.9066])),
                  ('param2', tensor([-0.4472,  0.1409,  0.4852])),
                  ('buffer1', tensor([ 0.6949, -0.1944,  1.2911, -2.1044])),
                  ('param_list.0', tensor([ 0.4202, -0.1953])),
                  ('param_list.1', tensor([ 1.5299, -0.8747])),
                  ('param_list.2', tensor([-1.6289,  1.4898])),
                  ('param_dict.bar', tensor([-0.6434,  1.5187,  0.0346, -0.4077])),
                  ('param_dict.foo', tensor([-0.0845, -1.4324,  0.7022])),
                  ('linear.weight', tensor([[-0.3915, -0.6176],
                                            [ 0.6062, -0.5992],
                                            [ 0.4452, -0.2843]])),
                  ('linear.bias', tensor([-0.3710, -0.0795, -0.3947]))])

For more information, check out:

* Saving and loading: https://pytorch.org/tutorials/beginner/saving_loading_models.html
* Serialization semantics: https://pytorch.org/docs/master/notes/serialization.html
* What is a state dict? https://pytorch.org/tutorials/recipes/recipes/what_is_state_dict.html

Module Initialization
---------------------

By default, parameters and floating-point buffers for modules provided by :mod:`torch.nn` are initialized during
module instantiation as 32-bit floating point values on the CPU using an initialization scheme determined to
perform well historically for the module type. For certain use cases, it may be desired to initialize with a different
dtype, device (e.g. GPU), or initialization technique.

Examples:

.. code-block:: python

   # Initialize module directly onto GPU.
   m = nn.Linear(5, 3, device='cuda')

   # Initialize module with 16-bit floating point parameters.
   m = nn.Linear(5, 3, dtype=torch.half)

   # Skip default parameter initialization and perform custom (e.g. orthogonal) initialization.
   m = torch.nn.utils.skip_init(nn.Linear, 5, 3)
   nn.init.orthogonal_(m.weight)

Note that the device and dtype options demonstrated above also apply to any floating-point buffers registered
for the module:

.. code-block:: python

   m = nn.BatchNorm2d(3, dtype=torch.half)
   print(m.running_mean)
   : tensor([0., 0., 0.], dtype=torch.float16)

While module writers can use any device or dtype to initialize parameters in their custom modules, good practice is
to use ``dtype=torch.float`` and ``device='cpu'`` by default as well. Optionally, you can provide full flexibility
in these areas for your custom module by conforming to the convention demonstrated above that all
:mod:`torch.nn` modules follow:

* Provide a ``device`` constructor kwarg that applies to any parameters / buffers registered by the module.
* Provide a ``dtype`` constructor kwarg that applies to any parameters / floating-point buffers registered by
  the module.
* Only use initialization functions (i.e. functions from :mod:`torch.nn.init`) on parameters and buffers within the
  module's constructor. Note that this is only required to use :func:`~torch.nn.utils.skip_init`; see
  `this page <https://pytorch.org/tutorials/prototype/skip_param_init.html#updating-modules-to-support-skipping-initialization>`_ for an explanation.

For more information, check out:

* Skipping module parameter initialization: https://pytorch.org/tutorials/prototype/skip_param_init.html

Module Hooks
------------

In :ref:`Neural Network Training with Modules`, we demonstrated the training process for a module, which iteratively
performs forward and backward passes, updating module parameters each iteration. For more control
over this process, PyTorch provides "hooks" that can perform arbitrary computation during a forward or backward
pass, even modifying how the pass is done if desired. Some useful examples for this functionality include
debugging, visualizing activations, examining gradients in-depth, etc. Hooks can be added to modules
you haven't written yourself, meaning this functionality can be applied to third-party or PyTorch-provided modules.

PyTorch provides two types of hooks for modules:

* **Forward hooks** are called during the forward pass. They can be installed for a given module with
  :func:`~torch.nn.Module.register_forward_pre_hook` and :func:`~torch.nn.Module.register_forward_hook`.
  These hooks will be called respectively just before the forward function is called and just after it is called.
  Alternatively, these hooks can be installed globally for all modules with the analagous
  :func:`~torch.nn.modules.module.register_module_forward_pre_hook` and
  :func:`~torch.nn.modules.module.register_module_forward_hook` functions.
* **Backward hooks** are called during the backward pass. They can be installed with
  :func:`~torch.nn.Module.register_full_backward_hook`. These hooks will be called when the backward for this
  Module has been computed and will allow the user to access the gradients for both the inputs and outputs.
  Alternatively, they can be installed globally for all modules with
  :func:`~torch.nn.modules.module.register_module_full_backward_hook`.

All hooks allow the user to return an updated value that will be used throughout the remaining computation.
Thus, these hooks can be used to either execute arbitrary code along the regular module forward/backward or
modify some inputs/outputs without having to change the module's ``forward()`` function.

Below is an example demonstrating usage of forward and backward hooks:

.. code-block:: python

   torch.manual_seed(1)

   def forward_pre_hook(m, inputs):
     # Allows for examination and modification of the input before the forward pass.
     # Note that inputs are always wrapped in a tuple.
     input = inputs[0]
     return input + 1.

   def forward_hook(m, inputs, output):
     # Allows for examination of inputs / outputs and modification of the outputs
     # after the forward pass. Note that inputs are always wrapped in a tuple while outputs
     # are passed as-is.

     # Residual computation a la ResNet.
     return output + inputs[0]

   def backward_hook(m, grad_inputs, grad_outputs):
     # Allows for examination of grad_inputs / grad_outputs and modification of
     # grad_inputs used in the rest of the backwards pass. Note that grad_inputs and
     # grad_outputs are always wrapped in tuples.
     new_grad_inputs = [torch.ones_like(gi) * 42. for gi in grad_inputs]
     return new_grad_inputs

   # Create sample module & input.
   m = nn.Linear(3, 3)
   x = torch.randn(2, 3, requires_grad=True)

   # ==== Demonstrate forward hooks. ====
   # Run input through module before and after adding hooks.
   print('output with no forward hooks: {}'.format(m(x)))
   : output with no forward hooks: tensor([[-0.5059, -0.8158,  0.2390],
                                           [-0.0043,  0.4724, -0.1714]], grad_fn=<AddmmBackward>)

   # Note that the modified input results in a different output.
   forward_pre_hook_handle = m.register_forward_pre_hook(forward_pre_hook)
   print('output with forward pre hook: {}'.format(m(x)))
   : output with forward pre hook: tensor([[-0.5752, -0.7421,  0.4942],
                                           [-0.0736,  0.5461,  0.0838]], grad_fn=<AddmmBackward>)

   # Note the modified output.
   forward_hook_handle = m.register_forward_hook(forward_hook)
   print('output with both forward hooks: {}'.format(m(x)))
   : output with both forward hooks: tensor([[-1.0980,  0.6396,  0.4666],
                                             [ 0.3634,  0.6538,  1.0256]], grad_fn=<AddBackward0>)

   # Remove hooks; note that the output here matches the output before adding hooks.
   forward_pre_hook_handle.remove()
   forward_hook_handle.remove()
   print('output after removing forward hooks: {}'.format(m(x)))
   : output after removing forward hooks: tensor([[-0.5059, -0.8158,  0.2390],
                                                  [-0.0043,  0.4724, -0.1714]], grad_fn=<AddmmBackward>)

   # ==== Demonstrate backward hooks. ====
   m(x).sum().backward()
   print('x.grad with no backwards hook: {}'.format(x.grad))
   : x.grad with no backwards hook: tensor([[ 0.4497, -0.5046,  0.3146],
                                            [ 0.4497, -0.5046,  0.3146]])

   # Clear gradients before running backward pass again.
   m.zero_grad()
   x.grad.zero_()

   m.register_full_backward_hook(backward_hook)
   m(x).sum().backward()
   print('x.grad with backwards hook: {}'.format(x.grad))
   : x.grad with backwards hook: tensor([[42., 42., 42.],
                                         [42., 42., 42.]])

Advanced Features
-----------------

PyTorch also provides several more advanced features that are designed to work with modules. All these functionalities
are available for custom-written modules, with the small caveat that certain features may require modules to conform
to particular constraints in order to be supported. In-depth discussion of these features and the corresponding
requirements can be found in the links below.

Distributed Training
********************

Various methods for distributed training exist within PyTorch, both for scaling up training using multiple GPUs
as well as training across multiple machines. Check out the
`distributed training overview page <https://pytorch.org/tutorials/beginner/dist_overview.html>`_ for
detailed information on how to utilize these.

Profiling Performance
*********************

The `PyTorch Profiler <https://pytorch.org/tutorials/beginner/profiler.html>`_ can be useful for identifying
performance bottlenecks within your models. It measures and outputs performance characteristics for
both memory usage and time spent.

Improving Performance with Quantization
***************************************

Applying quantization techniques to modules can improve performance and memory usage by utilizing lower
bitwidths than floating-point precision. Check out the various PyTorch-provided mechanisms for quantization
`here <https://pytorch.org/docs/stable/quantization.html>`_.

Improving Memory Usage with Pruning
***********************************

Large deep learning models are often over-parametrized, resulting in high memory usage. To combat this, PyTorch
provides mechanisms for model pruning, which can help reduce memory usage while maintaining task accuracy. The
`Pruning tutorial <https://pytorch.org/tutorials/intermediate/pruning_tutorial.html>`_ describes how to utilize
the pruning techniques PyTorch provides or define custom pruning techniques as necessary.

Deploying with TorchScript
**************************

When deploying a model for use in production, the overhead of Python can be unacceptable due to its poor
performance characteristics. For cases like this,
`TorchScript <https://pytorch.org/tutorials/beginner/Intro_to_TorchScript_tutorial.html>`_ provides a way to load
and run an optimized model program from outside of Python, such as within a C++ program.

Parametrizations
****************

For certain applications, it can be beneficial to constrain the parameter space during model training. For example,
enforcing orthogonality of the learned parameters can improve convergence for RNNs. PyTorch provides a mechanism for
applying `parametrizations <https://pytorch.org/tutorials/intermediate/parametrizations.html>`_ such as this, and
further allows for custom constraints to be defined.

Transforming Modules with FX
****************************

The `FX <https://pytorch.org/docs/stable/fx.html>`_ component of PyTorch provides a flexible way to transform
modules by operating directly on module computation graphs. This can be used to programmatically generate or
manipulate modules for a broad array of use cases. To explore FX, check out these examples of using FX for
`convolution + batch norm fusion <https://pytorch.org/tutorials/intermediate/fx_conv_bn_fuser.html>`_ and
`CPU performance analysis <https://pytorch.org/tutorials/intermediate/fx_profiling_tutorial.html>`_.
