Conceptual quantum machinear learning code implment in Qiskit and Q#
- Dominant language
- Jupyter Notebook
- Stars
- 2
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
ChatGPTA: 好的,下面給你各 2 段「能跑」的最小可行範例:一段 **Qiskit(Python)**,一段 **Q#(含 C# host)**。兩者都展示了典型 QML 流程:**資料嵌入(feature map)→ 參數化量子電路(PQC/ansatz)→ 以期望值當作可微損失做訓練(用 parameter-shift 做數值梯度)**。我用最小 XOR 類資料做二分類示範,模型輸出是測量 $Z$ 期望,映成 $[0,1]$ 機率。
---
# Qiskit:PQC 二分類(XOR),手刻 parameter-shift
```python
# pip install qiskit numpy
import numpy as np
from qiskit import QuantumCircuit
from qiskit.circuit import ParameterVector
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives import Estimator
# ----- 1) Toy 資料(XOR) -----
X = np.array([[0.,0.],[0.,1.],[1.,0.],[1.,1.]]) # 兩維特徵
y = np.array([0,1,1,0]) # 標籤 {0,1}
# 簡單角度縮放,映到 [0, 2π)
scale = 2*np.pi
Xang = X * scale
# ----- 2) 量子特徵映射(Ry 角度編碼 + CNOT糾纏) -----
def feature_map(x):
qc = QuantumCircuit(2)
qc.ry(x[0], 0)
qc.ry(x[1], 1)
qc.cx(0, 1)
return qc
# ----- 3) Ansatz(兩層 Ry + CX) -----
def make_ansatz():
theta = ParameterVector("θ", 4) # 4 個可訓參數
qc = QuantumCircuit(2)
# layer 1
qc.ry(theta[0], 0)
qc.ry(theta[1], 1)
qc.cx(0, 1)
# layer 2
qc.ry(theta[2], 0)
qc.ry(theta[3], 1)
return qc, theta
ansatz, theta = make_ansatz()
# 觀測算符:Z ⊗ I(看第一顆量子位的 Z 期望)
observable = SparsePauliOp.from_list([("ZI", 1.0)])
estimator = Estimator() # 走本地模擬後端(如 Statevector/backends 由環境決定)
# ----- 4) 前向:給定 (θ, x),回傳 -----
def expval(theta_vals, x):
qc = QuantumCircuit(2)
qc.compose(feature_map(x), inplace=True)
qc.compose(ansatz, inplace=True)
# 用 Estimator 評估期望值
job = estimator.run([qc], [observable], [dict(zip(theta, theta_vals))])
return job.result().values[0].real # ∈ [-1, 1]
# sigmoid,把期望值映成 [0,1] 機率
def model_prob(theta_vals, x):
z = expval(theta_vals, x) # [-1,1]
p1 = (z + 1)/2 # 當作預測「類別=1」的機率
return np.clip(p1, 1e-6, 1-1e-6)
# 二元交叉熵
def loss(theta_vals):
ps = np.array([model_prob(theta_vals, x) for x in Xang])
ce = -(y*np.log(ps) + (1-y)*np.log(1-ps))
return float(np.mean(ce))
# ----- 5) parameter-shift 梯度 -----
def grad(theta_vals, shift=np.pi/2):
g = np.zeros_like(theta_vals, dtype=float)
for j in range(len(theta_vals)):
tp = theta_vals.copy(); tm = theta_vals.copy()
tp[j] += shift; tm[j] -= shift
g[j] = (loss(tp) - loss(tm)) / 2.0
return g
# ----- 6) 簡單 SGD -----
np.random.seed(0)
theta_vals = np.random.uniform(0, 2*np.pi, len(theta))
lr = 0.2
for it in range(60):
L = loss(theta_vals)
g = grad(theta_vals)
theta_vals -= lr * g
if (it+1) % 10 == 0:
preds = (np.array([model_prob(theta_vals, x) for x in Xang]) > 0.5).astype(int)
acc = (preds == y).mean()
print(f"iter {it+1:02d} | loss={L:.4f} | acc={acc:.2f}")
print("θ* =", theta_vals)
print("pred probs =", [round(model_prob(theta_vals, x), 3) for x in Xang])
```
重點:
* **Ry 角度編碼 + CX** 即為一個簡單 feature map;你也能換成 Qiskit 內建 `PauliFeatureMap`/`ZZFeatureMap`。
* 期望值用 **`Estimator` 原語**算 $\langle Z\otimes I\rangle$,再做 **parameter-shift** 的 $\pm \pi/2$ 數值梯度來更新參數。
---
# Q#:同樣概念的 PQC + C# host 做訓練
**Q# 檔(VariationalClassifier.qs)**
(以 Ry 角度編碼 + CX 糾纏,量測第 0 qubit 的 $Z$ 期望)
```qsharp
namespace QMLDemo {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Math;
operation FeatureMap(x : Double[], qs : Qubit[]) : Unit is Adj + Ctl {
// Ry encoding
Ry(x[0], qs[0]);
Ry(x[1], qs[1]);
CNOT(qs[0], qs[1]);
}
operation Ansatz(theta : Double[], qs : Qubit[]) : Unit is Adj + Ctl {
// layer 1
Ry(theta[0], qs[0]);
Ry(theta[1], qs[1]);
CNOT(qs[0], qs[1]);
// layer 2
Ry(theta[2], qs[0]);
Ry(theta[3], qs[1]);
}
// 以多次 shots 估計 Z⊗I 的期望值,輸出落在 [-1,1]
operation ExpZGivenParams(x : Double[], theta : Double[], shots : Int) : Double {
use qs = Qubit[2];
mutable plusCount = 0;
for _ in 1..shots {
// |00>
ResetAll(qs);
// prepare circuit
FeatureMap(x, qs);
Ansatz(theta, qs);
// 測量 Z on qubit 0
let r = M(qs[0]);
if (r == Zero) { set plusCount += 1; }
// 清場
ResetAll(qs);
}
// p0 - p1 =
let p0 = IntAsDouble(plusCount) / IntAsDouble(shots);
return 2.0 * p0 - 1.0;
}
}
```
**C# host(Program.cs)**
(簡單 SGD + parameter-shift)
```csharp
// dotnet add package Microsoft.Quantum.Development.Kit
// dotnet add package Microsoft.Quantum.Standard
using System;
using System.Linq;
using Microsoft.Quantum.Simulation.Simulators;
using QMLDemo;
class Program {
static double Sigmoid(double z) => 1.0 / (1.0 + Math.Exp(-z));
static double ProbFromZ(double z) => Math.Clamp((z + 1.0)/2.0, 1e-6, 1-1e-6);
static void Main() {
// XOR toy data
double[][] X = {
new double[]{0.0,0.0},
new double[]{0.0,1.0},
new double[]{1.0,0.0},
new double[]{1.0,1.0}
};
int[] y = {0,1,1,0};
double scale = 2*Math.PI;
double[][] Xang = X.Select(v => v.Select(t => t*scale).ToArray()).ToArray();
double[] theta = Enumerable.Range(0,4).Select(_ => 2*Math.PI*new Random().NextDouble()).ToArray();
double lr = 0.2;
int shots = 2000;
double shift = Math.PI/2;
using var sim = new QuantumSimulator();
Func Loss = th => {
double ce = 0.0;
for (int i=0;i 0.5 ? 1 : 0;
if (pred==y[i]) correct++;
}
Console.WriteLine($"iter {it+1:00} | loss={L:F4} | acc={(double)correct/Xang.Length:F2}");
}
}
Console.WriteLine("theta* = ["+string.Join(", ", theta.Select(v=>v.ToString("F3")))+"]");
}
}
```
---
## 補充
* 以上兩個版本都用 **Ry 角度編碼** 當作量子特徵映射;你可以替換成 Qiskit 內建的 `PauliFeatureMap / ZZFeatureMap`,或在 Q# 中自行加入 `Rz`、更多糾纏層。
* 若要走 **kernel 方法**:在 Qiskit 可用 `Statevector` 直接模擬兩個嵌入電路的內積 $|\langle\phi(x)|\phi(x')\rangle|^2$ 來做 Gram 矩陣(之後丟到 SVM)。
---
## 來源(官方文件 / 教學)
* Qiskit `Statevector` 與內積 API(可用來做核的內積或期望值輔助),IBM 官方文件。 ([[quantum.cloud.ibm.com](https://quantum.cloud.ibm.com/docs/api/qiskit/qiskit.quantum_info.Statevector?utm_source=chatgpt.com)][1])
* Qiskit 入門:**Primitives(Estimator / Sampler)** 範例與指南(本例用 Estimator 取期望值)。 ([[quantum.cloud.ibm.com](https://quantum.cloud.ibm.com/docs/guides/primitives-examples?utm_source=chatgpt.com)][2])
* Qiskit 資料編碼與常見 **Feature Map**(含 Z/ZZ/PauliFeatureMap 的設計理念)。 ([[quantum.cloud.ibm.com](https://quantum.cloud.ibm.com/learning/en/courses/quantum-machine-learning/data-encoding?utm_source=chatgpt.com)][3], [[Quantum Computing Stack Exchange](https://quantumcomputing.stackexchange.com/questions/22121/how-does-the-zz-feature-map-influence-the-measurement?utm_source=chatgpt.com)][4])
* 單量子位 **RY** 旋轉 gate 資料(矩陣與在電路中的使用)。 ([[quantum.cloud.ibm.com](https://quantum.cloud.ibm.com/docs/api/qiskit/qiskit.circuit.library.RYGate?utm_source=chatgpt.com)][5])
* Q# 量子運算與旋轉/量測的基礎說明(Ry/測量在 Q# 流程中的位置,含官方與社群討論導引)。 ([[Quantum Computing Stack Exchange](https://quantumcomputing.stackexchange.com/questions/4223/how-to-measure-in-an-arbitrary-basis-in-q?utm_source=chatgpt.com)][6])
如果你想,我可以把 Qiskit 版本改成 **量子核 SVM** 或 **VQE/QAOA** 的模板;或把 Q# 版本換成 **以期望值 API** 的更高效實作(減少 shots 抖動)。你偏好哪一條線?
[1]: https://quantum.cloud.ibm.com/docs/api/qiskit/qiskit.quantum_info.Statevector?utm_source=chatgpt.com "Statevector (latest version) | IBM Quantum Documentation"
[2]: https://quantum.cloud.ibm.com/docs/guides/primitives-examples?utm_source=chatgpt.com "Primitives examples | IBM Quantum Documentation"
[3]: https://quantum.cloud.ibm.com/learning/en/courses/quantum-machine-learning/data-encoding?utm_source=chatgpt.com "Data encoding | IBM Quantum Learning"
[4]: https://quantumcomputing.stackexchange.com/questions/22121/how-does-the-zz-feature-map-influence-the-measurement?utm_source=chatgpt.com "How does the ZZ Feature Map influence the measurement?"
[5]: https://quantum.cloud.ibm.com/docs/api/qiskit/qiskit.circuit.library.RYGate?utm_source=chatgpt.com "RYGate (latest version) | IBM Quantum Documentation"
[6]: https://quantumcomputing.stackexchange.com/questions/4223/how-to-measure-in-an-arbitrary-basis-in-q?utm_source=chatgpt.com "How to measure in an arbitrary basis in Q"
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.