Skip to content

Commit ee1c5f2

Browse files
committed
Create qrbm3.py
1 parent 3875ce7 commit ee1c5f2

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

doc/src/week16/programs/qrbm3.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Code example for a Quantum Boltzmann Machine (QBM) applied to a binary classification problem using PennyLane. This example uses a simplified dataset (XOR problem) and trains a parameterized quantum circuit to model the joint distribution of features and labels.
2+
3+
import pennylane as qml
4+
from pennylane import numpy as np
5+
6+
# Define the target probabilities for the XOR dataset
7+
target_probs = np.zeros(8)
8+
target_indices = [0, 3, 5, 6] # Binary: 000, 011, 101, 110
9+
for idx in target_indices:
10+
target_probs[idx] = 0.25
11+
12+
# Quantum circuit configuration
13+
num_qubits = 3 # 2 features + 1 label
14+
dev = qml.device("default.qubit", wires=num_qubits)
15+
16+
@qml.qnode(dev)
17+
def circuit(params):
18+
# First rotation layer
19+
for i in range(num_qubits):
20+
qml.RX(params[0][i], wires=i)
21+
qml.RY(params[1][i], wires=i)
22+
23+
# Entangling gates
24+
qml.CNOT(wires=[0, 1])
25+
qml.CNOT(wires=[1, 2])
26+
qml.CNOT(wires=[0, 2])
27+
28+
# Second rotation layer
29+
for i in range(num_qubits):
30+
qml.RX(params[2][i], wires=i)
31+
qml.RY(params[3][i], wires=i)
32+
33+
return qml.probs(wires=range(num_qubits))
34+
35+
# Initialize parameters
36+
params = [
37+
np.random.uniform(0, 2*np.pi, size=num_qubits, requires_grad=True),
38+
np.random.uniform(0, 2*np.pi, size=num_qubits, requires_grad=True),
39+
np.random.uniform(0, 2*np.pi, size=num_qubits, requires_grad=True),
40+
np.random.uniform(0, 2*np.pi, size=num_qubits, requires_grad=True)
41+
]
42+
43+
# Cost function (KL divergence)
44+
def cost(params):
45+
model_probs = circuit(params)
46+
cost = 0.0
47+
for idx in target_indices:
48+
q = model_probs[idx]
49+
cost += 0.25 * (np.log(0.25) - np.log(q + 1e-10)) # Add small epsilon to avoid log(0)
50+
return cost
51+
52+
# Optimization
53+
opt = qml.AdamOptimizer(stepsize=0.1)
54+
max_iterations = 100
55+
56+
for i in range(max_iterations):
57+
params, current_cost = opt.step_and_cost(cost, params)
58+
if i % 10 == 0:
59+
print(f"Iteration {i+1}: Cost = {current_cost}")
60+
61+
# Prediction function
62+
def predict(features):
63+
# Calculate probabilities for both possible labels
64+
all_probs = circuit(params)
65+
feature_mask = (int(f"{features[0]}{features[1]}", 2) << 1)
66+
p0 = all_probs[feature_mask]
67+
p1 = all_probs[feature_mask | 1]
68+
total = p0 + p1
69+
return p0/total if total != 0 else 0.5, p1/total if total != 0 else 0.5
70+
71+
# Test the model
72+
test_cases = [(0,0), (0,1), (1,0), (1,1)]
73+
print("\nPredictions:")
74+
for features in test_cases:
75+
prob_0, prob_1 = predict(features)
76+
print(f"Features {features}: P(0)={prob_0:.2f}, P(1)={prob_1:.2f}")
77+
78+
"""
79+
**Key components explained:**
80+
81+
1. **Dataset**: Uses XOR problem with binary features and labels encoded in 3 qubits (2 features, 1 label).
82+
83+
2. **Quantum Circuit**:
84+
- Uses rotation gates (RX, RY) and entangling gates (CNOT)
85+
- Parameters are optimized to match the target distribution
86+
- Outputs probabilities for all possible 8 states
87+
88+
3. **Training**:
89+
- Minimizes KL divergence between model and target probabilities
90+
- Uses Adam optimizer for better convergence
91+
92+
4. **Prediction**:
93+
- Calculates conditional probabilities p(label|features) by marginalizing the joint distribution
94+
- Normalizes probabilities for classification
95+
96+
**Note:** This is a simplified example. For real-world applications, you would need to:
97+
1. Handle continuous features (e.g., using amplitude encoding)
98+
2. Use more sophisticated ansatz architectures
99+
3. Implement proper batching for larger datasets
100+
4. Add regularization to prevent overfitting
101+
102+
The output should show decreasing cost during training and high probabilities for correct labels in predictions. Actual results may vary due to random initialization and optimization challenges.
103+
"""

0 commit comments

Comments
 (0)