def METHOD_NAME(
    shift: Tuple[np.float64], scale: Tuple[np.float64], num_layers: int,
    num_units: int,
    dropout_rate: float) -> Callable[[specs.EnvironmentSpec], bc.BCNetworks]:
  """Returns the factory of networks to be used by the agent.
  Args:
    shift: Shift of the observations in demonstrations.
    scale: Scale of the observations in demonstrations.
    num_layers: Number of layers of the BC network.
    num_units: Number of units of the BC network.
    dropout_rate: Dropout rate of the BC network.
  Returns:
    Network factory.
  """
  def network_factory(spec: specs.EnvironmentSpec) -> bc.BCNetworks:
    """Creates the network used by the agent."""
    action_spec = spec.actions
    num_dimensions = np.prod(action_spec.shape, dtype=int)
    def actor_fn(obs, is_training=False, key=None):
      obs += shift
      obs *= scale
      hidden_layers = [num_units] * num_layers
      mlp = hk.Sequential([
          hk.nets.MLP(hidden_layers + [num_dimensions]),
      ])
      if is_training:
        return mlp(obs, dropout_rate=dropout_rate, rng=key)
      else:
        return mlp(obs)
    policy = hk.without_apply_rng(hk.transform(actor_fn))
    # Create dummy observations to create network parameters.
    dummy_obs = utils.zeros_like(spec.observations)
    dummy_obs = utils.add_batch_dim(dummy_obs)
    policy_network = bc.BCPolicyNetwork(lambda key: policy.init(key, dummy_obs),
                                        policy.apply)
    return bc.BCNetworks(policy_network=policy_network)
  return network_factory