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])
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
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 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_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)
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
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
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")
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)
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")
def setUp(self): if has_torch: self.net = createDefaultNN(2, 3)()
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.")