docs: def _instantiate_layers(self):
      """Instantiates all the linear modules used in the network.
  
      Layers are instantiated in the constructor, as opposed to the build
      function, because MLP implements the Transposable interface, and the
      transpose function can be called before the module is actually connected
      to the graph and build is called.
  
      Notice that this is safe since layers in the transposed module are
      instantiated using a lambda returning input_size of the mlp layers, and
      this doesn't have to return sensible values until the original module is
      connected to the graph.
      """
  
      # Here we are entering the module's variable scope to name our submodules
      # correctly (not to create variables). As such it's safe to not check
      # whether we're in the same graph. This is important if we're constructing
      # the module in one graph and connecting it in another (e.g. with `defun`
      # the module is created in some default graph, and connected to a capturing
      # graph in order to turn it into a graph function).
      with self._enter_variable_scope(check_same_graph=False):
        self._layers = [basic.Linear(self._output_sizes[i],
                                     name="linear_{}".format(i),
                                     initializers=self._initializers,
                                     partitioners=self._partitioners,
                                     regularizers=self._regularizers,
                                     use_bias=self.use_bias)
                        for i in xrange(self._num_layers)]