squ11z1 commited on
Commit
3e58e87
·
verified ·
1 Parent(s): b715983

Delete quantum_kernel.py

Browse files
Files changed (1) hide show
  1. quantum_kernel.py +0 -376
quantum_kernel.py DELETED
@@ -1,376 +0,0 @@
1
- """
2
- Быстрое создание квантового ядра для IBM Quantum
3
- Оптимизировано для выполнения за ~8 минут
4
- """
5
-
6
- # ===== ШАГ 1: УСТАНОВКА И ИМПОРТЫ =====
7
- # Выполните в терминале:
8
- # pip install qiskit qiskit-ibm-runtime qiskit-machine-learning scikit-learn
9
-
10
- import numpy as np
11
- from sklearn.datasets import make_classification
12
- from sklearn.model_selection import train_test_split
13
- from sklearn.svm import SVC
14
- from sklearn.metrics import accuracy_score
15
-
16
- from qiskit import QuantumCircuit
17
- from qiskit.circuit import ParameterVector
18
- from qiskit.circuit.library import ZZFeatureMap, PauliFeatureMap
19
- from qiskit_ibm_runtime import QiskitRuntimeService, Sampler
20
- from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
21
-
22
- # ===== ШАГ 2: СОЗДАНИЕ ДАННЫХ =====
23
- # Создаём простой датасет для бинарной классификации
24
- print("Создание датасета...")
25
-
26
- # Рассчитываем оптимальный размер на основе вашей скорости
27
- # Ваша скорость: 108 схем за 44.3 секунды = 2.44 схемы/сек
28
- # Доступно времени: ~7.5 минут = 450 секунд
29
- # Максимум схем: 450 * 2.44 = ~1100 схем
30
- # Оптимально: ~900 схем (запас 20%)
31
-
32
- # Для 900 схем нужно: sqrt(900 * 0.75) ≈ 26 train образцов
33
- # 26 train + 9 test = 35 образцов → 26^2 + 9*26 = 676 + 234 = 910 схем
34
-
35
- X, y = make_classification(
36
- n_samples=35, # Оптимально под вашу скорость!
37
- n_features=4, # 4 признака -> 2 кубита
38
- n_informative=4,
39
- n_redundant=0,
40
- n_clusters_per_class=1,
41
- random_state=42
42
- )
43
-
44
- # Нормализация данных в диапазон [0, 2π]
45
- X_min, X_max = X.min(), X.max()
46
- X_normalized = 2 * np.pi * (X - X_min) / (X_max - X_min)
47
-
48
- # Разделение на train/test (74/26)
49
- X_train, X_test, y_train, y_test = train_test_split(
50
- X_normalized, y, test_size=0.26, random_state=42 # ~26 train, ~9 test
51
- )
52
-
53
- print(f"Train: {len(X_train)} образцов, Test: {len(X_test)} образцов")
54
- total_circuits = len(X_train)**2 + len(X_test)*len(X_train)
55
- expected_time = total_circuits / 2.44 # На основе вашей реальной скорости
56
- print(f"ВАЖНО: Общее количество схем = {len(X_train)**2} + {len(X_test)*len(X_train)} = {total_circuits}")
57
- print(f"📊 Ожидаемое время (на основе вашей скорости 2.44 схем/сек):")
58
- print(f" ~{expected_time:.0f} секунд ({expected_time/60:.1f} минут)")
59
- print(f" Запас до 8 минут: {8 - expected_time/60:.1f} минут")
60
-
61
- # ===== ШАГ 3: СОЗДАНИЕ FEATURE MAP =====
62
- num_qubits = 2 # Используем 2 кубита (4 признака / 2)
63
-
64
- # ZZFeatureMap с минимальными reps для ibm_fez
65
- feature_map = ZZFeatureMap(
66
- feature_dimension=num_qubits,
67
- reps=1, # МИНИМУМ для экономии времени!
68
- entanglement='linear'
69
- )
70
-
71
- print(f"\nFeature map создана с {num_qubits} кубитами")
72
- print(f"Количество параметров: {feature_map.num_parameters}")
73
- print(f"Глубина схемы: {feature_map.depth()}")
74
-
75
- # ===== ШАГ 4: ПОДКЛЮЧЕНИЕ К IBM QUANTUM =====
76
- print("\nПодключение к IBM Quantum...")
77
-
78
- # ibm_quantum_platform - это канал по умолчанию, можно не указывать
79
- try:
80
- # Простейший вариант: token + instance (необязательно)
81
- service = QiskitRuntimeService(token='YDU7vuX8jQb4gFHEaxnLPkuyg05ueEzfB2baajl3dmP_')
82
-
83
- # Сохраняем для будущего использования
84
- QiskitRuntimeService.save_account(
85
- token='YDU7vuX8jQb4gFHEaxnLPkuyg05ueEzfB2baajl3dmP_',
86
- overwrite=True
87
- )
88
- print("✅ API токен успешно сохранён!")
89
- print("✅ Подключение установлено!")
90
-
91
- except Exception as e:
92
- print(f"❌ Ошибка подключения: {e}")
93
- raise
94
-
95
- # Подключаемся к ibm_fez (реальный квантовый компьютер!)
96
- try:
97
- backend = service.backend('ibm_fez')
98
- print(f"\n{'='*50}")
99
- print(f"Используем РЕАЛЬНЫЙ квантовый компьютер: {backend.name}")
100
- print(f"Количество кубитов: {backend.num_qubits}")
101
- print(f"Статус: {'✅ Operational' if backend.status().operational else '❌ Not operational'}")
102
- print(f"{'='*50}\n")
103
- except Exception as e:
104
- print(f"\n⚠️ Backend ibm_fez недоступен: {e}")
105
- print("\nДоступные backends:")
106
- backends = service.backends()
107
- for b in backends:
108
- status = "✅" if b.status().operational else "❌"
109
- print(f" {status} {b.name} ({b.num_qubits} qubits)")
110
-
111
- print("\n💡 Используем наименее загруженный backend...")
112
- backend = service.least_busy(operational=True, simulator=False, min_num_qubits=2)
113
- print(f"Выбран: {backend.name}\n")
114
-
115
- # ===== ШАГ 5: ФУНКЦИЯ ДЛЯ ВЫЧИСЛЕНИЯ ЯДРА =====
116
- def compute_kernel_matrix(X1, X2, feature_map, backend, shots=1024):
117
- """
118
- Вычисляет матрицу квантового ядра между X1 и X2
119
-
120
- Параметры:
121
- - X1, X2: массивы данных
122
- - feature_map: квантовая карта признаков
123
- - backend: IBM Quantum backend
124
- - shots: количество измерений на схему
125
- """
126
- n1, n2 = len(X1), len(X2)
127
- kernel_matrix = np.zeros((n1, n2))
128
-
129
- circuits = []
130
- indices = []
131
-
132
- # Создаём схемы для всех пар (i, j)
133
- for i in range(n1):
134
- for j in range(n2):
135
- # Берём только первые num_qubits признаков
136
- x1_features = X1[i][:num_qubits]
137
- x2_features = X2[j][:num_qubits]
138
-
139
- # Создаём overlap circuit
140
- qc = QuantumCircuit(num_qubits)
141
-
142
- # Применяем feature map для x1
143
- qc.compose(feature_map.assign_parameters(x1_features), inplace=True)
144
-
145
- # Применяем inverse feature map для x2
146
- qc.compose(
147
- feature_map.assign_parameters(x2_features).inverse(),
148
- inplace=True
149
- )
150
-
151
- qc.measure_all()
152
- circuits.append(qc)
153
- indices.append((i, j))
154
-
155
- # Оптимизация схем для ibm_fez
156
- print(f"Транспиляция {len(circuits)} схем для ibm_fez...")
157
- pm = generate_preset_pass_manager(
158
- optimization_level=2, # Хороший баланс для реального QPU
159
- backend=backend
160
- )
161
- transpiled_circuits = pm.run(circuits)
162
-
163
- # Выполнение на квантовом компьютере ibm_fez
164
- print(f"Отправка задачи на {backend.name} (shots={shots})...")
165
- print("⏳ Ожидание выполнения на реальном квантовом компьютере...")
166
-
167
- sampler = Sampler(mode=backend)
168
- job = sampler.run(transpiled_circuits, shots=shots)
169
-
170
- # Показываем ID задачи для отслеживания
171
- print(f"Job ID: {job.job_id()}")
172
- print(f"Статус: {job.status()}")
173
-
174
- result = job.result()
175
- print("✅ Выполнение завершено!")
176
-
177
- # Обработка результатов
178
- for idx, (i, j) in enumerate(indices):
179
- counts = result[idx].data.meas.get_counts()
180
- # Вероятность измерить |00...0>
181
- zero_state = '0' * num_qubits
182
- prob_zero = counts.get(zero_state, 0) / shots
183
- kernel_matrix[i, j] = prob_zero
184
-
185
- return kernel_matrix
186
-
187
- # ===== ШАГ 6: ВЫЧИСЛЕНИЕ МАТРИЦ ЯДРА =====
188
- print("\n" + "="*60)
189
- print("ВЫЧИСЛЕНИЕ КВАНТОВОГО ЯДРА НА IBM_FEZ")
190
- print("="*60)
191
-
192
- # Для реального QPU используем меньше shots для экономии времени
193
- shots = 1024 # Минимум для приемлемой точности
194
-
195
- import time
196
- start_time = time.time()
197
-
198
- # Вычисляем матрицу ядра для обучающих данных
199
- print(f"\n🔬 Вычисление K_train ({len(X_train)}x{len(X_train)} = {len(X_train)**2} схем)...")
200
- K_train = compute_kernel_matrix(X_train, X_train, feature_map, backend, shots)
201
- train_time = time.time() - start_time
202
- print(f"⏱️ Время: {train_time:.1f} секунд")
203
-
204
- # Вычисляем матрицу ядра для тестовых данных
205
- print(f"\n🔬 Вычисление K_test ({len(X_test)}x{len(X_train)} = {len(X_test)*len(X_train)} схем)...")
206
- K_test = compute_kernel_matrix(X_test, X_train, feature_map, backend, shots)
207
- test_time = time.time() - start_time - train_time
208
- print(f"⏱️ Время: {test_time:.1f} секунд")
209
-
210
- total_time = time.time() - start_time
211
- print(f"\n✅ Все матрицы ядра готовы!")
212
- print(f"📊 Общее время выполнения: {total_time:.1f} секунд ({total_time/60:.2f} минут)")
213
- print(f"K_train shape: {K_train.shape}")
214
- print(f"K_test shape: {K_test.shape}")
215
-
216
- # ===== ШАГ 7: ОБУЧЕНИЕ SVM =====
217
- print("\n=== ОБУЧЕНИЕ SVM КЛАССИФИКАТОРА ===")
218
-
219
- # Используем SVM с предвычисленным ядром
220
- svm = SVC(kernel='precomputed')
221
- svm.fit(K_train, y_train)
222
-
223
- # Предсказание
224
- y_pred = svm.predict(K_test)
225
-
226
- # Оценка точности
227
- accuracy = accuracy_score(y_test, y_pred)
228
- print(f"\nТочность на тестовой выборке: {accuracy:.2%}")
229
-
230
- # ===== ШАГ 8: ВИЗУАЛИЗАЦИЯ =====
231
- print("\n=== ВИЗУАЛИЗАЦИЯ РЕЗУЛЬТАТОВ ===")
232
-
233
- import matplotlib.pyplot as plt
234
-
235
- fig, axes = plt.subplots(1, 2, figsize=(12, 5))
236
-
237
- # Визуализация матрицы ядра
238
- im1 = axes[0].imshow(K_train, cmap='hot', interpolation='nearest')
239
- axes[0].set_title('Матрица квантового ядра (Train)')
240
- axes[0].set_xlabel('Образец j')
241
- axes[0].set_ylabel('Образец i')
242
- plt.colorbar(im1, ax=axes[0])
243
-
244
- # Визуализация предсказаний
245
- axes[1].scatter(range(len(y_test)), y_test, c='blue',
246
- marker='o', label='Истинные метки', s=100)
247
- axes[1].scatter(range(len(y_pred)), y_pred, c='red',
248
- marker='x', label='Предсказания', s=100)
249
- axes[1].set_title('Предсказания vs Истинные метки')
250
- axes[1].set_xlabel('Индекс образца')
251
- axes[1].set_ylabel('Класс')
252
- axes[1].legend()
253
- axes[1].grid(True, alpha=0.3)
254
-
255
- plt.tight_layout()
256
- plt.savefig('quantum_kernel_results.png', dpi=150, bbox_inches='tight')
257
- print("График сохранён в 'quantum_kernel_results.png'")
258
- plt.show()
259
-
260
- # ===== ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ =====
261
- print("\n=== ИТОГИ ===")
262
- print(f"Общее количество схем выполнено: {len(X_train)**2 + len(X_test)*len(X_train)}")
263
- print(f"Shots на схему: {shots}")
264
- print(f"Точность классификации: {accuracy:.2%}")
265
- print(f"\nСредние значения в матрице ядра:")
266
- print(f" K_train: min={K_train.min():.3f}, max={K_train.max():.3f}, mean={K_train.mean():.3f}")
267
- print(f" K_test: min={K_test.min():.3f}, max={K_test.max():.3f}, mean={K_test.mean():.3f}")
268
-
269
- # ===== СОХРАНЕНИЕ РЕЗУЛЬТАТОВ =====
270
- print("\n=== СОХРАНЕНИЕ РЕЗУЛЬТАТОВ ===")
271
-
272
- import pickle
273
- import json
274
- from datetime import datetime
275
-
276
- # Создаём папку для результатов
277
- import os
278
- results_dir = "quantum_kernel_results"
279
- os.makedirs(results_dir, exist_ok=True)
280
-
281
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
282
-
283
- # 1. Сохраняем матрицы ядра (numpy arrays)
284
- np.save(f'{results_dir}/K_train_{timestamp}.npy', K_train)
285
- np.save(f'{results_dir}/K_test_{timestamp}.npy', K_test)
286
- print(f"✅ Матрицы ядра сохранены:")
287
- print(f" - {results_dir}/K_train_{timestamp}.npy")
288
- print(f" - {results_dir}/K_test_{timestamp}.npy")
289
-
290
- # 2. Сохраняем данные и метки
291
- np.save(f'{results_dir}/X_train_{timestamp}.npy', X_train)
292
- np.save(f'{results_dir}/X_test_{timestamp}.npy', X_test)
293
- np.save(f'{results_dir}/y_train_{timestamp}.npy', y_train)
294
- np.save(f'{results_dir}/y_test_{timestamp}.npy', y_test)
295
- print(f"✅ Данные и метки сохранены")
296
-
297
- # 3. Сохраняем обученную модель SVM
298
- with open(f'{results_dir}/svm_model_{timestamp}.pkl', 'wb') as f:
299
- pickle.dump(svm, f)
300
- print(f"✅ Модель SVM сохранена: {results_dir}/svm_model_{timestamp}.pkl")
301
-
302
- # 4. Сохраняем метаданные эксперимента
303
- metadata = {
304
- 'timestamp': timestamp,
305
- 'backend': backend.name,
306
- 'num_qubits': num_qubits,
307
- 'shots': shots,
308
- 'num_train_samples': len(X_train),
309
- 'num_test_samples': len(X_test),
310
- 'total_circuits': len(X_train)**2 + len(X_test)*len(X_train),
311
- 'execution_time_seconds': total_time,
312
- 'accuracy': float(accuracy),
313
- 'feature_map': {
314
- 'type': 'ZZFeatureMap',
315
- 'reps': 1,
316
- 'entanglement': 'linear'
317
- },
318
- 'kernel_stats': {
319
- 'K_train_min': float(K_train.min()),
320
- 'K_train_max': float(K_train.max()),
321
- 'K_train_mean': float(K_train.mean()),
322
- 'K_test_min': float(K_test.min()),
323
- 'K_test_max': float(K_test.max()),
324
- 'K_test_mean': float(K_test.mean()),
325
- }
326
- }
327
-
328
- with open(f'{results_dir}/metadata_{timestamp}.json', 'w') as f:
329
- json.dump(metadata, f, indent=2)
330
- print(f"✅ Метаданные сохранены: {results_dir}/metadata_{timestamp}.json")
331
-
332
- # 5. Сохраняем график
333
- plt.savefig(f'{results_dir}/results_{timestamp}.png', dpi=150, bbox_inches='tight')
334
- print(f"✅ График сохранён: {results_dir}/results_{timestamp}.png")
335
-
336
- print(f"\n📁 Все результаты в папке: {results_dir}/")
337
- print("\n" + "="*60)
338
- print("КАК ИСПОЛЬЗОВАТЬ СОХРАНЁННЫЕ ДАННЫЕ:")
339
- print("="*60)
340
- print("""
341
- # Загрузить матрицы ядра:
342
- import numpy as np
343
- K_train = np.load('quantum_kernel_results/K_train_TIMESTAMP.npy')
344
- K_test = np.load('quantum_kernel_results/K_test_TIMESTAMP.npy')
345
-
346
- # Загрузить обученную модель:
347
- import pickle
348
- with open('quantum_kernel_results/svm_model_TIMESTAMP.pkl', 'rb') as f:
349
- svm = pickle.load(f)
350
-
351
- # Использовать для новых предсказаний:
352
- # 1. Вычислите квантовое ядро для но��ых данных X_new
353
- # 2. predictions = svm.predict(K_new)
354
-
355
- # Загрузить метаданные:
356
- import json
357
- with open('quantum_kernel_results/metadata_TIMESTAMP.json', 'r') as f:
358
- metadata = json.load(f)
359
- print(f"Точность модели: {metadata['accuracy']}")
360
- """)
361
-
362
- # СОВЕТЫ ПО ОПТИМИЗАЦИИ ДЛЯ IBM_FEZ:
363
- print("\n" + "="*60)
364
- print("ИСПОЛЬЗОВАНО НА IBM_FEZ:")
365
- print("="*60)
366
- print(f"✅ Образцов данных: {len(X_train) + len(X_test)}")
367
- print(f"✅ Всего схем выполнено: {len(X_train)**2 + len(X_test)*len(X_train)}")
368
- print(f"✅ Shots на схему: {shots}")
369
- print(f"✅ Общее время: {total_time/60:.2f} минут")
370
- remaining = 8 - total_time/60
371
- print(f"✅ Оставшееся время: ~{remaining:.2f} минут")
372
- print(f"\n📈 Статистика:")
373
- print(f" Скорость: ~{(len(X_train)**2 + len(X_test)*len(X_train)) / total_time:.1f} схем/сек")
374
- print(f" Среднее время на схему: ~{total_time / (len(X_train)**2 + len(X_test)*len(X_train)):.2f} сек")
375
- if remaining > 0:
376
- print(f"\n💡 Времени хватило! Можно было выполнить ещё ~{int(remaining * 60 / (total_time / (len(X_train)**2 + len(X_test)*len(X_train))))} схем")