Vietnamese
Ngôn ngữ
English
Bengali
French
Hindi
Italian
Japanese
Korean
Malayalam
Russian
Spanish
Tamil
Turkish
Vietnamese
Shortcuts

Ghi chú

Trang này được tạo từ docs/tutorials/04_qgans_for_loading_random_distributions.ipynb.

các qGAN để tải sự phân phối ngẫu nhiên

Với mẫu dữ liệu \(k\) chiều, chúng tôi sử dụng một Mạng Lượng Tử Đối Địch (qGAN) để tìm hiểu phân phối ngẫu nhiên cơ bản của dữ liệu và tải trực tiếp nó vào trạng thái lượng tử:

\[\big| g_{\theta}\rangle = \sum_{j=0}^{2^n-1} \sqrt{p_{\theta}^{j}}\big| j \rangle\]

với \(p_{\theta}^{j}\) miêu tả xác suất xảy ra của hệ cơ sở trạng thái \(\big| j\rangle\).

Mục đích của việc đào tạo qGAN là để tạo một trạng thái \(\big| g_{\theta}\rangle\) trong đó \(p_{\theta}^{j}\), với \(j\in \left\{0, \ldots, {2^n-1} \right\}\), miêu tả một hàm phân phối xác suất sát với sự phân phối của dữ liệu đào tạo nằm trong đó \(X=\left\{x^0, \ldots, x^{k-1} \right\}\).

Để có thêm chi tiết hãy tham khảo Quantum Generative Adversarial Networks for Learning and Loading Random Distributions Zoufal, Lucchi, Woerner [2019].

Ví dụ về cách sử dụng một qGAN được đào tạo trong một ứng dụng, giá của các phát sinh tài chính, vui lòng xem hướng dẫn ` Quyền chọn (cổ phiếu): Định giá quyền chọn với các qGAN <https://github.com/Qiskit/qiskit-finance/tree/main/docs/tutorials/10_qgan_option_pricing.ipynb>`__.

[1]:
import numpy as np

seed = 71
np.random.seed = seed

import matplotlib.pyplot as plt

%matplotlib inline

from qiskit import QuantumRegister, QuantumCircuit, BasicAer
from qiskit.circuit.library import TwoLocal

from qiskit.utils import QuantumInstance, algorithm_globals
from qiskit_machine_learning.algorithms import NumPyDiscriminator, QGAN

algorithm_globals.random_seed = seed

Tải dữ liệu đào tạo

Đầu tiên, chúng ta cần tải các mẫu dữ liệu đào tạo \(k\)- chiều (ở đây k=1).

Tiếp theo, độ phân giải dữ liệu được đặt, tức các giá trị dữ liệu nhỏ nhất/lớn nhất và số lượng qubit được sử dụng để đại diện cho mỗi chiều dữ liệu.

[2]:
# 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)

# 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.0, 3.0])
# Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]
num_qubits = [2]
k = len(num_qubits)

Khởi tạo qGAN

Qgan bao gồm một bộ tạo lượng tử \(G_{\theta}\), i.e., một ansatz, và một bộ phân loại tách biệt \(D_{\phi}\), một mạng lưới neuron.

Để thi hành một bộ tạo lượng tử, chúng ta chọn ansatz có độ sâu \(1\) thực thi các phép quay \(R_Y\) và các cổng \(CZ\) gates với một trạng thái đầu vào đều liên tục. Cụ thể, cho \(k>1\) tham số của bộ tạo cần được chọn một cách cẩn thận. Ví dụ như, độ sâu của mạch nên \(>1\) vì mạch càng sâu thì cho phép biểu diễn những cấu trúc càng phức tạp.

Bộ tách biệt cổ điển được sử dụng ở đây dựa trên việc thực hiện mạng neuron bằng cách sử dụng NumPy. Ngoài ra còn có một bộ tách biệt dựa trên PyTorch không được cài đặt mặc định khi cài đặt Qiskit - xem Optional Install để có thêm thông tin.

Ở đây, cả hai mạng được cập nhật với thuật toán tối ưu hóa ADAM (ADAM là qGAN tối ưu hóa mặc định).

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

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

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


# Set an initial state for the generator circuit as a uniform distribution
# This corresponds to applying Hadamard gates on all qubits
init_dist = QuantumCircuit(sum(num_qubits))
init_dist.h(init_dist.qubits)

# Set the ansatz circuit
ansatz = TwoLocal(int(np.sum(num_qubits)), "ry", "cz", entanglement=entangler_map, reps=1)

# Set generator's initial parameters - in order to reduce the training time and hence the
# total running time for this notebook
init_params = [3.0, 1.0, 0.6, 1.6]

# You can increase the number of training epochs and use random initial parameters.
# init_params = np.random.rand(ansatz.num_parameters_settable) * 2 * np.pi

# Set generator circuit by adding the initial distribution infront of the ansatz
g_circuit = ansatz.compose(init_dist, front=True)

# Set quantum generator
qgan.set_generator(generator_circuit=g_circuit, generator_init_params=init_params)
# The parameters have an order issue that following is a temp. workaround
qgan._generator._free_parameters = sorted(g_circuit.parameters, key=lambda p: p.name)
# Set classical discriminator neural network
discriminator = NumPyDiscriminator(len(num_qubits))
qgan.set_discriminator(discriminator)

Chạy đào tạo qGAN

Trong quá trình đào tạo các tham số của bộ tách biệt của bộ tạo được cập nhật một cách luân phiên dựa trên các hàm mất mát sau:

\[L_G\left(\phi, \theta\right) = -\frac{1}{m}\sum\limits_{l=1}^{m}\left[\log\left(D_{\phi}\left(g^{l}\right)\right)\right]\]

\[L_D\left(\phi, \theta\right) = \frac{1}{m}\sum\limits_{l=1}^{m}\left[\log D_{\phi}\left(x^{l}\right) + \log\left(1-D_{\phi}\left(g^{l}\right)\right)\right],\]

với \(m\) là kích cỡ của mẻ và \(g^l\) miêu tả những mẫu dữ liệu được tạo bởi bộ tạo lượng tử.

Xin lưu ý rằng việc đào tạo, trong mục đích của notebook này, đã được giữ ngắn gọn hơn bằng cách lựa chọn điểm khởi đầu đã biết (init_params). Nếu không có thông tin như vậy trước thì sự đào tạo có thể mất một thời gian.

[4]:
# Run qGAN
result = qgan.run(quantum_instance)
[5]:
print("Training results:")
for key, value in result.items():
    print(f"  {key} : {value}")
Training results:
  params_d : [ 0.03697158  0.61015372 -0.48103428 ... -0.1661673  -0.20186384
 -0.08584337]
  params_g : [2.95229918 0.9522102  0.55218478 1.64793094]
  loss_d : 0.6925
  loss_g : [0.7246]
  rel_entr : 0.107

Tiến trình đào tạo & kết quả

Bây giờ, chúng ta vẽ đồ thị sự tiến hóa của sự mất mát của bộ tạo và bộ tách biệt trong suốt quá trình đào tạo, cũng như sự tiến bộ trong entropy tương đối giữa các sự phân phối của nhóm được đào tạo và mục tiêu cuối cùng.

Cuối cùng, chúng ta cũng so sánh hàm phân phối tích lũy (CDF) của phân phối được đào tạo với CDF của phân phối mục tiêu.

[6]:
# 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")
plt.ylabel("loss")
plt.show()
../_images/tutorials_04_qgans_for_loading_random_distributions_10_0.png
[7]:
# Plot progress w.r.t relative entropy
plt.figure(figsize=(6, 5))
plt.title("Relative Entropy")
plt.plot(
    np.linspace(0, num_epochs, len(qgan.rel_entr)), qgan.rel_entr, color="mediumblue", lw=4, ls=":"
)
plt.grid()
plt.xlabel("time steps")
plt.ylabel("relative entropy")
plt.show()
../_images/tutorials_04_qgans_for_loading_random_distributions_11_0.png
[8]:
# Plot the CDF of the resulting distribution against the target distribution, i.e. log-normal
log_normal = np.random.lognormal(mean=1, sigma=1, size=100000)
log_normal = np.round(log_normal)
log_normal = log_normal[log_normal <= bounds[1]]
temp = []
for i in range(int(bounds[1] + 1)):
    temp += [np.sum(log_normal == i)]
log_normal = np.array(temp / sum(temp))

plt.figure(figsize=(6, 5))
plt.title("CDF (Cumulative Distribution Function)")
samples_g, prob_g = qgan.generator.get_output(qgan.quantum_instance, shots=10000)
samples_g = np.array(samples_g)
samples_g = samples_g.flatten()
num_bins = len(prob_g)
plt.bar(samples_g, np.cumsum(prob_g), color="royalblue", width=0.8, label="simulation")
plt.plot(
    np.cumsum(log_normal), "-o", label="log-normal", color="deepskyblue", linewidth=4, markersize=12
)
plt.xticks(np.arange(min(samples_g), max(samples_g) + 1, 1.0))
plt.grid()
plt.xlabel("x")
plt.ylabel("p(x)")
plt.legend(loc="best")
plt.show()
../_images/tutorials_04_qgans_for_loading_random_distributions_12_0.png
[9]:
import qiskit.tools.jupyter

%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
QiskitNone
Terra0.17.0.dev0+346ffa8
Aer0.8.0
Ignis0.6.0.dev0+d6f1ad7
AquaNone
IBM Q Provider0.13.0.dev0+10f19e0
System information
Python3.8.8 (default, Feb 24 2021, 13:46:16) [Clang 10.0.0 ]
OSDarwin
CPUs6
Memory (Gb)16.0
Wed Mar 31 23:30:54 2021 CEST

This code is a part of Qiskit

© Copyright IBM 2017, 2021.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.