    def __init__(self, params):
        """Initializes a class instance.

        Arguments:
            params (DotMap): A dotmap of model parameters.
                .name (str): Model name, used for logging/use in variable scopes.
                    Warning: Models with the same name will overwrite each other.
                .num_networks (int): (optional) The number of networks in the ensemble. Defaults to 1.
                    Ignored if model is being loaded.
                .model_dir (str/None): (optional) Path to directory from which model will be loaded, and
                    saved by default. Defaults to None.
                .load_model (bool): (optional) If True, model will be loaded from the model directory,
                    assuming that the files are generated by a model of the same name. Defaults to False.
                .sess (tf.Session/None): The session that this model will use.
                    If None, creates a session with its own associated graph. Defaults to None.
        """
        self.name = get_required_argument(params, 'name', 'Must provide name.')
        self.model_dir = params.get('model_dir', None)

        print('[ BNN ] Initializing model: {} | {} networks | {} elites'.format(params['name'], params['num_networks'], params['num_elites']))
        if params.get('sess', None) is None:
            config = tf.ConfigProto()
            # config.gpu_options.allow_growth = True
            self._sess = tf.Session(config=config)
        else:
            self._sess = params.get('sess')

        # Instance variables
        self.finalized = False
        self.layers, self.max_logvar, self.min_logvar = [], None, None
        self.decays, self.optvars, self.nonoptvars = [], [], []
        self.end_act, self.end_act_name = None, None
        self.scaler = None

        # Training objects
        self.optimizer = None
        self.sy_train_in, self.sy_train_targ = None, None
        self.train_op, self.mse_loss = None, None

        # Prediction objects
        self.sy_pred_in2d, self.sy_pred_mean2d_fac, self.sy_pred_var2d_fac = None, None, None
        self.sy_pred_mean2d, self.sy_pred_var2d = None, None
        self.sy_pred_in3d, self.sy_pred_mean3d_fac, self.sy_pred_var3d_fac = None, None, None

        if params.get('load_model', False):
            if self.model_dir is None:
                raise ValueError("Cannot load model without providing model directory.")
            self._load_structure()
            self.num_nets, self.model_loaded = self.layers[0].get_ensemble_size(), True
            print("Model loaded from %s." % self.model_dir)
            self.num_elites = params['num_elites']
        else:
            self.num_nets = params.get('num_networks', 1)
            self.num_elites = params['num_elites'] #params.get('num_elites', 1)
            self.model_loaded = False

        if self.num_nets == 1:
            print("Created a neural network with variance predictions.")
        else:
            print("Created an ensemble of {} neural networks with variance predictions | Elites: {}".format(self.num_nets, self.num_elites))
Initializes a class instance.

Arguments:
params (DotMap): A dotmap of model parameters.
.name (str): Model name, used for logging/use in variable scopes.
Warning: Models with the same name will overwrite each other.
.num_networks (int): (optional) The number of networks in the ensemble. Defaults to 1.
Ignored if model is being loaded.
.model_dir (str/None): (optional) Path to directory from which model will be loaded, and
saved by default. Defaults to None.
.load_model (bool): (optional) If True, model will be loaded from the model directory,
assuming that the files are generated by a model of the same name. Defaults to False.
.sess (tf.Session/None): The session that this model will use.
If None, creates a session with its own associated graph. Defaults to None.
mbpo/models/bnn.py