예제 #1
0
 def test_qgan_training_run_algo_numpy(self):
     """ qgan training run algo numpy test """
     # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
     num_qubits = [2]
     # Batch size
     batch_size = 100
     # Set number of training epochs
     num_epochs = 5
     _qgan = QGAN(
         self._real_data,
         self._bounds,
         num_qubits,
         batch_size,
         num_epochs,
         discriminator=NumPyDiscriminator(n_features=len(num_qubits)),
         snapshot_dir=None)
     _qgan.seed = self.seed
     _qgan.set_generator()
     trained_statevector = _qgan.run(
         QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                         seed_simulator=aqua_globals.random_seed,
                         seed_transpiler=aqua_globals.random_seed))
     trained_qasm = _qgan.run(
         QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                         seed_simulator=aqua_globals.random_seed,
                         seed_transpiler=aqua_globals.random_seed))
     self.assertAlmostEqual(trained_qasm['rel_entr'],
                            trained_statevector['rel_entr'],
                            delta=0.1)
예제 #2
0
    def test_qgan_training_run_algo_numpy_multivariate(self):
        """Test QGAN training using a NumPy discriminator, for multivariate distributions."""
        # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
        num_qubits = [1, 2]
        # Batch size
        batch_size = 100
        # Set number of training epochs
        num_epochs = 5

        # Reshape data in a multi-variate fashion
        # (two independent identically distributed variables,
        # each represented by half of the generated samples)
        real_data = self._real_data.reshape((-1, 2))
        bounds = [self._bounds, self._bounds]

        _qgan = QGAN(real_data,
                     bounds,
                     num_qubits,
                     batch_size,
                     num_epochs,
                     discriminator=NumPyDiscriminator(n_features=len(num_qubits)),
                     snapshot_dir=None)
        _qgan.seed = self.seed
        _qgan.set_generator()
        trained_statevector = _qgan.run(
            QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                            seed_simulator=aqua_globals.random_seed,
                            seed_transpiler=aqua_globals.random_seed))
        trained_qasm = _qgan.run(QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                                                 seed_simulator=aqua_globals.random_seed,
                                                 seed_transpiler=aqua_globals.random_seed))
        self.assertAlmostEqual(trained_qasm['rel_entr'], trained_statevector['rel_entr'], delta=0.1)
예제 #3
0
 def test_qgan_save_model(self):
     """Test the QGAN functionality to store the current model."""
     # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
     num_qubits = [2]
     # Batch size
     batch_size = 100
     # Set number of training epochs
     num_epochs = 5
     with tempfile.TemporaryDirectory() as tmpdirname:
         _qgan = QGAN(self._real_data,
                      self._bounds,
                      num_qubits,
                      batch_size,
                      num_epochs,
                      discriminator=NumPyDiscriminator(n_features=len(num_qubits)),
                      snapshot_dir=tmpdirname)
         _qgan.seed = self.seed
         _qgan.set_generator()
         trained_statevector = _qgan.run(
             QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                             seed_simulator=aqua_globals.random_seed,
                             seed_transpiler=aqua_globals.random_seed))
         trained_qasm = _qgan.run(QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                                                  seed_simulator=aqua_globals.random_seed,
                                                  seed_transpiler=aqua_globals.random_seed))
     self.assertAlmostEqual(trained_qasm['rel_entr'], trained_statevector['rel_entr'], delta=0.1)
예제 #4
0
 def test_qgan_training_run_algo_torch(self):
     """Test QGAN training using a PyTorch discriminator."""
     try:
         # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
         num_qubits = [2]
         # Batch size
         batch_size = 100
         # Set number of training epochs
         num_epochs = 5
         _qgan = QGAN(self._real_data,
                      self._bounds,
                      num_qubits,
                      batch_size,
                      num_epochs,
                      discriminator=PyTorchDiscriminator(n_features=len(num_qubits)),
                      snapshot_dir=None)
         _qgan.seed = self.seed
         _qgan.set_generator()
         trained_statevector = _qgan.run(QuantumInstance(
             BasicAer.get_backend('statevector_simulator'),
             seed_simulator=aqua_globals.random_seed,
             seed_transpiler=aqua_globals.random_seed))
         trained_qasm = _qgan.run(QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                                                  seed_simulator=aqua_globals.random_seed,
                                                  seed_transpiler=aqua_globals.random_seed))
         self.assertAlmostEqual(trained_qasm['rel_entr'],
                                trained_statevector['rel_entr'], delta=0.1)
     except MissingOptionalLibraryError:
         self.skipTest('pytorch not installed, skipping test')
예제 #5
0
class TestQGAN(QiskitAquaTestCase):
    """ Test QGAN """
    def setUp(self):
        super().setUp()

        self.seed = 7
        aqua_globals.random_seed = self.seed
        # Number training data samples
        n_v = 5000
        # Load data samples from log-normal distribution with mean=1 and standard deviation=1
        m_u = 1
        sigma = 1
        self._real_data = aqua_globals.random.lognormal(mean=m_u,
                                                        sigma=sigma,
                                                        size=n_v)
        # Set the data resolution
        # Set upper and lower data values as list of k
        # min/max data values [[min_0,max_0],...,[min_k-1,max_k-1]]
        self._bounds = [0., 3.]
        # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
        num_qubits = [2]
        # Batch size
        batch_size = 100
        # Set number of training epochs
        # num_epochs = 10
        num_epochs = 5

        # Initialize qGAN
        self.qgan = QGAN(self._real_data,
                         self._bounds,
                         num_qubits,
                         batch_size,
                         num_epochs,
                         snapshot_dir=None)
        self.qgan.seed = 7
        # Set quantum instance to run the quantum generator
        self.qi_statevector = QuantumInstance(
            backend=BasicAer.get_backend('statevector_simulator'),
            seed_simulator=2,
            seed_transpiler=2)
        self.qi_qasm = QuantumInstance(
            backend=BasicAer.get_backend('qasm_simulator'),
            shots=1000,
            seed_simulator=2,
            seed_transpiler=2)
        # Set entangler map
        entangler_map = [[0, 1]]

        # Set an initial state for the generator circuit
        init_dist = UniformDistribution(sum(num_qubits),
                                        low=self._bounds[0],
                                        high=self._bounds[1])
        q = QuantumRegister(sum(num_qubits), name='q')
        qc = QuantumCircuit(q)
        init_dist.build(qc, q)
        init_distribution = Custom(num_qubits=sum(num_qubits), circuit=qc)
        # Set variational form
        var_form = RY(sum(num_qubits),
                      depth=1,
                      initial_state=init_distribution,
                      entangler_map=entangler_map,
                      entanglement_gate='cz')
        # Set generator's initial parameters
        init_params = aqua_globals.random.rand(
            var_form._num_parameters) * 2 * 1e-2
        # Set generator circuit
        self.g_var_form = UnivariateVariationalDistribution(
            sum(num_qubits),
            var_form,
            init_params,
            low=self._bounds[0],
            high=self._bounds[1])

        theta = ParameterVector('θ', var_form.num_parameters)
        var_form = var_form.construct_circuit(theta)
        self.g_circuit = UnivariateVariationalDistribution(
            sum(num_qubits),
            var_form,
            init_params,
            low=self._bounds[0],
            high=self._bounds[1])

    def tearDown(self):
        super().tearDown()
        warnings.filterwarnings(action="always", category=DeprecationWarning)

    @data(False, True)
    def test_sample_generation(self, use_circuits):
        """ sample generation test """
        if use_circuits:
            self.qgan.set_generator(generator_circuit=self.g_circuit)
        else:
            # ignore deprecation warnings from the deprecation of VariationalForm as input for
            # the univariate variational distribution
            warnings.filterwarnings("ignore", category=DeprecationWarning)
            self.qgan.set_generator(generator_circuit=self.g_var_form)

        _, weights_statevector = \
            self.qgan._generator.get_output(self.qi_statevector, shots=100)
        samples_qasm, weights_qasm = self.qgan._generator.get_output(
            self.qi_qasm, shots=100)
        samples_qasm, weights_qasm = zip(
            *sorted(zip(samples_qasm, weights_qasm)))
        for i, weight_q in enumerate(weights_qasm):
            self.assertAlmostEqual(weight_q, weights_statevector[i], delta=0.1)

        if not use_circuits:
            warnings.filterwarnings(action="always",
                                    category=DeprecationWarning)

    @data(False, True)
    def test_qgan_training(self, use_circuits):
        """ qgan training test """
        if use_circuits:
            self.qgan.set_generator(generator_circuit=self.g_circuit)
        else:
            # ignore deprecation warnings from the deprecation of VariationalForm as input for
            # the univariate variational distribution
            warnings.filterwarnings("ignore", category=DeprecationWarning)
            self.qgan.set_generator(generator_circuit=self.g_var_form)

        trained_statevector = self.qgan.run(self.qi_statevector)
        trained_qasm = self.qgan.run(self.qi_qasm)
        self.assertAlmostEqual(trained_qasm['rel_entr'],
                               trained_statevector['rel_entr'],
                               delta=0.1)

        if not use_circuits:
            warnings.filterwarnings(action="always",
                                    category=DeprecationWarning)

    def test_qgan_training_run_algo_torch(self):
        """ qgan training run algo torch test """
        try:
            # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
            num_qubits = [2]
            # Batch size
            batch_size = 100
            # Set number of training epochs
            num_epochs = 5
            _qgan = QGAN(
                self._real_data,
                self._bounds,
                num_qubits,
                batch_size,
                num_epochs,
                discriminator=PyTorchDiscriminator(n_features=len(num_qubits)),
                snapshot_dir=None)
            _qgan.seed = self.seed
            _qgan.set_generator()
            trained_statevector = _qgan.run(
                QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                                seed_simulator=aqua_globals.random_seed,
                                seed_transpiler=aqua_globals.random_seed))
            trained_qasm = _qgan.run(
                QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                                seed_simulator=aqua_globals.random_seed,
                                seed_transpiler=aqua_globals.random_seed))
            self.assertAlmostEqual(trained_qasm['rel_entr'],
                                   trained_statevector['rel_entr'],
                                   delta=0.1)
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(str(ex))

    def test_qgan_training_run_algo_numpy(self):
        """ qgan training run algo numpy test """
        # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
        num_qubits = [2]
        # Batch size
        batch_size = 100
        # Set number of training epochs
        num_epochs = 5
        _qgan = QGAN(
            self._real_data,
            self._bounds,
            num_qubits,
            batch_size,
            num_epochs,
            discriminator=NumPyDiscriminator(n_features=len(num_qubits)),
            snapshot_dir=None)
        _qgan.seed = self.seed
        _qgan.set_generator()
        trained_statevector = _qgan.run(
            QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                            seed_simulator=aqua_globals.random_seed,
                            seed_transpiler=aqua_globals.random_seed))
        trained_qasm = _qgan.run(
            QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                            seed_simulator=aqua_globals.random_seed,
                            seed_transpiler=aqua_globals.random_seed))
        self.assertAlmostEqual(trained_qasm['rel_entr'],
                               trained_statevector['rel_entr'],
                               delta=0.1)
예제 #6
0
class TestQGAN(QiskitAquaTestCase):
    """Test the QGAN algorithm."""

    def setUp(self):
        super().setUp()

        self.seed = 7
        aqua_globals.random_seed = self.seed
        # Number training data samples
        n_v = 5000
        # Load data samples from log-normal distribution with mean=1 and standard deviation=1
        m_u = 1
        sigma = 1
        self._real_data = aqua_globals.random.lognormal(mean=m_u, sigma=sigma, size=n_v)
        # Set upper and lower data values as list of k
        # min/max data values [[min_0,max_0],...,[min_k-1,max_k-1]]
        self._bounds = [0., 3.]
        # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
        num_qubits = [2]
        # Batch size
        batch_size = 100
        # Set number of training epochs
        # num_epochs = 10
        num_epochs = 5

        # Initialize qGAN
        self.qgan = QGAN(self._real_data,
                         self._bounds,
                         num_qubits,
                         batch_size,
                         num_epochs,
                         snapshot_dir=None)
        self.qgan.seed = 7
        # Set quantum instance to run the quantum generator
        self.qi_statevector = QuantumInstance(backend=BasicAer.get_backend('statevector_simulator'),
                                              seed_simulator=2,
                                              seed_transpiler=2)
        self.qi_qasm = QuantumInstance(backend=BasicAer.get_backend('qasm_simulator'),
                                       shots=1000,
                                       seed_simulator=2,
                                       seed_transpiler=2)
        # Set entangler map
        entangler_map = [[0, 1]]

        # Set an initial state for the generator circuit
        init_dist = UniformDistribution(sum(num_qubits), low=self._bounds[0], high=self._bounds[1])
        q = QuantumRegister(sum(num_qubits), name='q')
        qc = QuantumCircuit(q)
        init_dist.build(qc, q)
        init_distribution = Custom(num_qubits=sum(num_qubits), circuit=qc)

        # Set generator's initial parameters
        init_params = aqua_globals.random.random(2 * sum(num_qubits)) * 2 * 1e-2

        # Set variational form
        var_form = RealAmplitudes(sum(num_qubits), reps=1, initial_state=init_distribution,
                                  entanglement=entangler_map)
        self.generator_circuit = var_form
        warnings.filterwarnings('ignore', category=DeprecationWarning)
        self.generator_factory = UnivariateVariationalDistribution(sum(num_qubits), var_form,
                                                                   init_params,
                                                                   low=self._bounds[0],
                                                                   high=self._bounds[1])
        warnings.filterwarnings('always', category=DeprecationWarning)

    @data('circuit', 'factory')
    def test_sample_generation(self, circuit_type):
        """Test sample generation."""
        if circuit_type == 'factory':
            warnings.filterwarnings('ignore', category=DeprecationWarning)
            self.qgan.set_generator(generator_circuit=self.generator_factory)
            warnings.filterwarnings('always', category=DeprecationWarning)
        else:
            self.qgan.set_generator(generator_circuit=self.generator_circuit)

        _, weights_statevector = self.qgan._generator.get_output(self.qi_statevector, shots=100)
        samples_qasm, weights_qasm = self.qgan._generator.get_output(self.qi_qasm, shots=100)
        samples_qasm, weights_qasm = zip(*sorted(zip(samples_qasm, weights_qasm)))
        for i, weight_q in enumerate(weights_qasm):
            self.assertAlmostEqual(weight_q, weights_statevector[i], delta=0.1)

    def test_qgan_training_cg(self):
        """Test QGAN training."""
        optimizer = CG(maxiter=1)
        self.qgan.set_generator(generator_circuit=self.generator_circuit,
                                generator_optimizer=optimizer)
        trained_statevector = self.qgan.run(self.qi_statevector)
        trained_qasm = self.qgan.run(self.qi_qasm)
        self.assertAlmostEqual(trained_qasm['rel_entr'], trained_statevector['rel_entr'], delta=0.1)

    def test_qgan_training_cobyla(self):
        """Test QGAN training."""
        optimizer = COBYLA(maxiter=1)
        self.qgan.set_generator(generator_circuit=self.generator_circuit,
                                generator_optimizer=optimizer)
        trained_statevector = self.qgan.run(self.qi_statevector)
        trained_qasm = self.qgan.run(self.qi_qasm)
        self.assertAlmostEqual(trained_qasm['rel_entr'], trained_statevector['rel_entr'], delta=0.1)

    def test_qgan_training(self):
        """Test QGAN training."""
        warnings.filterwarnings('ignore', category=DeprecationWarning)
        self.qgan.set_generator(generator_circuit=self.generator_circuit)
        warnings.filterwarnings('always', category=DeprecationWarning)

        trained_statevector = self.qgan.run(self.qi_statevector)
        trained_qasm = self.qgan.run(self.qi_qasm)
        self.assertAlmostEqual(trained_qasm['rel_entr'], trained_statevector['rel_entr'], delta=0.1)

    def test_qgan_training_run_algo_torch(self):
        """Test QGAN training using a PyTorch discriminator."""
        try:
            # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
            num_qubits = [2]
            # Batch size
            batch_size = 100
            # Set number of training epochs
            num_epochs = 5
            _qgan = QGAN(self._real_data,
                         self._bounds,
                         num_qubits,
                         batch_size,
                         num_epochs,
                         discriminator=PyTorchDiscriminator(n_features=len(num_qubits)),
                         snapshot_dir=None)
            _qgan.seed = self.seed
            _qgan.set_generator()
            trained_statevector = _qgan.run(QuantumInstance(
                BasicAer.get_backend('statevector_simulator'),
                seed_simulator=aqua_globals.random_seed,
                seed_transpiler=aqua_globals.random_seed))
            trained_qasm = _qgan.run(QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                                                     seed_simulator=aqua_globals.random_seed,
                                                     seed_transpiler=aqua_globals.random_seed))
            self.assertAlmostEqual(trained_qasm['rel_entr'],
                                   trained_statevector['rel_entr'], delta=0.1)
        except MissingOptionalLibraryError:
            self.skipTest('pytorch not installed, skipping test')

    def test_qgan_training_run_algo_torch_multivariate(self):
        """Test QGAN training using a PyTorch discriminator, for multivariate distributions."""
        try:
            # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
            num_qubits = [1, 2]
            # Batch size
            batch_size = 100
            # Set number of training epochs
            num_epochs = 5

            # Reshape data in a multi-variate fashion
            # (two independent identically distributed variables,
            # each represented by half of the generated samples)
            real_data = self._real_data.reshape((-1, 2))
            bounds = [self._bounds, self._bounds]

            _qgan = QGAN(real_data,
                         bounds,
                         num_qubits,
                         batch_size,
                         num_epochs,
                         discriminator=PyTorchDiscriminator(n_features=len(num_qubits)),
                         snapshot_dir=None)
            _qgan.seed = self.seed
            _qgan.set_generator()
            trained_statevector = _qgan.run(QuantumInstance(
                BasicAer.get_backend('statevector_simulator'),
                seed_simulator=aqua_globals.random_seed,
                seed_transpiler=aqua_globals.random_seed))
            trained_qasm = _qgan.run(QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                                                     seed_simulator=aqua_globals.random_seed,
                                                     seed_transpiler=aqua_globals.random_seed))
            self.assertAlmostEqual(trained_qasm['rel_entr'],
                                   trained_statevector['rel_entr'], delta=0.1)
        except MissingOptionalLibraryError:
            self.skipTest('pytorch not installed, skipping test')

    def test_qgan_training_run_algo_numpy(self):
        """Test QGAN training using a NumPy discriminator."""
        # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
        num_qubits = [2]
        # Batch size
        batch_size = 100
        # Set number of training epochs
        num_epochs = 5
        _qgan = QGAN(self._real_data,
                     self._bounds,
                     num_qubits,
                     batch_size,
                     num_epochs,
                     discriminator=NumPyDiscriminator(n_features=len(num_qubits)),
                     snapshot_dir=None)
        _qgan.seed = self.seed
        _qgan.set_generator()
        trained_statevector = _qgan.run(
            QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                            seed_simulator=aqua_globals.random_seed,
                            seed_transpiler=aqua_globals.random_seed))
        trained_qasm = _qgan.run(QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                                                 seed_simulator=aqua_globals.random_seed,
                                                 seed_transpiler=aqua_globals.random_seed))
        self.assertAlmostEqual(trained_qasm['rel_entr'], trained_statevector['rel_entr'], delta=0.1)

    def test_qgan_save_model(self):
        """Test the QGAN functionality to store the current model."""
        # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
        num_qubits = [2]
        # Batch size
        batch_size = 100
        # Set number of training epochs
        num_epochs = 5
        with tempfile.TemporaryDirectory() as tmpdirname:
            _qgan = QGAN(self._real_data,
                         self._bounds,
                         num_qubits,
                         batch_size,
                         num_epochs,
                         discriminator=NumPyDiscriminator(n_features=len(num_qubits)),
                         snapshot_dir=tmpdirname)
            _qgan.seed = self.seed
            _qgan.set_generator()
            trained_statevector = _qgan.run(
                QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                                seed_simulator=aqua_globals.random_seed,
                                seed_transpiler=aqua_globals.random_seed))
            trained_qasm = _qgan.run(QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                                                     seed_simulator=aqua_globals.random_seed,
                                                     seed_transpiler=aqua_globals.random_seed))
        self.assertAlmostEqual(trained_qasm['rel_entr'], trained_statevector['rel_entr'], delta=0.1)

    def test_qgan_training_run_algo_numpy_multivariate(self):
        """Test QGAN training using a NumPy discriminator, for multivariate distributions."""
        # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
        num_qubits = [1, 2]
        # Batch size
        batch_size = 100
        # Set number of training epochs
        num_epochs = 5

        # Reshape data in a multi-variate fashion
        # (two independent identically distributed variables,
        # each represented by half of the generated samples)
        real_data = self._real_data.reshape((-1, 2))
        bounds = [self._bounds, self._bounds]

        _qgan = QGAN(real_data,
                     bounds,
                     num_qubits,
                     batch_size,
                     num_epochs,
                     discriminator=NumPyDiscriminator(n_features=len(num_qubits)),
                     snapshot_dir=None)
        _qgan.seed = self.seed
        _qgan.set_generator()
        trained_statevector = _qgan.run(
            QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                            seed_simulator=aqua_globals.random_seed,
                            seed_transpiler=aqua_globals.random_seed))
        trained_qasm = _qgan.run(QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                                                 seed_simulator=aqua_globals.random_seed,
                                                 seed_transpiler=aqua_globals.random_seed))
        self.assertAlmostEqual(trained_qasm['rel_entr'], trained_statevector['rel_entr'], delta=0.1)

    def test_qgan_training_analytic_gradients(self):
        """Test QGAN training with analytic gradients"""
        self.qgan.set_generator(self.generator_circuit)
        numeric_results = self.qgan.run(self.qi_qasm)
        self.qgan.set_generator(self.generator_circuit,
                                generator_gradient=Gradient('param_shift'))
        analytic_results = self.qgan.run(self.qi_qasm)
        self.assertAlmostEqual(numeric_results['rel_entr'],
                               analytic_results['rel_entr'], delta=0.1)
init_distribution = Custom(num_qubits=sum(num_qubits), circuit=qc)
var_form = TwoLocal(int(np.sum(num_qubits)), 'ry', 'cz', entanglement=entangler_map,
                    reps=1, initial_state=init_distribution)
# Set generator's initial parameters
init_params = aqua_globals.random.random(var_form.num_parameters_settable) * 2 * np.pi
# Set generator circuit
g_circuit = UnivariateVariationalDistribution(int(sum(num_qubits)), var_form, init_params,
                                              low=bounds[0], high=bounds[1])
# Set quantum generator
qgan.set_generator(generator_circuit=g_circuit)
# Set classical discriminator neural network
discriminator = NumPyDiscriminator(len(num_qubits))
qgan.set_discriminator(discriminator)


qgan.run(quantum_instance)

# Runtime
end = time.time()
print('qGAN training runtime: ', (end - start)/60., ' min')


# Plot progress w.r.t the generator's and the discriminator's loss function
t_steps = np.arange(num_epochs)
plt.figure(figsize=(6,5))
plt.title("Progress in the loss function")
plt.plot(t_steps, qgan.g_loss, label = "Generator loss function", color = 'mediumvioletred', linewidth = 2)
plt.plot(t_steps, qgan.d_loss, label = "Discriminator loss function", color = 'rebeccapurple', linewidth = 2)
plt.grid()
plt.legend(loc = 'best')
plt.xlabel('time steps')
예제 #8
0
def QGAN_method(kk, num_qubit, epochs, batch, bound, snap, data):
    start = time.time()

    real_data = data

    # In[41]:

    # Number training data samples
    N = 1000

    # Load data samples from log-normal distribution with mean=1 and standard deviation=1
    mu = 1
    sigma = 1

    # real_data = np.random.lognormal(mean = mu, sigma=sigma, size=N)
    # print(real_data)

    # Set the data resolution
    # Set upper and lower data values as list of k min/max data values [[min_0,max_0],...,[min_k-1,max_k-1]]
    bounds = np.array([0, bound])

    # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
    num_qubits = [num_qubit]

    k = kk

    # In[52]:

    # Set number of training epochs
    # Note: The algorithm's runtime can be shortened by reducing the number of training epochs.
    num_epochs = epochs
    # Batch size
    batch_size = batch

    # Initialize qGAN
    qgan = QGAN(real_data,
                bounds,
                num_qubits,
                batch_size,
                num_epochs,
                snapshot_dir=snap)
    qgan.seed = 1
    # Set quantum instance to run the quantum generator
    quantum_instance = QuantumInstance(
        backend=BasicAer.get_backend('statevector_simulator'))

    # Set entangler map
    entangler_map = [[0, 1]]

    # Set an initial state for the generator circuit
    init_dist = UniformDistribution(sum(num_qubits),
                                    low=bounds[0],
                                    high=bounds[1])
    q = QuantumRegister(sum(num_qubits), name='q')
    qc = QuantumCircuit(q)
    init_dist.build(qc, q)
    init_distribution = Custom(num_qubits=sum(num_qubits), circuit=qc)
    var_form = RY(int(np.sum(num_qubits)),
                  depth=k,
                  initial_state=init_distribution,
                  entangler_map=entangler_map,
                  entanglement_gate='cz')

    # Set generator's initial parameters
    init_params = aqua_globals.random.rand(
        var_form._num_parameters) * 2 * np.pi
    # Set generator circuit
    g_circuit = UnivariateVariationalDistribution(int(sum(num_qubits)),
                                                  var_form,
                                                  init_params,
                                                  low=bounds[0],
                                                  high=bounds[1])
    # Set quantum generator
    qgan.set_generator(generator_circuit=g_circuit)
    # Set classical discriminator neural network
    discriminator = NumPyDiscriminator(len(num_qubits))
    qgan.set_discriminator(discriminator)

    # In[53]:

    # Run qGAN
    qgan.run(quantum_instance)

    # Runtime
    end = time.time()
    print('qGAN training runtime: ', (end - start) / 60., ' min')

    return qgan
예제 #9
0
class TestQGAN(QiskitAquaTestCase):
    """Test the QGAN algorithm."""
    def setUp(self):
        super().setUp()

        self.seed = 7
        aqua_globals.random_seed = self.seed
        # Number training data samples
        n_v = 5000
        # Load data samples from log-normal distribution with mean=1 and standard deviation=1
        m_u = 1
        sigma = 1
        self._real_data = aqua_globals.random.lognormal(mean=m_u,
                                                        sigma=sigma,
                                                        size=n_v)
        # Set upper and lower data values as list of k
        # min/max data values [[min_0,max_0],...,[min_k-1,max_k-1]]
        self._bounds = [0., 3.]
        # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
        num_qubits = [2]
        # Batch size
        batch_size = 100
        # Set number of training epochs
        # num_epochs = 10
        num_epochs = 5

        # Initialize qGAN
        self.qgan = QGAN(self._real_data,
                         self._bounds,
                         num_qubits,
                         batch_size,
                         num_epochs,
                         snapshot_dir=None)
        self.qgan.seed = 7
        # Set quantum instance to run the quantum generator
        self.qi_statevector = QuantumInstance(
            backend=BasicAer.get_backend('statevector_simulator'),
            seed_simulator=2,
            seed_transpiler=2)
        self.qi_qasm = QuantumInstance(
            backend=BasicAer.get_backend('qasm_simulator'),
            shots=1000,
            seed_simulator=2,
            seed_transpiler=2)
        # Set entangler map
        entangler_map = [[0, 1]]

        # Set an initial state for the generator circuit
        init_dist = UniformDistribution(sum(num_qubits),
                                        low=self._bounds[0],
                                        high=self._bounds[1])
        q = QuantumRegister(sum(num_qubits), name='q')
        qc = QuantumCircuit(q)
        init_dist.build(qc, q)
        init_distribution = Custom(num_qubits=sum(num_qubits), circuit=qc)

        # Set generator's initial parameters
        init_params = aqua_globals.random.random(
            2 * sum(num_qubits)) * 2 * 1e-2

        # Set variational form
        var_form = RealAmplitudes(sum(num_qubits),
                                  reps=1,
                                  initial_state=init_distribution,
                                  entanglement=entangler_map)
        self.generator_circuit = UnivariateVariationalDistribution(
            sum(num_qubits),
            var_form,
            init_params,
            low=self._bounds[0],
            high=self._bounds[1])

    def test_sample_generation(self):
        """Test sample generation."""
        self.qgan.set_generator(generator_circuit=self.generator_circuit)
        _, weights_statevector = self.qgan._generator.get_output(
            self.qi_statevector, shots=100)
        samples_qasm, weights_qasm = self.qgan._generator.get_output(
            self.qi_qasm, shots=100)
        samples_qasm, weights_qasm = zip(
            *sorted(zip(samples_qasm, weights_qasm)))
        for i, weight_q in enumerate(weights_qasm):
            self.assertAlmostEqual(weight_q, weights_statevector[i], delta=0.1)

    def test_qgan_training(self):
        """Test QGAN training."""
        self.qgan.set_generator(generator_circuit=self.generator_circuit)
        trained_statevector = self.qgan.run(self.qi_statevector)
        trained_qasm = self.qgan.run(self.qi_qasm)
        self.assertAlmostEqual(trained_qasm['rel_entr'],
                               trained_statevector['rel_entr'],
                               delta=0.1)

    def test_qgan_training_run_algo_torch(self):
        """Test QGAN training using a PyTorch discriminator."""
        try:
            # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
            num_qubits = [2]
            # Batch size
            batch_size = 100
            # Set number of training epochs
            num_epochs = 5
            _qgan = QGAN(
                self._real_data,
                self._bounds,
                num_qubits,
                batch_size,
                num_epochs,
                discriminator=PyTorchDiscriminator(n_features=len(num_qubits)),
                snapshot_dir=None)
            _qgan.seed = self.seed
            _qgan.set_generator()
            trained_statevector = _qgan.run(
                QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                                seed_simulator=aqua_globals.random_seed,
                                seed_transpiler=aqua_globals.random_seed))
            trained_qasm = _qgan.run(
                QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                                seed_simulator=aqua_globals.random_seed,
                                seed_transpiler=aqua_globals.random_seed))
            self.assertAlmostEqual(trained_qasm['rel_entr'],
                                   trained_statevector['rel_entr'],
                                   delta=0.1)
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(str(ex))

    def test_qgan_training_run_algo_numpy(self):
        """Test QGAN training using a NumPy discriminator."""
        # Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
        num_qubits = [2]
        # Batch size
        batch_size = 100
        # Set number of training epochs
        num_epochs = 5
        _qgan = QGAN(
            self._real_data,
            self._bounds,
            num_qubits,
            batch_size,
            num_epochs,
            discriminator=NumPyDiscriminator(n_features=len(num_qubits)),
            snapshot_dir=None)
        _qgan.seed = self.seed
        _qgan.set_generator()
        trained_statevector = _qgan.run(
            QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                            seed_simulator=aqua_globals.random_seed,
                            seed_transpiler=aqua_globals.random_seed))
        trained_qasm = _qgan.run(
            QuantumInstance(BasicAer.get_backend('qasm_simulator'),
                            seed_simulator=aqua_globals.random_seed,
                            seed_transpiler=aqua_globals.random_seed))
        self.assertAlmostEqual(trained_qasm['rel_entr'],
                               trained_statevector['rel_entr'],
                               delta=0.1)