예제 #1
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])
예제 #2
0
    def setUp(self):
        if has_torch:
            net = createDefaultNN(5, 2, nonlinearity=torch.nn.Softplus(), batch_norm_last_layer=False)()
            net_bn = createDefaultNN(5, 2, nonlinearity=torch.nn.Softplus(), batch_norm_last_layer=True)()
            self.tensor = torch.randn((10, 5), requires_grad=True)
            self.y = net(self.tensor)
            self.y_bn = net_bn(self.tensor)

            self.y_with_infinities = self.y.detach().clone()
            self.y_with_infinities[0, 0] = np.inf

            self.f, self.s = jacobian_second_order(self.tensor, self.y)  # reference derivatives
            self.f_bn, self.s_bn = jacobian_second_order(self.tensor, self.y_bn)  # reference derivatives
예제 #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)
예제 #4
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)
예제 #5
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 setUp(self):
     if has_torch:
         self.net = createDefaultNN(2, 3)()
         self.net_with_discard_wrapper = DiscardLastOutputNet(self.net)
         # reference input and output
         torch.random.manual_seed(1)
         self.tensor_1 = torch.randn(2)
         self.tensor_2 = torch.randn(1, 2)
         self.tensor_3 = torch.randn(1, 3, 2)
예제 #7
0
    def fromFile(cls,
                 path_to_net_state_dict,
                 network_class=None,
                 input_size=None,
                 output_size=None,
                 hidden_sizes=None,
                 previous_statistics=None):
        """If the neural network state_dict was saved to the disk, this method can be used to instantiate a
        NeuralEmbedding object with that neural network.

        In order for the state_dict to be read correctly, the network class is needed. Therefore, we provide 2 options:
        1) the Pytorch neural network class can be passed (if the user defined it, for instance)
        2) if the neural network was defined by using the DefaultNN class in abcpy.NN_utilities.networks, you can
        provide arguments `input_size`, `output_size` and `hidden_sizes` (the latter is optional) that define
        the sizes of a fully connected network; then a DefaultNN is instantiated with those sizes. This can be used
        if for instance the neural network was trained using the utilities in abcpy.statisticslearning and you did
        not provide explicitly the neural network class there, but defined it through the sizes of the different layers.

        In both cases, note that the input size of the neural network must coincide with the size of each of the
        datapoints generated from the model (unless some other statistics are computed beforehand).

        Parameters
        ----------
        path_to_net_state_dict : basestring
            the path where the state-dict is saved
        network_class : torch.nn class, optional
            if the neural network class is known explicitly (for instance if the used defined it), then it has to be
             passed here. This must not be provided together with `input_size` or `output_size`.
        input_size : integer, optional
            if the neural network is an instance of abcpy.NN_utilities.networks.DefaultNN with some input and
            output size, then you should provide here the input size of the network. It has to be provided together with
            the corresponding output_size, and it must not be provided with `network_class`.
        output_size : integer, optional
            if the neural network is an instance of abcpy.NN_utilities.networks.DefaultNN with some input and
            output size, then you should provide here the output size of the network. It has to be provided together
            with the corresponding input_size, and it must not be provided with `network_class`.
        hidden_sizes : array-like, optional
            if the neural network is an instance of abcpy.NN_utilities.networks.DefaultNN with some input and
            output size, then you can provide here an array-like with the size of the hidden layers (for instance
            [5,7,5] denotes 3 hidden layers with correspondingly 5,7,5 neurons). In case this parameter is not provided,
            the hidden sizes are determined from the input and output sizes as determined in
            abcpy.NN_utilities.networks.DefaultNN. Note that this must not be provided together with `network_class`.
        previous_statistics : Statistics class, optional
            It allows pipelining of Statistics. Specifically, if the final statistic to be used is determined by the
            composition of two Statistics, you can pass the first here; then, whenever the final statistic is needed, it
            is sufficient to call the `statistics` method of the second one, and that will automatically apply both
            transformations. In this case, this is the statistics that has to be computed before the neural network
            transformation is applied.
        Returns
        -------
        abcpy.statistics.NeuralEmbedding
            the `NeuralEmbedding` object with the neural network obtained from the specified file.
        """
        if not has_torch:
            raise ImportError(
                "Pytorch is required to instantiate an element of the {} class, in order to handle "
                "neural networks. Please install it. ".format(cls.__name__))

        if network_class is None and (input_size is None
                                      or output_size is None):
            raise RuntimeError(
                "You need to pass either network class or both input_size and output_size."
            )
        if network_class is not None and (input_size is not None
                                          or output_size is not None):
            raise RuntimeError(
                "You can't pass together network_class and one of input_size, output_size"
            )
        if network_class is not None and hidden_sizes is not None:
            raise RuntimeError(
                "You passed hidden_sizes as an argument, but that may be passed only if you are passing "
                "input_size and input_size as well, and you are not passing network_class."
            )

        if network_class is not None:  # user explicitly passed the NN class
            net = load_net(path_to_net_state_dict, network_class)
            statistic_object = cls(net,
                                   previous_statistics=previous_statistics)
        else:  # the user passed the input_size, output_size and (maybe) the hidden_sizes
            net = load_net(
                path_to_net_state_dict,
                createDefaultNN(input_size=input_size,
                                output_size=output_size,
                                hidden_sizes=hidden_sizes))
            statistic_object = cls(net,
                                   previous_statistics=previous_statistics)

        return statistic_object
예제 #8
0
    def fromFile(cls,
                 path_to_net_state_dict,
                 network_class=None,
                 path_to_scaler=None,
                 input_size=None,
                 output_size=None,
                 hidden_sizes=None,
                 degree=1,
                 cross=False,
                 reference_simulations=None,
                 previous_statistics=None):
        """If the neural network state_dict was saved to the disk, this method can be used to instantiate a
        NeuralEmbedding object with that neural network.

        In order for the state_dict to be read correctly, the network class is needed. Therefore, we provide 2 options:
        1) the Pytorch neural network class can be passed (if the user defined it, for instance)
        2) if the neural network was defined by using the DefaultNN class in abcpy.NN_utilities.networks, you can
        provide arguments `input_size`, `output_size` and `hidden_sizes` (the latter is optional) that define
        the sizes of a fully connected network; then a DefaultNN is instantiated with those sizes. This can be used
        if for instance the neural network was trained using the utilities in abcpy.statisticslearning and you did
        not provide explicitly the neural network class there, but defined it through the sizes of the different layers.

        In both cases, note that the input size of the neural network must coincide with the size of each of the
        datapoints generated from the model (unless some other statistics are computed beforehand).

        Note that if the neural network was of the class `ScalerAndNet`, ie a scaler was applied before the data is fed
        through it, you need to pass `path_to_scaler` as well. Then this method will instantiate the network in the
        correct way.

        Parameters
        ----------
        path_to_net_state_dict : basestring
            the path where the state-dict is saved
        network_class : torch.nn class, optional
            if the neural network class is known explicitly (for instance if the used defined it), then it has to be
             passed here. This must not be provided together with `input_size` or `output_size`.
        path_to_scaler: basestring, optional
            The path where the scaler which was applied before the neural network is saved. Note that if the neural
            network was trained on scaled data and now you do not pass the correct scaler, the behavior will not be
            correct, leading to wrong inference. Default to None.
        input_size : integer, optional
            if the neural network is an instance of abcpy.NN_utilities.networks.DefaultNN with some input and
            output size, then you should provide here the input size of the network. It has to be provided together with
            the corresponding output_size, and it must not be provided with `network_class`.
        output_size : integer, optional
            if the neural network is an instance of abcpy.NN_utilities.networks.DefaultNN with some input and
            output size, then you should provide here the output size of the network. It has to be provided together
            with the corresponding input_size, and it must not be provided with `network_class`.
        hidden_sizes : array-like, optional
            if the neural network is an instance of abcpy.NN_utilities.networks.DefaultNN with some input and
            output size, then you can provide here an array-like with the size of the hidden layers (for instance
            [5,7,5] denotes 3 hidden layers with correspondingly 5,7,5 neurons). In case this parameter is not provided,
            the hidden sizes are determined from the input and output sizes as determined in
            abcpy.NN_utilities.networks.DefaultNN. Note that this must not be provided together with `network_class`.
        degree: integer, optional
            Of polynomial expansion. The default value is 2 meaning second order polynomial expansion.
        cross: boolean, optional
            Defines whether to include the cross-product terms. The default value is True, meaning the cross product term
            is included.
        reference_simulations: array, optional
            A numpy array with shape (n_samples, output_size) containing a set of reference simulations. If provided,
            statistics are computed at initialization for all reference simulations, and the standard deviation of the
            different statistics is extracted. The standard deviation is then used to standardize the summary
            statistics each time they are compute on a new observation or simulation. Defaults to None, in which case
            standardization is not applied.
        previous_statistics : abcpy.statistics.Statistics, optional
            It allows pipelining of Statistics. Specifically, if the final statistic to be used is determined by the
            composition of two Statistics, you can pass the first here; then, whenever the final statistic is needed, it
            is sufficient to call the `statistics` method of the second one, and that will automatically apply both
            transformations. In this case, this is the statistics that has to be computed before the neural network
            transformation is applied.
        Returns
        -------
        abcpy.statistics.NeuralEmbedding
            the `NeuralEmbedding` object with the neural network obtained from the specified file.
        """
        if not has_torch:
            raise ImportError(
                "Pytorch is required to instantiate an element of the {} class, in order to handle "
                "neural networks. Please install it. ".format(cls.__name__))

        if network_class is None and (input_size is None
                                      or output_size is None):
            raise RuntimeError(
                "You need to pass either network class or both input_size and output_size."
            )
        if network_class is not None and (input_size is not None
                                          or output_size is not None):
            raise RuntimeError(
                "You can't pass together network_class and one of input_size, output_size"
            )
        if network_class is not None and hidden_sizes is not None:
            raise RuntimeError(
                "You passed hidden_sizes as an argument, but that may be passed only if you are passing "
                "input_size and input_size as well, and you are not passing network_class."
            )

        if network_class is None:
            network_class = createDefaultNN(input_size=input_size,
                                            output_size=output_size,
                                            hidden_sizes=hidden_sizes)

        # the stored state_dict could be either a simple network or a network wrapped with DiscardLastOutput (in case
        # the statistics was learned with the Exponential Family method); while instead the network class refers only to
        # the actual net. Therefore need to try and load in both ways
        try:
            net = load_net(path_to_net_state_dict, network_class)
        except RuntimeError:
            net = load_net(path_to_net_state_dict, DiscardLastOutputNet,
                           network_class())

        if path_to_scaler is not None:
            f = open(path_to_scaler, 'rb')
            scaler = cloudpickle.load(f)
            f.close()
            net = ScalerAndNet(net, scaler)

        statistic_object = cls(net,
                               degree=degree,
                               cross=cross,
                               reference_simulations=reference_simulations,
                               previous_statistics=previous_statistics)

        return statistic_object
예제 #9
0
    def test_errors(self):
        if has_torch:
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    parameters=np.ones((100, 1)))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    simulations_net=createDefaultNN(1, 3))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    parameters_net=createDefaultNN(1, 3))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    noise_type="ciao",
                    use_tqdm=False)
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    noise_type="sphere",
                    variance_reduction=True,
                    use_tqdm=False)
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    simulations=np.ones((100, 1)))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    simulations=np.ones((100, 1, 3)))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    parameters=np.ones((100, 1, 2)))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    simulations=np.ones((100, 1)),
                    parameters=np.zeros((99, 1)))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    parameters_val=np.ones((100, 1)))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    simulations_val=np.ones((100, 1)))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    simulations_val=np.ones((100, 1, 3)))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    parameters_val=np.ones((100, 1, 2)))
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    simulations_val=np.ones((100, 1)),
                    parameters_val=np.zeros((99, 1)))
            with self.assertRaises(TypeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    parameters=[i for i in range(10)],
                    simulations=[i for i in range(10)])
            with self.assertRaises(TypeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    parameters_val=[i for i in range(10)],
                    simulations_val=[i for i in range(10)])
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    lower_bound_simulations=[1, 2, 3])
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    seed=1,
                    upper_bound_simulations=[1, 2, 3])
            with self.assertRaises(RuntimeError):
                self.statisticslearning = ExponentialFamilyScoreMatching(
                    [self.Y],
                    self.statistics_cal,
                    self.backend,
                    n_samples=1000,
                    lower_bound_simulations=np.array([-1000, -1000]),
                    seed=1,
                    upper_bound_simulations=np.array([1000, 1000, 1000]))

            with self.assertRaises(RuntimeError):
                self.statisticslearning_all_defaults.test_losses = [4, 2, 1]
                self.statisticslearning_all_defaults.plot_losses()
            with self.assertRaises(NotImplementedError):
                self.statisticslearning_all_defaults.plot_losses(
                    which_losses="foo")
예제 #10
0
    def setUp(self):
        # define prior and model
        sigma = Uniform([[1], [2]])
        mu = Normal([0, 1])
        self.Y = Normal([mu, sigma])

        # define backend
        self.backend = Backend()

        # define statistics
        self.statistics_cal = Identity(degree=3, cross=False)

        if has_torch:
            self.statisticslearning_all_defaults = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                use_tqdm=False)
            self.statisticslearning_no_sliced = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                sliced=False,
                use_tqdm=False)
            self.statisticslearning_sphere_noise = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                use_tqdm=False,
                noise_type="sphere")
            self.statisticslearning_gaussian_noise = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                use_tqdm=False,
                noise_type="gaussian")
            self.statisticslearning_variance_reduction = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                use_tqdm=False,
                variance_reduction=True)
            self.statisticslearning_no_bn = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                batch_norm=False,
                use_tqdm=False)
            self.statisticslearning_provide_nets = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                simulations_net=createDefaultNN(3, 3)(),
                parameters_net=createDefaultNN(2, 2)(),
                use_tqdm=False)
            self.statisticslearning_embedding_dim = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                embedding_dimension=4,
                use_tqdm=False)
            self.statisticslearning_validation_early_stop = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=20,
                n_samples_val=20,
                early_stopping=True,
                use_tqdm=False)
            self.statisticslearning_scale = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                scale_samples=False,
                scale_parameters=True,
                use_tqdm=False)
            self.statisticslearning_bounds = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                lower_bound_simulations=np.array([-1000, -1000, -1000]),
                upper_bound_simulations=np.array([1000, 1000, 1000]),
                use_tqdm=False,
                seed=1)
            self.statisticslearning_no_schedulers = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                scheduler_parameters=False,
                scheduler_simulations=False,
                use_tqdm=False)
            self.statisticslearning_lam = ExponentialFamilyScoreMatching(
                [self.Y],
                self.statistics_cal,
                self.backend,
                n_samples=4,
                n_epochs=2,
                use_tqdm=False,
                sliced=False,
                lam=0.1)
예제 #11
0
 def test_errors(self):
     if has_torch:
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 parameters=np.ones((100, 1)))
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 embedding_net=createDefaultNN(1, 2))
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 simulations=np.ones((100, 1)))
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 simulations=np.ones((100, 1, 3)))
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 parameters=np.ones((100, 1, 2)))
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 simulations=np.ones((100, 1)),
                 parameters=np.zeros((99, 1)))
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 parameters_val=np.ones((100, 1)))
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 simulations_val=np.ones((100, 1)))
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 simulations_val=np.ones((100, 1, 3)))
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 parameters_val=np.ones((100, 1, 2)))
         with self.assertRaises(RuntimeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 simulations_val=np.ones((100, 1)),
                 parameters_val=np.zeros((99, 1)))
         with self.assertRaises(TypeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 parameters=[i for i in range(10)],
                 simulations=[i for i in range(10)])
         with self.assertRaises(TypeError):
             self.statisticslearning = SemiautomaticNN(
                 [self.Y],
                 self.statistics_cal,
                 self.backend,
                 n_samples=1000,
                 n_samples_per_param=1,
                 seed=1,
                 parameters_val=[i for i in range(10)],
                 simulations_val=[i for i in range(10)])
         with self.assertRaises(RuntimeError):
             self.statisticslearning2.test_losses = [4, 2, 1]
             self.statisticslearning2.plot_losses()
         with self.assertRaises(NotImplementedError):
             self.statisticslearning.plot_losses(which_losses="foo")
예제 #12
0
 def setUp(self):
     if has_torch:
         self.net = createDefaultNN(2, 3)()
예제 #13
0
    def __init__(self,
                 model,
                 statistics_calc,
                 backend,
                 training_routine,
                 distance_learning,
                 embedding_net=None,
                 n_samples=1000,
                 n_samples_per_param=1,
                 parameters=None,
                 simulations=None,
                 seed=None,
                 cuda=None,
                 quantile=0.1,
                 **training_routine_kwargs):
        """
        Parameters
        ----------
        model: abcpy.models.Model
            Model object that conforms to the Model class.
        statistics_cal: abcpy.statistics.Statistics
            Statistics object that conforms to the Statistics class.
        backend: abcpy.backends.Backend
            Backend object that conforms to the Backend class.
        training_routine: function
            training routine to train the network. It has to take as first and second arguments the matrix of
            simulations and the corresponding targets (or the similarity matrix if `distance_learning` is True). It also
            needs to have as keyword parameters embedding_net and cuda.
        distance_learning: boolean
            this has to be True if the statistics learning technique is based on distance learning, in which case the
            __init__ computes the similarity matrix.
        embedding_net: torch.nn object or list
            it can be a torch.nn object with input size corresponding to size of model output, alternatively, a list
            with integer numbers denoting the width of the hidden layers, from which a fully connected network with
            that structure is created, having the input and output size corresponding to size of model output and
            number of parameters. In case this is None, the depth of the network and the width of the hidden layers is
            determined from the input and output size as specified in abcpy.NN_utilities.networks.DefaultNN.
        n_samples: int, optional
            The number of (parameter, simulated data) tuple to be generated to learn the summary statistics in pilot
            step. The default value is 1000.
            This is ignored if `simulations` and `parameters` are provided.
        n_samples_per_param: int, optional
            Number of data points in each simulated data set. This is ignored if `simulations` and `parameters` are
            provided. Default to 1.
        parameters: array, optional
            A numpy array with shape (n_samples, n_parameters) that is used, together with `simulations` to fit the
            summary selection learning algorithm. It has to be provided together with `simulations`, in which case no
            other simulations are performed. Default value is None.
        simulations: array, optional
            A numpy array with shape (n_samples, output_size) that is used, together with `parameters` to fit the
            summary selection learning algorithm. It has to be provided together with `parameters`, in which case no
            other simulations are performed. Default value is None.
        seed: integer, optional
            Optional initial seed for the random number generator. The default value is generated randomly.
        cuda: boolean, optional
             If cuda=None, it will select GPU if it is available. Or you can specify True to use GPU or False to use CPU
        quantile: float, optional
            quantile used to define the similarity set if distance_learning is True. Default to 0.1.
        training_routine_kwargs:
            additional kwargs to be passed to the underlying training routine.
        """
        self.logger = logging.getLogger(__name__)

        # Define device
        if not has_torch:
            raise ImportError(
                "Pytorch is required to instantiate an element of the {} class, in order to handle "
                "neural networks. Please install it. ".format(
                    self.__class__.__name__))

        # set random seed for torch as well:
        if seed is not None:
            torch.manual_seed(seed)

        if cuda is None:
            cuda = torch.cuda.is_available()
        elif cuda and not torch.cuda.is_available:
            # if the user requested to use GPU but no GPU is there
            cuda = False
            self.logger.warning(
                "You requested to use GPU but no GPU is available! The computation will proceed on CPU."
            )

        self.device = "cuda" if cuda and torch.cuda.is_available else "cpu"
        if self.device == "cuda":
            self.logger.debug("We are using GPU to train the network.")
        else:
            self.logger.debug("We are using CPU to train the network.")

        # this handles generation of the data (or its formatting in case the data is provided to the Semiautomatic
        # class)
        super(StatisticsLearningNN,
              self).__init__(model, statistics_calc, backend, n_samples,
                             n_samples_per_param, parameters, simulations,
                             seed)

        self.logger.info('Learning of the transformation...')
        # Define Data
        target, simulations_reshaped = self.sample_parameters, self.sample_statistics

        if distance_learning:
            self.logger.debug("Computing similarity matrix...")
            # define the similarity set
            similarity_set = compute_similarity_matrix(target, quantile)
            self.logger.debug("Done")

        # now setup the default neural network or not

        if isinstance(embedding_net, torch.nn.Module):
            self.embedding_net = embedding_net
            self.logger.debug('We use the provided neural network')

        elif isinstance(embedding_net, list) or embedding_net is None:
            # therefore we need to generate the neural network given the list. The following function returns a class
            # of NN with given input size, output size and hidden sizes; then, need () to instantiate the network
            self.embedding_net = createDefaultNN(
                input_size=simulations_reshaped.shape[1],
                output_size=target.shape[1],
                hidden_sizes=embedding_net)()
            self.logger.debug('We generate a default neural network')

        if cuda:
            self.embedding_net.cuda()

        self.logger.debug('We now run the training routine')

        if distance_learning:
            self.embedding_net = training_routine(
                simulations_reshaped,
                similarity_set,
                embedding_net=self.embedding_net,
                cuda=cuda,
                **training_routine_kwargs)
        else:
            self.embedding_net = training_routine(
                simulations_reshaped,
                target,
                embedding_net=self.embedding_net,
                cuda=cuda,
                **training_routine_kwargs)

        self.logger.info("Finished learning the transformation.")