Repository: sbi-dev/sbi

Issue:
Deprecate the simple interface. 
Currently, in our simple interface, we only allow very few kwargs. We could add two arguments `init_kwargs` and `call_kwargs`, which would both be dictionaries. Not sure if we want this (it's also covered in the flexible interface), but we should discuss.

This had been requested by Miles in #275 


Discussion:
More context: 

The simple interface is here: 

https://github.com/sbi-dev/sbi/blob/c3c2b6e142fb4c57d5599effc1f01f8222a37c57/sbi/inference/base.py#L35

i.e., it's a single function that takes simulator, prior, method and budget and runs SBI to return a posterior object. We created it to show how simple inference with `sbi` can be. 
However, it's also quite rigid, which is why one should work with the "flexible interface" our actual API instead. 

We can make the simple interface more flexible by adding additional `kwargs` that are passed on to the inference methods. 

I think it's nice to keep `infer` for illustration, but to remove it from all the tutorials. We can keep it in `minimal.py` and in `getting_started` but we should add the `kwargs` there as well and add a note that in practice, the flexible interface should be used really. 
I can look into this (but cannot assign myself yet)

Resolving patch:
diff --git a/sbi/inference/base.py b/sbi/inference/base.py
--- a/sbi/inference/base.py
+++ b/sbi/inference/base.py
@@ -38,6 +38,9 @@ def infer(
     method: str,
     num_simulations: int,
     num_workers: int = 1,
+    init_kwargs: Optional[Dict] = None,
+    train_kwargs: Optional[Dict] = None,
+    build_posterior_kwargs: Optional[Dict] = None,
 ) -> NeuralPosterior:
     r"""Runs simulation-based inference and returns the posterior.
 
@@ -63,6 +66,10 @@ def infer(
         num_simulations: Number of simulation calls. More simulations means a longer
             runtime, but a better posterior estimate.
         num_workers: Number of parallel workers to use for simulations.
+        init_kwargs: Additional keyword arguments for the inference method
+            which are passed to `__init__`.
+        train_kwargs: Additional keyword arguments for training the density estimator.
+        build_posterior_kwargs: Additional keyword arguments for `build_posterior`.
 
     Returns: Posterior over parameters conditional on observations (amortized).
     """
@@ -74,17 +81,37 @@ def infer(
             "Method not available. `method` must be one of 'SNPE', 'SNLE', 'SNRE'."
         ) from err
 
+    if (
+        init_kwargs is not None
+        or build_posterior_kwargs is not None
+        or train_kwargs is not None
+    ):
+        warn(
+            "We discourage the use the simple interface in more complicated settings. "
+            "Have a look into the flexible interface, e.g. in our tutorial "
+            "(https://sbi-dev.github.io/sbi/tutorial/02_flexible_interface/).",
+            stacklevel=2,
+        )
+    # Set variables to empty dicts to be able to pass them
+    # to the functions later on (if necessary).
+    if build_posterior_kwargs is None:
+        build_posterior_kwargs = {}
+    if train_kwargs is None:
+        train_kwargs = {}
+    if init_kwargs is None:
+        init_kwargs = {}
+
     simulator, prior = prepare_for_sbi(simulator, prior)
 
-    inference = method_fun(prior=prior)
+    inference = method_fun(prior=prior, **init_kwargs)
     theta, x = simulate_for_sbi(
         simulator=simulator,
         proposal=prior,
         num_simulations=num_simulations,
         num_workers=num_workers,
     )
-    _ = inference.append_simulations(theta, x).train()
-    posterior = inference.build_posterior()
+    _ = inference.append_simulations(theta, x).train(**train_kwargs)
+    posterior = inference.build_posterior(**build_posterior_kwargs)
 
     return posterior
 


Test patch:
diff --git a/tests/base_test.py b/tests/base_test.py
--- a/tests/base_test.py
+++ b/tests/base_test.py
@@ -1,7 +1,30 @@
 import pytest
 import torch
 
-from sbi.inference import SNPE
+from sbi import utils
+from sbi.inference import SNPE, infer
+
+
+def test_infer():
+    # Example is taken from 00_getting_started.ipynb
+    num_dim = 3
+    prior = utils.BoxUniform(low=-2 * torch.ones(num_dim), high=2 * torch.ones(num_dim))
+
+    def simulator(parameter_set):
+        return 1.0 + parameter_set + torch.randn(parameter_set.shape) * 0.1
+
+    posterior = infer(simulator, prior, method="SNPE_A", num_simulations=10)
+    assert posterior is not None, "Most basic use of 'infer' failed"
+    posterior = infer(
+        simulator,
+        prior,
+        method="SNPE_A",
+        num_simulations=10,
+        init_kwargs={'num_components': 5},
+        train_kwargs={'max_num_epochs': 2},
+        build_posterior_kwargs={'prior': prior},
+    )
+    assert posterior is not None, "Using 'infer' with keyword arguments failed"
 
 
 @pytest.mark.parametrize("training_batch_size", (1, 10, 100))