Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Submission #48

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0544b9c
Added some data exploration
hillstefan Jan 28, 2023
dcf4274
Moved iquhack into example folder
hillstefan Jan 28, 2023
b0ce98e
encoderv1, super simple version
MirteSudoku Jan 28, 2023
a08e87c
Added encoderFRQI
NilsCi Jan 28, 2023
5d73979
full histogram and updated epsilon. Also displays circuits
MirteSudoku Jan 28, 2023
8e13168
Debugging encoderFRQI
NilsCi Jan 29, 2023
76eda7a
debugging
NilsCi Jan 29, 2023
f759804
Debugging encoderFRQI
NilsCi Jan 29, 2023
b8abf8a
added optimizer
hillstefan Jan 29, 2023
e251e3c
Did the merge work?
hillstefan Jan 29, 2023
5cebba3
test
Jan 29, 2023
120354a
Added faulty, but theoretically more correct version
NilsCi Jan 29, 2023
8b2f09c
Python version of encoderv1 called encoderBASIC
MirteSudoku Jan 29, 2023
a6a670d
classifier circuit checkpoint
hillstefan Jan 29, 2023
69d4c6e
abstract concepts simulator circuit
hillstefan Jan 29, 2023
7369a89
classifier circuit simulator classes
hillstefan Jan 29, 2023
ed7e084
bugfix classifier
hillstefan Jan 29, 2023
57c74bd
final? basic encoder functions
MirteSudoku Jan 29, 2023
8fe801a
training routine
hillstefan Jan 29, 2023
cd59fef
weird overnight desync
NilsCi Jan 29, 2023
4ee2a85
decoder first version
Jan 29, 2023
1cebe1d
added weights circuit plus first full classifier training
hillstefan Jan 29, 2023
3f7e3cc
training algorithm
hillstefan Jan 29, 2023
3274e35
utils fix
hillstefan Jan 29, 2023
21058cd
ry(pi*w[i], i) for every qubit i
MirteSudoku Jan 29, 2023
ad8bade
idk what I did
MirteSudoku Jan 29, 2023
eaa514e
Submission part 1
MirteSudoku Jan 29, 2023
5fa6fa1
not working classifier training test
hillstefan Jan 29, 2023
58d25cc
Worked on a better encoder
NilsCi Jan 29, 2023
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
21,678 changes: 21,678 additions & 0 deletions .ipynb_checkpoints/data-exploration-checkpoint.ipynb

Large diffs are not rendered by default.

246 changes: 246 additions & 0 deletions .ipynb_checkpoints/encoderv1-checkpoint.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "9c97e0dc",
"metadata": {},
"outputs": [],
"source": [
"import cirq\n",
"import numpy as np\n",
"import pickle\n",
"import json\n",
"import os\n",
"from collections import Counter\n",
"from sklearn.metrics import mean_squared_error\n",
"\n",
"\n",
"import matplotlib.pyplot as plt #added\n",
"\n",
"#define utility functions\n",
"\n",
"def simulate(circuit: cirq.Circuit) -> dict:\n",
" \"\"\"This funcion simulate a cirq circuit (without measurement) and output results in the format of histogram.\n",
" \"\"\"\n",
" simulator = cirq.Simulator()\n",
" result = simulator.simulate(circuit)\n",
" \n",
" state_vector=result.final_state_vector\n",
" \n",
" histogram = dict()\n",
" for i in range(len(state_vector)):\n",
" population = abs(state_vector[i]) ** 2\n",
" if population > 1e-9:\n",
" histogram[i] = population\n",
" \n",
" return histogram\n",
"\n",
"\n",
"def histogram_to_category(histogram):\n",
" \"\"\"This function take a histogram representations of circuit execution results, and process into labels as described in \n",
" the problem description.\"\"\"\n",
" assert abs(sum(histogram.values())-1)<1e-8\n",
" positive=0\n",
" for key in histogram.keys():\n",
" digits = bin(int(key))[2:].zfill(20)\n",
" if digits[-1]=='0':\n",
" positive+=histogram[key]\n",
" \n",
" return positive\n",
"\n",
"def count_gates(circuit: cirq.Circuit):\n",
" \"\"\"Returns the number of 1-qubit gates, number of 2-qubit gates, number of 3-qubit gates....\"\"\"\n",
" counter=Counter([len(op.qubits) for op in circuit.all_operations()])\n",
" \n",
" #feel free to comment out the following two lines. But make sure you don't have k-qubit gates in your circuit\n",
" #for k>2\n",
" for i in range(2,20):\n",
" assert counter[i]==0\n",
" \n",
" return counter\n",
"\n",
"def image_mse(image1,image2):\n",
" # Using sklearns mean squared error:\n",
" # https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html\n",
" return mean_squared_error(image1, image2)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7f19ddcc",
"metadata": {},
"outputs": [],
"source": [
"#load the mock data (for testing only)\n",
"files=os.listdir(\"mock_data\")\n",
"dataset=list()\n",
"for file in files:\n",
" with open('mock_data/'+file, \"r\") as infile:\n",
" loaded = json.load(infile)\n",
" dataset.append(loaded)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a443b6a8",
"metadata": {},
"outputs": [],
"source": [
"#load the actual hackthon data (fashion-mnist)\n",
"images=np.load('data/images.npy')\n",
"labels=np.load('data/labels.npy')\n",
"print(set(labels))\n",
"print(len(labels))\n",
"print(len(images))\n",
"\n",
"print(labels[80])\n",
"#print(images[100])\n",
"\n",
"#you can visualize it\n",
"import matplotlib.pyplot as plt\n",
"plt.imshow(images[80])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb2031cd",
"metadata": {},
"outputs": [],
"source": [
"#submission to part 1, you should make this into a .py file\n",
"\n",
"n=len(dataset)\n",
"mse=0\n",
"gatecount=0\n",
"\n",
"def encode(image):\n",
" circuit=cirq.Circuit()\n",
" epsilon = 10**(-4) #background is sometimes not exactly 0\n",
" \n",
" \n",
" if len(image) < 28:\n",
" rows_to_check = [0, 1]\n",
" qubits = cirq.LineQubit.range(4)\n",
" else:\n",
" rows_to_check = [1, 7, 14, 21, 26] #rows we use to get info\n",
" qubits = cirq.LineQubit.range(2*len(rows_to_check))\n",
" \n",
" \n",
" for row in rows_to_check:\n",
" for i in range(len(image[0])):\n",
" if image[row][i] >= epsilon:\n",
" circuit.append(cirq.rx(np.pi/len(image[0]))(qubits[rows_to_check.index(row)])) #should represent % non-background values for a row in rows_to_check (first |rows_to_check| qubits)\n",
" #check amount of \"segments\" (between 0 and 3) in each row in rows_to_check\n",
" if i == 0:\n",
" circuit.append(cirq.rx(np.pi/3)(qubits[rows_to_check.index(row)+len(rows_to_check)-1])) #starts with non-background e.g. [[1,1],[1,1]]\n",
" else:\n",
" if image[row][i-1] < epsilon:\n",
" circuit.append(cirq.rx(np.pi/3)(rows_to_check.index(row)+len(rows_to_check)-1))\n",
" return circuit\n",
"\n",
"def encode_old(image):\n",
" circuit=cirq.Circuit()\n",
" if image[0][0]==0:\n",
" circuit.append(cirq.rx(np.pi).on(cirq.LineQubit(0)))\n",
" return circuit\n",
"\n",
"\n",
"def decode(histogram):\n",
" if 1 in histogram.keys():\n",
" image=[[0,0],[0,0]]\n",
" else:\n",
" image=[[1,1],[1,1]]\n",
" return image\n",
"\n",
"def run_part1(image):\n",
" #encode image into a circuit\n",
" circuit=encode(data['image'])\n",
"\n",
" #simulate circuit\n",
" histogram=simulate(circuit)\n",
" print(\"Histogram:\")\n",
" for key in histogram.keys():\n",
" print(histogram.get(key), end = \" \")\n",
" print(\"\\n\")\n",
"\n",
" #reconstruct the image\n",
" image_re=decode(histogram)\n",
"\n",
" return circuit,image_re"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "385faa44",
"metadata": {},
"outputs": [],
"source": [
"#how we grade your submission\n",
"\n",
"n=len(dataset)\n",
"mse=0\n",
"gatecount=0\n",
"\n",
"for data in dataset:\n",
" print(data)\n",
" #encode image into circuit\n",
" circuit,image_re=run_part1(data['image'])\n",
" #count the number of 2qubit gates used\n",
" gatecount+=count_gates(circuit)[2]\n",
" \n",
" #calculate mse\n",
" mse+=image_mse(data['image'],image_re)\n",
" \n",
"#fidelity of reconstruction\n",
"f=1-mse\n",
"gatecount=gatecount/n\n",
"\n",
"#score for part1 \n",
"print(f*(0.999**gatecount))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ad7e81d7",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "d344c8c3-f49d-4d63-8263-33e49834abe9",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 [Default]",
"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.9.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
132 changes: 132 additions & 0 deletions Submission/Part1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""

Part one submission.

Contains the simulate(circuit: qiskit.QuantumCircuit), encode(image), decode(histogram) and run_part1(image) functions.

"""
import qiskit
from qiskit import QuantumCircuit, QuantumRegister
from qiskit import transpile, assemble
from qiskit import quantum_info
from qiskit.execute_function import execute
from qiskit import BasicAer
import numpy as np
import pickle
import json
import os
from collections import Counter
from sklearn.metrics import mean_squared_error
from typing import Dict, List
import matplotlib.pyplot as plt
from math import ceil

#Simulate
def simulate(circuit: qiskit.QuantumCircuit) -> dict:
"""Simulate the circuit, give the state vector as the result."""
backend = BasicAer.get_backend('statevector_simulator')
job = execute(circuit, backend)
result = job.result()
state_vector = result.get_statevector()

histogram = dict()
for i in range(len(state_vector)):
population = abs(state_vector[i]) ** 2
if population > 1e-9:
histogram[i] = population

return histogram



#encode
def encode(image):
epsilon = 0.1/255 #background is sometimes not exactly 0

if len(image) < 28:
rows_to_check = [0, 1]
else:
rows_to_check = [1, 7, 14, 21, 26] #rows we use to get info
q = 2*len(rows_to_check)

qubits = QuantumRegister(q,'qubits')
qc = QuantumCircuit(qubits)
for row in rows_to_check:
for i in range(len(image[0])):
if image[row][i] >= epsilon:
qc.rx(np.pi/len(image[0]),qubits[rows_to_check.index(row)]) #should represent % non-background values for a row in rows_to_check (first |rows_to_check| qubits)
#check amount of "segments" (between 0 and 3) in each row in rows_to_check
if i == 0:
qc.rx(np.pi/3,qubits[rows_to_check.index(row)+len(rows_to_check)])#starts with non-background e.g. [[1,1],[1,1]]
else:
if image[row][i-1] < epsilon:
qc.rx(np.pi/3,rows_to_check.index(row)+len(rows_to_check))
qc=transpile(qc)
return qc



#decode
def decode(histogram):
#need to know size of picture
if len(histogram) <= 4: #mock data
if 1 in histogram.keys():
return [[0,0],[0,0]]
else:
return [[1,1],[1,1]]
else:
rows_to_check = 5
decoded_rows = []
decoded_qubit_values = [0]*2*rows_to_check
for key in histogram.keys():
#find qubit that corresponds to your row to find
binary_key = str(bin(key)[2:].zfill(len(decoded_qubit_values)))
for i in range(len(binary_key)):
if binary_key[i] == '1':
decoded_qubit_values[i] += histogram[key]
for i in range(len(decoded_qubit_values)//2):
#non-background pixels in row
r = ceil(decoded_qubit_values[i*2]*28)
#segments
s = int(decoded_qubit_values[i*2+1]*3+0.1)
#construct row without info on intensity
if s == 0:
l = 0
else:
l = r//s
row = []
for i in range(s):
row += [0.5/255]*l + [0]
row = row[:-1]
decoded_row = row + [0]*int((28-r-max(0,s-1))/2)
decoded_row = [0]*(28-len(decoded_row))+decoded_row
decoded_rows.append(decoded_row)
decoded_image = []
for i in range(28):
if i <4:
index = 0
elif i < 11:
index = 1
elif i < 17:
index = 2
elif i < 25:
index = 3
else:
index = 4
decoded_image.append(decoded_rows[index])
return np.array(decoded_image)



#run_part1
def run_part1(image):
#encode image into a circuit
circuit=encode(data['image'])

#simulate circuit
histogram=simulate(circuit)

#reconstruct the image
image_re=decode(histogram)

return circuit, image_re
10 changes: 10 additions & 0 deletions circuit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from abc import ABC


class Circuit(ABC)

@static
def get_circuit(x, weights):



Loading