Exemplo n.º 1
0
 def setUp(self):
     if has_torch:
         self.net = createDefaultNN(2, 3)()
         self.net_with_scaler = ScalerAndNet(self.net, None)
         self.stat_calc = NeuralEmbedding(self.net)
         self.stat_calc_with_scaler = NeuralEmbedding(self.net_with_scaler)
     if not has_torch:
         self.assertRaises(ImportError, NeuralEmbedding, None)
Exemplo n.º 2
0
    def test_statistics(self):
        if not has_torch:
            self.assertRaises(ImportError, NeuralEmbedding, None)
        else:
            self.stat_calc = NeuralEmbedding(self.net)

            self.assertRaises(TypeError, self.stat_calc.statistics, 3.4)
            vec1 = np.array([1, 2])
            vec2 = np.array([1])
            self.assertTrue((self.stat_calc.statistics([vec1])).all())
            self.assertTrue((self.stat_calc.statistics([vec1, vec1])).all())
            self.assertRaises(RuntimeError, self.stat_calc.statistics, [vec2])
Exemplo n.º 3
0
    def setUp(self):
        if has_torch:
            self.net = createDefaultNN(2, 3)()
            self.net_with_scaler = ScalerAndNet(self.net, None)
            self.net_with_discard_wrapper = DiscardLastOutputNet(self.net)
            self.stat_calc = NeuralEmbedding(self.net)
            self.stat_calc_with_scaler = NeuralEmbedding(self.net_with_scaler)
            self.stat_calc_with_discard_wrapper = NeuralEmbedding(
                self.net_with_discard_wrapper)
            # reference input and output
            torch.random.manual_seed(1)
            self.tensor = torch.randn(1, 2)
            self.out = self.net(self.tensor)
            self.out_discard = self.net_with_discard_wrapper(self.tensor)

            # try now the statistics rescaling option:
            mu = Uniform([[-5.0], [5.0]], name='mu')
            sigma = Uniform([[0.0], [10.0]], name='sigma')
            # define a Gaussian model
            self.model = Normal([mu, sigma])

            sampler = DrawFromPrior([self.model], BackendDummy(), seed=1)
            reference_parameters, reference_simulations = sampler.sample_par_sim_pairs(
                30, 1)
            reference_simulations = reference_simulations.reshape(
                reference_simulations.shape[0], reference_simulations.shape[2])

            self.stat_calc_rescaling = NeuralEmbedding(
                self.net,
                reference_simulations=reference_simulations,
                previous_statistics=Identity(degree=2))

        if not has_torch:
            self.assertRaises(ImportError, NeuralEmbedding, None)
Exemplo n.º 4
0
class NeuralEmbeddingTests(unittest.TestCase):
    def setUp(self):
        if has_torch:
            self.net = createDefaultNN(2, 3)()

    def test_statistics(self):
        if not has_torch:
            self.assertRaises(ImportError, NeuralEmbedding, None)
        else:
            self.stat_calc = NeuralEmbedding(self.net)

            self.assertRaises(TypeError, self.stat_calc.statistics, 3.4)
            vec1 = np.array([1, 2])
            vec2 = np.array([1])
            self.assertTrue((self.stat_calc.statistics([vec1])).all())
            self.assertTrue((self.stat_calc.statistics([vec1, vec1])).all())
            self.assertRaises(RuntimeError, self.stat_calc.statistics, [vec2])
Exemplo n.º 5
0
    def get_statistics(self):
        """
        Returns a NeuralEmbedding Statistics implementing the learned transformation.

        Returns
        -------
        abcpy.statistics.NeuralEmbedding object
            a statistics object that implements the learned transformation.
        """
        return NeuralEmbedding(net=self.embedding_net,
                               previous_statistics=self.statistics_calc)
Exemplo n.º 6
0
    def test_save_load(self):
        if has_torch:
            self.stat_calc.save_net("net.pth")
            self.stat_calc_with_scaler.save_net("net.pth",
                                                path_to_scaler="scaler.pkl")
            self.stat_calc_loaded = NeuralEmbedding.fromFile("net.pth",
                                                             input_size=2,
                                                             output_size=3)
            self.stat_calc_loaded = NeuralEmbedding.fromFile(
                "net.pth", network_class=createDefaultNN(2, 3))
            self.stat_calc_loaded_with_scaler = NeuralEmbedding.fromFile(
                "net.pth",
                network_class=createDefaultNN(2, 3),
                path_to_scaler="scaler.pkl")

            with self.assertRaises(RuntimeError):
                self.stat_calc_with_scaler.save_net("net.pth")
                self.stat_calc_loaded = NeuralEmbedding.fromFile("net.pth")
                self.stat_calc_loaded = NeuralEmbedding.fromFile(
                    "net.pth",
                    network_class=createDefaultNN(2, 3),
                    input_size=1)
                self.stat_calc_loaded = NeuralEmbedding.fromFile(
                    "net.pth",
                    network_class=createDefaultNN(2, 3),
                    hidden_sizes=[2, 3])
Exemplo n.º 7
0
class NeuralEmbeddingTests(unittest.TestCase):
    def setUp(self):
        if has_torch:
            self.net = createDefaultNN(2, 3)()
            self.net_with_scaler = ScalerAndNet(self.net, None)
            self.stat_calc = NeuralEmbedding(self.net)
            self.stat_calc_with_scaler = NeuralEmbedding(self.net_with_scaler)
        if not has_torch:
            self.assertRaises(ImportError, NeuralEmbedding, None)

    def test_statistics(self):
        if has_torch:
            self.assertRaises(TypeError, self.stat_calc.statistics, 3.4)
            vec1 = np.array([1, 2])
            vec2 = np.array([1])
            self.assertTrue((self.stat_calc.statistics([vec1])).all())
            self.assertTrue((self.stat_calc.statistics([vec1, vec1])).all())
            self.assertRaises(RuntimeError, self.stat_calc.statistics, [vec2])

    def test_save_load(self):
        if has_torch:
            self.stat_calc.save_net("net.pth")
            self.stat_calc_with_scaler.save_net("net.pth",
                                                path_to_scaler="scaler.pkl")
            self.stat_calc_loaded = NeuralEmbedding.fromFile("net.pth",
                                                             input_size=2,
                                                             output_size=3)
            self.stat_calc_loaded = NeuralEmbedding.fromFile(
                "net.pth", network_class=createDefaultNN(2, 3))
            self.stat_calc_loaded_with_scaler = NeuralEmbedding.fromFile(
                "net.pth",
                network_class=createDefaultNN(2, 3),
                path_to_scaler="scaler.pkl")

            with self.assertRaises(RuntimeError):
                self.stat_calc_with_scaler.save_net("net.pth")
                self.stat_calc_loaded = NeuralEmbedding.fromFile("net.pth")
                self.stat_calc_loaded = NeuralEmbedding.fromFile(
                    "net.pth",
                    network_class=createDefaultNN(2, 3),
                    input_size=1)
                self.stat_calc_loaded = NeuralEmbedding.fromFile(
                    "net.pth",
                    network_class=createDefaultNN(2, 3),
                    hidden_sizes=[2, 3])
Exemplo n.º 8
0
    def test_save_load(self):
        if has_torch:
            self.stat_calc.save_net("net.pth")
            self.stat_calc_with_scaler.save_net("net.pth",
                                                path_to_scaler="scaler.pkl")
            stat_calc_loaded = NeuralEmbedding.fromFile("net.pth",
                                                        input_size=2,
                                                        output_size=3)
            stat_calc_loaded = NeuralEmbedding.fromFile(
                "net.pth", network_class=createDefaultNN(2, 3))
            stat_calc_loaded_with_scaler = NeuralEmbedding.fromFile(
                "net.pth",
                network_class=createDefaultNN(2, 3),
                path_to_scaler="scaler.pkl")
            # test the network was recovered correctly
            out_new = stat_calc_loaded.net(self.tensor)
            self.assertTrue(torch.allclose(self.out, out_new))

            # now with the DiscardLastOutput wrapper
            self.stat_calc_with_discard_wrapper.save_net(
                "net_with_discard_wrapper.pth")
            stat_calc_with_discard_loaded = NeuralEmbedding.fromFile(
                "net_with_discard_wrapper.pth", input_size=2, output_size=3)
            # test the network was recovered correctly
            out_new_discard = stat_calc_with_discard_loaded.net(self.tensor)
            self.assertTrue(torch.allclose(self.out_discard, out_new_discard))

            # now with both DiscardLastOutput and Scaler wrappers
            stat_calc_with_discard_and_scaler_loaded = NeuralEmbedding.fromFile(
                "net_with_discard_wrapper.pth",
                input_size=2,
                output_size=3,
                path_to_scaler="scaler.pkl")

            with self.assertRaises(RuntimeError):
                self.stat_calc_with_scaler.save_net("net.pth")
                stat_calc_loaded = NeuralEmbedding.fromFile("net.pth")
                stat_calc_loaded = NeuralEmbedding.fromFile(
                    "net.pth",
                    network_class=createDefaultNN(2, 3),
                    input_size=1)
                stat_calc_loaded = NeuralEmbedding.fromFile(
                    "net.pth",
                    network_class=createDefaultNN(2, 3),
                    hidden_sizes=[2, 3])
def infer_parameters(steps=2, n_sample=50, n_samples_per_param=1, logging_level=logging.WARN):
    """Perform inference for this example.

    Parameters
    ----------
    steps : integer, optional
        Number of iterations in the sequential PMCABC algorithm ("generations"). The default value is 3
    n_samples : integer, optional
        Number of posterior samples to generate. The default value is 250.
    n_samples_per_param : integer, optional
        Number of data points in each simulated data set. The default value is 10.

    Returns
    -------
    abcpy.output.Journal
        A journal containing simulation results, metadata and optionally intermediate results.
    """
    logging.basicConfig(level=logging_level)
    # define backend
    # Note, the dummy backend does not parallelize the code!
    from abcpy.backends import BackendDummy as Backend
    backend = Backend()

    # define observation for true parameters mean=170, std=15
    height_obs = [160.82499176, 167.24266737, 185.71695756, 153.7045709, 163.40568812, 140.70658699, 169.59102084,
                  172.81041696, 187.38782738, 179.66358934, 176.63417241, 189.16082803, 181.98288443, 170.18565017,
                  183.78493886, 166.58387299, 161.9521899, 155.69213073, 156.17867343, 144.51580379, 170.29847515,
                  197.96767899, 153.36646527, 162.22710198, 158.70012047, 178.53470703, 170.77697743, 164.31392633,
                  165.88595994, 177.38083686, 146.67058471763457, 179.41946565658628, 238.02751620619537,
                  206.22458790620766, 220.89530574344568, 221.04082532837026, 142.25301427453394, 261.37656571434275,
                  171.63761180867033, 210.28121820385866, 237.29130237612236, 175.75558340169619, 224.54340549862235,
                  197.42448680731226, 165.88273684581381, 166.55094082844519, 229.54308602661584, 222.99844054358519,
                  185.30223966014586, 152.69149367593846, 206.94372818527413, 256.35498655339154, 165.43140916577741,
                  250.19273595481803, 148.87781549665536, 223.05547559193792, 230.03418198709608, 146.13611923127021,
                  138.24716809523139, 179.26755740864527, 141.21704876815426, 170.89587081800852, 222.96391329259626,
                  188.27229523693822, 202.67075179617672, 211.75963110985992, 217.45423324370509]

    # define prior
    from abcpy.continuousmodels import Uniform
    mu = Uniform([[150], [200]], name="mu")
    sigma = Uniform([[5], [25]], name="sigma")

    # define the model
    from abcpy.continuousmodels import Normal
    height = Normal([mu, sigma], )

    # 1) generate simulations from prior
    from abcpy.inferences import DrawFromPrior
    draw_from_prior = DrawFromPrior([height], backend=backend)

    # notice the use of the `.sample_par_sim_pairs` method rather than `.sample` to obtain data suitably formatted
    # for the summary statistics learning routines
    parameters, simulations = draw_from_prior.sample_par_sim_pairs(100, n_samples_per_param=1)
    # if you want to use the test loss to do early stopping in the training:
    parameters_val, simulations_val = draw_from_prior.sample_par_sim_pairs(100, n_samples_per_param=1)
    # discard the mid dimension (n_samples_per_param, as the StatisticsLearning classes use that =1)
    simulations = simulations.reshape(simulations.shape[0], simulations.shape[2])
    simulations_val = simulations_val.reshape(simulations_val.shape[0], simulations_val.shape[2])

    # 2) now train the NNs with the different methods with the generated data
    from abcpy.statistics import Identity
    identity = Identity()  # to apply before computing the statistics

    logging.info("semiNN")
    from abcpy.statisticslearning import SemiautomaticNN, TripletDistanceLearning
    semiNN = SemiautomaticNN([height], identity, backend=backend, parameters=parameters,
                             simulations=simulations, parameters_val=parameters_val, simulations_val=simulations_val,
                             early_stopping=True,  # early stopping
                             seed=1, n_epochs=10, scale_samples=False, use_tqdm=False)
    logging.info("triplet")
    triplet = TripletDistanceLearning([height], identity, backend=backend, parameters=parameters,
                                      simulations=simulations, parameters_val=parameters_val,
                                      simulations_val=simulations_val,
                                      early_stopping=True,  # early stopping
                                      seed=1, n_epochs=10, scale_samples=True, use_tqdm=False)

    # 3) save and re-load NNs:
    # get the statistics from the already fit StatisticsLearning object 'semiNN':
    learned_seminn_stat = semiNN.get_statistics()
    learned_triplet_stat = triplet.get_statistics()

    # this has a save net method:
    learned_seminn_stat.save_net("seminn_net.pth")
    # if you used `scale_samples=True` in learning the NNs, need to provide a path where pickle stores the scaler too:
    learned_triplet_stat.save_net("triplet_net.pth", path_to_scaler="scaler.pkl")

    # to reload: need to use the Neural Embedding statistics fromFile; this needs to know which kind of NN it is using;
    # need therefore to pass either the input/output size (it data size and number parameters) or the network class if
    # that was specified explicitly in the StatisticsLearning class. Check the docstring for NeuralEmbedding.fromFile
    # for more details.
    from abcpy.statistics import NeuralEmbedding
    learned_seminn_stat_loaded = NeuralEmbedding.fromFile("seminn_net.pth", input_size=1, output_size=2)
    learned_triplet_stat_loaded = NeuralEmbedding.fromFile("triplet_net.pth", input_size=1, output_size=2,
                                                           path_to_scaler="scaler.pkl")

    # 4) you can optionally rescale the different summary statistics be their standard deviation on a reference dataset
    # of simulations. To do this, it is enough to pass at initialization the reference dataset, and the rescaling will
    # be applied every time the statistics is computed on some simulation or observation.
    learned_triplet_stat_loaded = NeuralEmbedding.fromFile("triplet_net.pth", input_size=1, output_size=2,
                                                           path_to_scaler="scaler.pkl",
                                                           reference_simulations=simulations_val)

    # 5) perform inference
    # define distance
    from abcpy.distances import Euclidean
    distance_calculator = Euclidean(learned_seminn_stat_loaded)

    # define kernel
    from abcpy.perturbationkernel import DefaultKernel
    kernel = DefaultKernel([mu, sigma])

    # define sampling scheme
    from abcpy.inferences import PMCABC
    sampler = PMCABC([height], [distance_calculator], backend, kernel, seed=1)

    eps_arr = np.array([500])  # starting value of epsilon; the smaller, the slower the algorithm.
    # at each iteration, take as epsilon the epsilon_percentile of the distances obtained by simulations at previous
    # iteration from the observation
    epsilon_percentile = 10
    journal = sampler.sample([height_obs], steps, eps_arr, n_sample, n_samples_per_param, epsilon_percentile)

    return journal
Exemplo n.º 10
0
                jrnl = Journal.fromFile(inference_folder + "jrnl" + namefile_postfix + ".jnl")
                perform_ABC = False
                print("\n Using previosly generated approx posterior.")
            except FileNotFoundError:
                perform_ABC = True
        else:
            perform_ABC = True

        # you can perform ABC inference with both SM, FP statistics and the true ones
        if technique in ["SM", "SSM"]:
            if perform_ABC:
                print(f"\nPerform ABC inference with {technique} statistics.")
                if weighted_euclidean_distance:  # define the distance object
                    # keep the last 100 test samples to estimate the initial eps value if not provided
                    distance_calculator = WeightedEuclidean(
                        NeuralEmbedding(RescaleAndDiscardLastOutputNet(net_data_SM, scaler_data_SM)),
                        [samples_matrix_test[i].numpy() for i in
                         range(samples_matrix_test.shape[0] - 100 * (ABC_eps is None))])
                else:
                    distance_calculator = Euclidean(
                        NeuralEmbedding(RescaleAndDiscardLastOutputNet(net_data_SM, scaler_data_SM)))

        elif "FP" == technique:
            if perform_ABC:
                print("\nPerform ABC inference with FP statistics.")
                if weighted_euclidean_distance:
                    distance_calculator = WeightedEuclidean(
                        NeuralEmbedding(RescaleAndNet(net_FP, scaler_data_FP)),
                        [samples_matrix_test[i].numpy() for i in
                         range(samples_matrix_test.shape[0] - 100 * (ABC_eps is None))])
                else:
Exemplo n.º 11
0
class NeuralEmbeddingTests(unittest.TestCase):
    def setUp(self):
        if has_torch:
            self.net = createDefaultNN(2, 3)()
            self.net_with_scaler = ScalerAndNet(self.net, None)
            self.net_with_discard_wrapper = DiscardLastOutputNet(self.net)
            self.stat_calc = NeuralEmbedding(self.net)
            self.stat_calc_with_scaler = NeuralEmbedding(self.net_with_scaler)
            self.stat_calc_with_discard_wrapper = NeuralEmbedding(
                self.net_with_discard_wrapper)
            # reference input and output
            torch.random.manual_seed(1)
            self.tensor = torch.randn(1, 2)
            self.out = self.net(self.tensor)
            self.out_discard = self.net_with_discard_wrapper(self.tensor)

            # try now the statistics rescaling option:
            mu = Uniform([[-5.0], [5.0]], name='mu')
            sigma = Uniform([[0.0], [10.0]], name='sigma')
            # define a Gaussian model
            self.model = Normal([mu, sigma])

            sampler = DrawFromPrior([self.model], BackendDummy(), seed=1)
            reference_parameters, reference_simulations = sampler.sample_par_sim_pairs(
                30, 1)
            reference_simulations = reference_simulations.reshape(
                reference_simulations.shape[0], reference_simulations.shape[2])

            self.stat_calc_rescaling = NeuralEmbedding(
                self.net,
                reference_simulations=reference_simulations,
                previous_statistics=Identity(degree=2))

        if not has_torch:
            self.assertRaises(ImportError, NeuralEmbedding, None)

    def test_statistics(self):
        if has_torch:
            self.assertRaises(TypeError, self.stat_calc.statistics, 3.4)
            vec1 = np.array([1, 2])
            vec2 = np.array([1])
            self.assertTrue((self.stat_calc.statistics([vec1])).all())
            self.assertTrue((self.stat_calc.statistics([vec1, vec1])).all())
            self.assertRaises(RuntimeError, self.stat_calc.statistics, [vec2])

            self.assertTrue(
                (self.stat_calc_rescaling.statistics([vec2])).all())

    def test_save_load(self):
        if has_torch:
            self.stat_calc.save_net("net.pth")
            self.stat_calc_with_scaler.save_net("net.pth",
                                                path_to_scaler="scaler.pkl")
            stat_calc_loaded = NeuralEmbedding.fromFile("net.pth",
                                                        input_size=2,
                                                        output_size=3)
            stat_calc_loaded = NeuralEmbedding.fromFile(
                "net.pth", network_class=createDefaultNN(2, 3))
            stat_calc_loaded_with_scaler = NeuralEmbedding.fromFile(
                "net.pth",
                network_class=createDefaultNN(2, 3),
                path_to_scaler="scaler.pkl")
            # test the network was recovered correctly
            out_new = stat_calc_loaded.net(self.tensor)
            self.assertTrue(torch.allclose(self.out, out_new))

            # now with the DiscardLastOutput wrapper
            self.stat_calc_with_discard_wrapper.save_net(
                "net_with_discard_wrapper.pth")
            stat_calc_with_discard_loaded = NeuralEmbedding.fromFile(
                "net_with_discard_wrapper.pth", input_size=2, output_size=3)
            # test the network was recovered correctly
            out_new_discard = stat_calc_with_discard_loaded.net(self.tensor)
            self.assertTrue(torch.allclose(self.out_discard, out_new_discard))

            # now with both DiscardLastOutput and Scaler wrappers
            stat_calc_with_discard_and_scaler_loaded = NeuralEmbedding.fromFile(
                "net_with_discard_wrapper.pth",
                input_size=2,
                output_size=3,
                path_to_scaler="scaler.pkl")

            with self.assertRaises(RuntimeError):
                self.stat_calc_with_scaler.save_net("net.pth")
                stat_calc_loaded = NeuralEmbedding.fromFile("net.pth")
                stat_calc_loaded = NeuralEmbedding.fromFile(
                    "net.pth",
                    network_class=createDefaultNN(2, 3),
                    input_size=1)
                stat_calc_loaded = NeuralEmbedding.fromFile(
                    "net.pth",
                    network_class=createDefaultNN(2, 3),
                    hidden_sizes=[2, 3])
Exemplo n.º 12
0
                                           early_stopping=False, batch_size=32, # early stopping
                                           seed=1, n_epochs=2000, lr=1e-3, scale_samples=False) # 2000
        # get the statistics from the StatisticsLearning object:
        learned_seminn_stat = semiNN.get_statistics()
        learned_triplet_stat = triplet.get_statistics()
        # saving the learned net
        if fake:
            learned_seminn_stat.save_net("Data/Pilots/seminn_net_fake.pth")
            learned_triplet_stat.save_net("Data/Pilots/triplet_net_fake.pth")
        else:
            learned_seminn_stat.save_net("Data/Pilots/seminn_net_"+str(whichobs)+".pth")
            learned_triplet_stat.save_net("Data/Pilots/triplet_net_"+str(whichobs)+".pth")

    if sample:
        if fake:
            learned_seminn_stat_loaded = NeuralEmbedding.fromFile("Data/Pilots/seminn_net_fake.pth", input_size=len(InformativeIndices), output_size=7, previous_statistics=identity)
            learned_triplet_stat_loaded = NeuralEmbedding.fromFile("Data/Pilots/triplet_net_fake.pth", input_size=len(InformativeIndices), output_size=7, previous_statistics=identity)
        else:
            learned_seminn_stat_loaded = NeuralEmbedding.fromFile("Data/Pilots/seminn_net_"+str(whichobs)+".pth", input_size=len(InformativeIndices), output_size=7, previous_statistics=identity)
            learned_triplet_stat_loaded = NeuralEmbedding.fromFile("Data/Pilots/triplet_net_"+str(whichobs)+".pth", input_size=len(InformativeIndices), output_size=7, previous_statistics=identity)

        # Define Distance functions
        from abcpy.distances import Euclidean
        dist_calc_seminn = Euclidean(learned_seminn_stat_loaded)
        dist_calc_triplet = Euclidean(learned_triplet_stat_loaded)
        from statistic import Multiply
        L = np.load('Data/L_all_3_cross.npz')['L']
        stat_mult = Multiply(L=L, degree=3, cross=True)
        dist_calc_mult = Euclidean(stat_mult)
        print(dist_calc_mult.distance(obsdata, obsdata))