Skip to content

Commit de9b068

Browse files
committed
Create qnnpytorch.py
1 parent c7d709a commit de9b068

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import pennylane as qml
2+
from pennylane import numpy as np
3+
import torch
4+
import torch.nn as nn
5+
import torch.optim as optim
6+
from torch.utils.data import DataLoader, TensorDataset
7+
8+
# Set random seed for reproducibility
9+
torch.manual_seed(42)
10+
11+
# Quantum device with 2 qubits
12+
n_qubits = 2
13+
dev = qml.device("default.qubit", wires=n_qubits)
14+
15+
# Quantum circuit (variational ansatz)
16+
def quantum_circuit(inputs, weights):
17+
# Encode classical data
18+
for i in range(n_qubits):
19+
qml.RY(inputs[i], wires=i)
20+
21+
# Trainable layer
22+
qml.CNOT(wires=[0, 1])
23+
for i in range(n_qubits):
24+
qml.Rot(*weights[i], wires=i)
25+
26+
# QNode: quantum node that can be called like a function
27+
@qml.qnode(dev, interface="torch")
28+
def qnode(inputs, weights):
29+
quantum_circuit(inputs, weights)
30+
return [qml.expval(qml.PauliZ(i)) for i in range(n_qubits)]
31+
32+
# Torch module for quantum layer
33+
class QuantumLayer(nn.Module):
34+
def __init__(self):
35+
super().__init__()
36+
# Initialize trainable parameters for each qubit
37+
self.q_weights = nn.Parameter(0.01 * torch.randn(n_qubits, 3))
38+
39+
def forward(self, x):
40+
# Apply quantum circuit to each input sample
41+
return torch.stack([qnode(x[i], self.q_weights) for i in range(x.shape[0])])
42+
43+
# Full hybrid quantum-classical neural network
44+
class HybridQNN(nn.Module):
45+
def __init__(self):
46+
super().__init__()
47+
self.quantum_layer = QuantumLayer()
48+
self.classifier = nn.Sequential(
49+
nn.Linear(n_qubits, 4),
50+
nn.ReLU(),
51+
nn.Linear(4, 1),
52+
nn.Sigmoid()
53+
)
54+
55+
def forward(self, x):
56+
q_out = self.quantum_layer(x)
57+
return self.classifier(q_out)
58+
59+
# Toy dataset (binary classification)
60+
X = torch.tensor([[0.0, 0.1], [0.1, 0.2], [3.0, 3.1], [3.1, 3.0]], dtype=torch.float32)
61+
Y = torch.tensor([[0.], [0.], [1.], [1.]], dtype=torch.float32)
62+
63+
dataset = TensorDataset(X, Y)
64+
loader = DataLoader(dataset, batch_size=2, shuffle=True)
65+
66+
# Instantiate model, loss, optimizer
67+
model = HybridQNN()
68+
criterion = nn.BCELoss()
69+
optimizer = optim.Adam(model.parameters(), lr=0.01)
70+
71+
# Training loop
72+
for epoch in range(30):
73+
for xb, yb in loader:
74+
pred = model(xb)
75+
loss = criterion(pred, yb)
76+
optimizer.zero_grad()
77+
loss.backward()
78+
optimizer.step()
79+
print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")

0 commit comments

Comments
 (0)