تعلّم نموذج الضوضاء لبوابة
هذا الدرس يوضح تعلّم نموذج ضوضاء لبوابة وحدوية بپروتوكول تعلّم قياسي متاح عبر دوال البروتوكول عالية المستوى prepare_vanilla_program() و process_vanilla_result().
-
عرّف البوابة
-
جهّز المحاكاة المحلية
-
جهّز البرنامج الكمي
-
شغّل البرنامج الكمي
-
اقرأ النتائج
الدوائر أدناه تُحاكى محلياً، فهذا الشرح ما يحتاج بيانات اعتماد IBM Quantum®. وللتشغيل على جهاز حقيقي بدلاً من ذلك:
-
الخطوة 1: استبدل
FakeMarrakeshبـ Backend حقيقي. -
الخطوة 2: مرّر ذلك الـ Backend كوضع (mode) للمنفِّذ (executor)، واحذف خيارات المحاكي.
1. عرّف البوابة
البوابة هي BoxOp تحمل طبقة ملتفّة (twirled) من ست بوابات CZ منفصلة.
from qiskit.circuit import QuantumCircuit
from qiskit_ibm_runtime.fake_provider import FakeMarrakesh
from samplomatic import InjectNoise, Tag, Twirl
backend = FakeMarrakesh()
cz_pairs = [(91, 92), (93, 94), (95, 99), (98, 111), (112, 113), (114, 115)]
circuit = QuantumCircuit(backend.num_qubits)
with circuit.box([Twirl(), Tag("cz_gate"), InjectNoise("cz_gate")]):
for pair in cz_pairs:
circuit.cz(*pair)
from qiskit_ibm_runtime import QiskitRuntimeService
backend = QiskitRuntimeService().backend("ibm_marrakesh")
2. جهّز المحاكاة المحلية
مؤشرات باولي داخل كل خريطة محلية بالنسبة للبوابة، وبترتيب تصاعدي للكيوبتات الفيزيائية:
cz_qubits = sorted({qubit for pair in cz_pairs for qubit in pair})
local = {qubit: index for index, qubit in enumerate(cz_qubits)}
local
{91: 0,
92: 1,
93: 2,
94: 3,
95: 4,
98: 5,
99: 6,
111: 7,
112: 8,
113: 9,
114: 10,
115: 11}
عرّف الضوضاء بحد ZZ مترابط وحد XX أضعف على كل زوج CZ، بالإضافة إلى حد Z أحادي الكيوبت في كل مكان؛ ويحصل القياس على حد قلب البت (bit-flip) لكل كيوبت.
from qiskit.quantum_info import PauliLindbladMap
num_qubits = len(cz_qubits)
cz_noise = PauliLindbladMap.from_sparse_list(
[("ZZ", [local[a], local[b]], 8e-4) for a, b in cz_pairs]
+ [("XX", [local[a], local[b]], 4e-4) for a, b in cz_pairs]
+ [("Z", [index], 3e-4) for index in range(num_qubits)],
num_qubits=num_qubits,
)
readout_noise = PauliLindbladMap.from_sparse_list(
[("X", [index], 5e-3) for index in range(num_qubits)], num_qubits=num_qubits
)
ابنِ صندوقاً ليتعلمه القياس.
measurement = QuantumCircuit(backend.num_qubits, num_qubits)
with measurement.box([Twirl(), Tag("readout"), InjectNoise("readout")]):
for clbit, qubit in enumerate(cz_qubits):
measurement.measure(qubit, clbit)
كل إدخال في layer_noise_model يقرن أحد هذه الصناديق بالخريطة التي تُطبَّق عليه. استخدم طريقة محاكاة المثبّتات (stabilizer)، وعيّن seed_simulator لجعل البيانات المحاكاة قابلة لإعادة الإنتاج.
from qiskit_aer import AerSimulator
from qiskit_ibm_runtime import Executor
executor = Executor(
mode=AerSimulator(method="stabilizer"),
options={
"simulator": {
"layer_noise_model": [
(circuit[0], cz_noise),
(measurement[0], readout_noise),
],
"seed_simulator": 1234,
}
},
)
executor = Executor(mode=backend)
3. تجهيز البرنامج الكمّي
استخدم prepare_vanilla_program() لبناء البرنامج الكمّي الذي يحتوي على تجارب التعلّم.
from qiskit_noise_learning.protocols import prepare_vanilla_program
program = prepare_vanilla_program(
backend,
[circuit[0], measurement[0]],
fragment_depths=[2, 16, 64, 128],
num_randomizations=50,
shots_per_randomization=20,
)
print(f"Number of template circuits: {len(program.items)}")
Number of template circuits: 5
4. تشغيل البرنامج الكمّي
أرسل البرنامج الكمّي. هذه الخطوة هي نفسها سواء كان المنفّذ (executor) موجهاً إلى محاكي أو إلى جهاز حقيقي.
result = executor.run(program).result()
5. قراءة النتائج
عالج النتيجة باستخدام process_vanilla_result().
from qiskit_noise_learning.protocols import process_vanilla_result
noise_maps, gate_names, fit = process_vanilla_result(result)
ارسم تناقص الدقة (fidelity) لكل زوج كيوبتات: البيانات والمطابقة الأسية معاً.
fit.plot_qubit_pair_decays(
pairs=cz_pairs,
observable_type="means",
exponential_fit=True,
)