':param env_spec:
:param hidden_sizes: list of sizes for the fully-connected hidden layers
:param learn_std: Is std trainable
:param init_std: Initial std
:param adaptive_std:
:param std_share_network:
:param std_hidden_sizes: list of sizes for the fully-connected layers for std
:param min_std: whether to make sure that the std is at least some threshold value, to avoid numerical issues
:param std_hidden_nonlinearity:
:param hidden_nonlinearity: nonlinearity used for each hidden layer
:param output_nonlinearity: nonlinearity for the output layer
:param mean_network: custom network for the output mean
:param std_network: custom network for the output log std
:param std_parametrization: how the std should be parametrized. There are a few options:
- exp: the logarithm of the std will be stored, and applied a exponential transformation
- softplus: the std will be computed as log(1+exp(x))
:return:'

def __init__(self, name, env_spec, hidden_sizes=(32, 32), learn_std=True, init_std=1.0, adaptive_std=False, std_share_network=False, std_hidden_sizes=(32, 32), min_std=1e-06, std_hidden_nonlinearity=tf.nn.tanh, hidden_nonlinearity=tf.nn.tanh, output_nonlinearity=None, mean_network=None, std_network=None, std_parametrization='exp'):

    Serializable.quick_init(self, locals())
    assert isinstance(env_spec.action_space, Box)
    with tf.variable_scope(name):
        obs_dim = env_spec.observation_space.flat_dim
        action_dim = env_spec.action_space.flat_dim
        if (mean_network is None):
            mean_network = MLP(name='mean_network', input_shape=(obs_dim,), output_dim=action_dim, hidden_sizes=hidden_sizes, hidden_nonlinearity=hidden_nonlinearity, output_nonlinearity=output_nonlinearity)
        self._mean_network = mean_network
        l_mean = mean_network.output_layer
        obs_var = mean_network.input_layer.input_var
        if (std_network is not None):
            l_std_param = std_network.output_layer
        elif adaptive_std:
            std_network = MLP(name='std_network', input_shape=(obs_dim,), input_layer=mean_network.input_layer, output_dim=action_dim, hidden_sizes=std_hidden_sizes, hidden_nonlinearity=std_hidden_nonlinearity, output_nonlinearity=None)
            l_std_param = std_network.output_layer
        else:
            if (std_parametrization == 'exp'):
                init_std_param = np.log(init_std)
            elif (std_parametrization == 'softplus'):
                init_std_param = np.log((np.exp(init_std) - 1))
            else:
                raise NotImplementedError
            l_std_param = L.ParamLayer(mean_network.input_layer, num_units=action_dim, param=tf.constant_initializer(init_std_param), name='output_std_param', trainable=learn_std)
        self.std_parametrization = std_parametrization
        if (std_parametrization == 'exp'):
            min_std_param = np.log(min_std)
        elif (std_parametrization == 'softplus'):
            min_std_param = np.log((np.exp(min_std) - 1))
        else:
            raise NotImplementedError
        self.min_std_param = min_std_param
        self._l_mean = l_mean
        self._l_std_param = l_std_param
        self._dist = DiagonalGaussian(action_dim)
        LayersPowered.__init__(self, [l_mean, l_std_param])
        super(GaussianMLPPolicy, self).__init__(env_spec)
        dist_info_sym = self.dist_info_sym(mean_network.input_layer.input_var, dict())
        mean_var = dist_info_sym['mean']
        log_std_var = dist_info_sym['log_std']
        self._f_dist = tensor_utils.compile_function(inputs=[obs_var], outputs=[mean_var, log_std_var])
