Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
266 changes: 266 additions & 0 deletions HelloWorldMerLin.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "c7a956c2",
"metadata": {},
"source": [
"# Hello World: Quantum Machine Learning with Merlin\n",
"\n",
"Welcome! This notebook demonstrates how to use Merlin to build, train, and evaluate a hybrid quantum-classical neural network for the classic Iris classification task. \n",
"You'll see how quantum layers can be integrated into standard PyTorch models and how to compare their performance."
]
},
{
"cell_type": "markdown",
"id": "34a189db",
"metadata": {},
"source": [
"## 1. Install and Import Dependencies\n",
"\n",
"First, let's make sure all required packages are installed and import them. \n",
"If you haven't installed Merlin yet, run: \n",
"`pip install merlinquantum` in your terminal or `!pip install merlinquantum` in your notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2ed0f1a9",
"metadata": {},
"outputs": [],
"source": [
"import torch\n",
"import torch.nn as nn\n",
"import merlin as ML\n",
"from merlin.datasets import iris"
]
},
{
"cell_type": "markdown",
"id": "5c13b34f",
"metadata": {},
"source": [
"## 2. Load and Prepare the Iris Dataset\n",
"\n",
"We'll use the classic Iris dataset, a simple and well-known benchmark for classification. \n",
"Let's load the data and convert it to PyTorch tensors for training."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c71851b3",
"metadata": {},
"outputs": [],
"source": [
"train_features, train_labels, train_metadata = iris.get_data_train()\n",
"test_features, test_labels, test_metadata = iris.get_data_test()\n",
"\n",
"# Convert data to PyTorch tensors\n",
"X_train = torch.FloatTensor(train_features)\n",
"y_train = torch.LongTensor(train_labels)\n",
"X_test = torch.FloatTensor(test_features)\n",
"y_test = torch.LongTensor(test_labels)\n",
"\n",
"print(f\"Training samples: {X_train.shape[0]}\")\n",
"print(f\"Test samples: {X_test.shape[0]}\")\n",
"print(f\"Features: {X_train.shape[1]}\")\n",
"print(f\"Classes: {len(torch.unique(y_train))}\")"
]
},
{
"cell_type": "markdown",
"id": "74a16ed3",
"metadata": {},
"source": [
"![iris](./img/iris.png)"
]
},
{
"cell_type": "markdown",
"id": "c80a7e7d",
"metadata": {},
"source": [
"## 3. Define the Hybrid Quantum-Classical Model\n",
"\n",
"We'll build a neural network that combines classical and quantum layers:\n",
"- **Classical preprocessing**: Reduces the 4 input features to 3.\n",
"- **Quantum layer**: Processes the features using a quantum circuit.\n",
"- **Classical output**: Maps quantum outputs to the 3 Iris classes."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "282b544b",
"metadata": {},
"outputs": [],
"source": [
"class HybridIrisClassifier(nn.Module):\n",
" \"\"\"\n",
" Hybrid model for Iris classification:\n",
" - Classical layer reduces 4 features to 3\n",
" - Quantum layer processes the 3 features\n",
" - Classical output layer for 3-class classification\n",
" \"\"\"\n",
" def __init__(self):\n",
" super(HybridIrisClassifier, self).__init__()\n",
"\n",
" # Classical preprocessing layer: 4 → 8 → 3\n",
" self.classical_in = nn.Sequential(\n",
" nn.Linear(4, 8),\n",
" nn.ReLU(),\n",
" nn.Linear(8, 3),\n",
" nn.Tanh() # Normalize to [-1, 1] for quantum layer\n",
" )\n",
"\n",
" # Quantum layer: processes 3 features\n",
" self.quantum = ML.QuantumLayer.simple(\n",
" input_size=3,\n",
" n_params=number_of_quantum_params\n",
" )\n",
"\n",
" # Classical output layer: quantum → 8 → 3\n",
" self.classical_out = nn.Sequential(\n",
" nn.Linear(self.quantum.output_size, 8),\n",
" nn.ReLU(),\n",
" nn.Dropout(0.1),\n",
" nn.Linear(8, 3)\n",
" )\n",
"\n",
" print(f\"\\nModel Architecture:\")\n",
" print(f\" Input: 4 features\")\n",
" print(f\" Classical preprocessing: 4 → 3\")\n",
" print(f\" Quantum layer: 3 → {self.quantum.output_size}\")\n",
" print(f\" Classical output: {self.quantum.output_size} → 3 classes\")\n",
"\n",
" def forward(self, x):\n",
" # Preprocess with classical layer\n",
" x = self.classical_in(x)\n",
"\n",
" # Shift tanh output from [-1, 1] to [0, 1] for quantum layer\n",
" x = (x + 1) / 2\n",
" x = self.quantum(x)\n",
"\n",
" # Final classification\n",
" x = self.classical_out(x)\n",
" return x"
]
},
{
"cell_type": "markdown",
"id": "aac69a97",
"metadata": {},
"source": [
"## 4. Set Training and Quantum Parameters\n",
"\n",
"You can adjust these parameters to see how they affect training and model performance."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ebdcce3a",
"metadata": {},
"outputs": [],
"source": [
"learning_rate = 0.05\n",
"number_of_epochs = 100\n",
"number_of_quantum_params = 200"
]
},
{
"cell_type": "markdown",
"id": "0b96210f",
"metadata": {},
"source": [
"## 5. Train the Hybrid Model\n",
"\n",
"We'll train our hybrid model using standard PyTorch routines. \n",
"The optimizer and loss function are set up as usual."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "88470525",
"metadata": {},
"outputs": [],
"source": [
"# Create model\n",
"model = HybridIrisClassifier()\n",
"\n",
"# Standard PyTorch training\n",
"optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\n",
"criterion = nn.CrossEntropyLoss()\n",
"\n",
"# Training loop (standard PyTorch)\n",
"for epoch in range(number_of_epochs):\n",
" optimizer.zero_grad()\n",
" outputs = model(X_train)\n",
" loss = criterion(outputs, y_train)\n",
" loss.backward()\n",
" optimizer.step()"
]
},
{
"cell_type": "markdown",
"id": "e4d0bc29",
"metadata": {},
"source": [
"## 6. Evaluate the Model\n",
"\n",
"After training, let's evaluate our model on the test set and print the accuracy."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6020e4ef",
"metadata": {},
"outputs": [],
"source": [
"# Evaluate on test set\n",
"model.eval()\n",
"with torch.no_grad():\n",
" test_outputs = model(X_test)\n",
" predictions = torch.argmax(test_outputs, dim=1)\n",
" accuracy = (predictions == y_test).float().mean().item()\n",
" print(f\"Test accuracy: {accuracy:.4f}\")"
]
},
{
"cell_type": "markdown",
"id": "7f6dd19d",
"metadata": {},
"source": [
"# Conclusion\n",
"\n",
"Congratulations! You've trained and evaluated a hybrid quantum-classical neural network using Merlin. \n",
"Feel free to experiment with the model architecture, quantum parameters, or try other datasets!"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading