Skip to content

Commit 3a677e6

Browse files
Merge pull request #23 from Using-Namespace-System/main
mosaiQue
2 parents f063813 + 98651e0 commit 3a677e6

25 files changed

+7510
-3356
lines changed

.gitignore

+1-4
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,4 @@ cython_debug/
161161

162162
# Local testing
163163
scripts/testPennylane.ipynb
164-
results_2/
165-
results_3/
166-
results/
167-
results_3/
164+
results_*/

mosaiQue/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
/output
22
/notebooks/mnist_train/
33
/notebooks/mnist_test/
4+
notebooks/*/*.npy
5+
notebooks/*/run*
6+
mosaique/models/__pycache__/*.pyc

mosaiQue/mosaique/config.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
"TRAIN_IMAGES": 60000,
55
"TEST_IMAGES": 10000,
66
"CHANNELS": 4,
7-
"SAVE_PATH": "../results/",
7+
"SAVE_PATH": "../results_4/",
88
"PREPROCESS": 1,
99
"DATA_REDUCTION": 1,
10-
"REDUCTION_RATIO": 0.001,
10+
"REDUCTION_RATIO": 1,
1111
"FILTER_TYPE": 0,
1212
"POOLING_SIZE": 2,
1313
"CLASSES": 10,
14-
"BATCH_SIZE": 512
14+
"BATCH_SIZE": 124
1515
}

mosaiQue/mosaique/models/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ def transform(self, dataset: np.ndarray[..., np.dtype[Any]]):
3636

3737
def post_transform(self, dataset: np.ndarray[..., np.dtype[Any]]):
3838
return self.kernel.post_transform(dataset)
39+
def channel_merge(self, dataset: np.ndarray[..., np.dtype[Any]]):
40+
return self.kernel.channel_merge(dataset)
3941

4042
def save(self, dataset: np.ndarray[..., np.dtype[Any]], variant:[int]):
4143
variant_string = ''.join(map(str,variant))

mosaiQue/mosaique/models/kernels.py

+15-12
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,29 @@ def fit(self, X: np.ndarray[..., np.dtype[Any]]):
2929
def transform(self, X: np.ndarray[..., np.dtype[Any]]):
3030
# shape MxN
3131
_m, _n = self.kernel_shape[:2]
32-
return (X
33-
.reshape((self.input_shape[0],-1, _m, self.input_shape[2]//_n, _n))
34-
.transpose((0,1,3,2,4))
35-
.reshape((self.input_shape[0], np.prod(self.input_shape[1:3])//(_m*_n), (_m*_n)))
32+
# Use slicing to extract all 2x2 patches from each 28x28 image
33+
# Reshape the array to extract all 2x2 patches
34+
# The number of 2x2 patches along height and width of each 28x28 image is 14
35+
return (X[:, :, :, np.newaxis]
36+
.reshape(self.input_shape[0], self.input_shape[2]//_m, _m, self.input_shape[2]//_n, _n)
37+
.transpose((0,1,3,4,2))
38+
.reshape(self.input_shape[0], -1, _m * _n)
3639
)
3740

3841
def post_transform(self, X: np.ndarray[..., np.dtype[Any]]):
3942
# shape MxN
4043
_m, _n = self.kernel_shape[:2]
4144
return (X
42-
.reshape((self.input_shape[0], self.input_shape[2] // _m, self.input_shape[2] // _n, _m * _n))
43-
)
45+
.reshape(self.input_shape[0], _n*_m, self.input_shape[2]//_n, self.input_shape[2]//_m)
46+
.transpose(0,2,3,1)
47+
)
4448

4549
def channel_merge(self, X: np.ndarray[..., np.dtype[Any]]):
4650
# shape MxN
4751
_m, _n = self.kernel_shape[:2]
4852
return (X
49-
.reshape((self.input_shape[0],-1, self.input_shape[2]//_n, _m, _n))
50-
.transpose((0,1,3,2,4))
51-
.reshape(self.input_shape)
52-
)
53-
54-
53+
.reshape(self.input_shape[0], self.input_shape[2]//_m, self.input_shape[2]//_n, _m,_n)
54+
.transpose((0,1,2,4,3))
55+
.transpose((0, 1, 3, 2, 4))
56+
.reshape(self.input_shape[:3])
57+
)

mosaiQue/mosaique/models/operation.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import tensorflow as tf
2+
from PIL.ImageChops import offset
23
from tensorflow import keras
34
import pennylane as qml
45

@@ -17,7 +18,9 @@ def __init__(self, *args, **kwargs):
1718
super().__init__(*args, **kwargs)
1819

1920
def call(self, inputs):
20-
return tf.transpose(tf.vectorized_map(self.q_node, inputs),(1,2,0))
21+
# does not work without setting a batch size
22+
return tf.stack(tf.vectorized_map(self.q_node, inputs),axis=1) - 1
23+
2124

2225
class OperationLayer():
2326
_q_layer: QuantumLayer
@@ -50,7 +53,7 @@ def pre_op(self) -> keras.Model:
5053
this_model = keras.models.Sequential([
5154
keras.layers.Rescaling(scale=1. / 255.0),
5255
self.q_layer,
53-
keras.layers.Rescaling(scale=127.5, offset=127.5)
56+
keras.layers.Rescaling(scale=-127.5)
5457
])
5558
this_model.compile(
5659
optimizer='adam',

mosaiQue/mosaique/tests/kernel2d.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818

1919
data_blocks = kernel.transform(dataset[[0,1]])
2020

21-
data_blocks = data_blocks.transpose((0,2,1))
21+
print(data_blocks[0])
2222

23-
data_blocks = kernel.post_transform(data_blocks)
23+
#data_blocks = data_blocks.transpose((0,2,1))
24+
25+
#data_blocks = kernel.post_transform(data_blocks)
26+
27+
#print(data_blocks[0])
2428

25-
print(data_blocks[0].T)
2629

2730

2831

mosaiQue/mosaique/tests/qernel2d.py

+25-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
from numpy.ma.core import product
2-
31
from mosaique.models.kernels import Kernel2d4x4
2+
from mosaique.models.operation import OperationLayer
43
import pennylane as qml
5-
from pennylane import numpy as pnp
64
import numpy as np
75
from typing import Any
86

@@ -13,21 +11,33 @@
1311

1412
dev = qml.device("default.qubit.tf", wires=4)
1513
@qml.qnode(dev, interface='tf')
16-
def qcnot_node(q1,q2,q3,q4):
17-
18-
qml.RY(np.pi * q1, wires=0)
19-
qml.RY(np.pi * q2, wires=1)
20-
qml.RY(np.pi * q3, wires=2)
21-
qml.RY(np.pi * q4, wires=3)
14+
def cnot(inputs):
15+
qml.AngleEmbedding(inputs[:, ...], wires=range(4), rotation='Y')
2216

23-
qml.CNOT(wires=[1, 2])
24-
qml.CNOT(wires=[0, 3])
17+
#qml.CNOT(wires=[0, 1])
18+
#qml.CNOT(wires=[2, 3])
2519

2620
# Measurement producing 4 classical output values
27-
return pnp.asarray([qml.expval(qml.PauliZ(wires=0)),qml.expval(qml.PauliZ(wires=1)),
28-
qml.expval(qml.PauliZ(wires=2)),qml.expval(qml.PauliZ(wires=3))])
21+
return [qml.expval(qml.PauliZ(j)) for j in range(4)]
22+
23+
kernel_shape = [2,2]
24+
25+
kernel = Kernel2d4x4(kernel_shape)
26+
27+
kernel.fit(dataset)
28+
29+
data_blocks = kernel.transform(dataset)[:,:,[0,3,2,1]]
30+
31+
#data_blocks = (245 * ((data_blocks+80)/(784)))
32+
33+
post_data = data_blocks.transpose((2,1,0))
34+
35+
post_data = post_data.transpose((2,1,0))
36+
37+
#post_data = post_data.reshape(20,14,14,4)
2938

39+
#post_data = np.asarray((((OperationLayer(cnot).pre_op(data_blocks)+1)*100)-160)) // 1
3040

31-
#data_blocks = kernel.inverse_transform(data_blocks)
41+
post_data = kernel.post_transform(post_data)[:,:,:,[0,3,2,1]]
3242

33-
#print(data_blocks[0])
43+
print((post_data)[0])

mosaiQue/notebooks/CIFAR-Training.ipynb

+2,239
Large diffs are not rendered by default.

mosaiQue/notebooks/CIFAR-test.ipynb

+241
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "32980464",
7+
"metadata": {
8+
"ExecuteTime": {
9+
"end_time": "2024-11-18T15:53:19.909394Z",
10+
"start_time": "2024-11-18T15:53:18.779242Z"
11+
}
12+
},
13+
"outputs": [],
14+
"source": [
15+
"#!sudo /opt/conda/bin/conda-develop -n QML-QPF PATH /workspaces/QML-QPF/mosaiQue"
16+
]
17+
},
18+
{
19+
"cell_type": "code",
20+
"execution_count": null,
21+
"id": "cd08081e",
22+
"metadata": {},
23+
"outputs": [],
24+
"source": [
25+
"\n",
26+
"#import tensorflow as tf\n",
27+
"#from tensorflow import keras\n",
28+
"import mosaique as mq\n",
29+
"from concurrent.futures import ProcessPoolExecutor, as_completed\n",
30+
"import itertools\n",
31+
"import numpy as np\n",
32+
"import pennylane as qml\n",
33+
"import os\n",
34+
"import time\n",
35+
"import datetime\n",
36+
"from tensorflow import keras\n",
37+
"from mosaique.models.operation import OperationLayer\n",
38+
"os.environ['TF_GPU_ALLOCATOR'] = 'cuda_malloc_async'\n",
39+
"\n",
40+
"fashionmnist_dataset = keras.datasets.fashion_mnist\n",
41+
"train_layer = mq.ConvolutionLayer4x4(\"fashionmnist_train\")\n",
42+
"test_layer = mq.ConvolutionLayer4x4(\"fashionmnist_test\")\n",
43+
"(train_images, train_labels), (test_images, test_labels) = fashionmnist_dataset.load_data()\n",
44+
"train_layer.fit(train_images)\n",
45+
"test_layer.fit(test_images)\n",
46+
"train_images = train_layer.transform(train_images)\n",
47+
"test_images = test_layer.transform(test_images)\n",
48+
"train_images = train_layer.post_transform(train_images.transpose((0,2,1)))\n",
49+
"test_images = test_layer.post_transform(test_images.transpose((0,2,1)))"
50+
]
51+
},
52+
{
53+
"cell_type": "code",
54+
"execution_count": null,
55+
"id": "a62fb6d5",
56+
"metadata": {},
57+
"outputs": [],
58+
"source": [
59+
"def run(tr_images, te_images, label):\n",
60+
" log_dir = train_layer.name + \"/run8/\" + label\n",
61+
" tensorboard_callback = keras.callbacks.TensorBoard(\n",
62+
" log_dir=log_dir,\n",
63+
" histogram_freq=1,\n",
64+
" write_graph=True,\n",
65+
" write_images=True,\n",
66+
" write_steps_per_second=True,\n",
67+
" update_freq='batch',\n",
68+
" profile_batch=1,\n",
69+
" embeddings_freq=1,\n",
70+
" embeddings_metadata=None\n",
71+
" )\n",
72+
" q_model = keras.models.Sequential([\n",
73+
" keras.layers.Rescaling(scale=-1. / 127.5, offset=1),\n",
74+
" keras.layers.Flatten(),\n",
75+
" keras.layers.Dense(10, activation=\"softmax\")\n",
76+
" ])\n",
77+
" q_model.compile(\n",
78+
" optimizer='adam',\n",
79+
" loss=\"sparse_categorical_crossentropy\",\n",
80+
" metrics=[\"accuracy\"],\n",
81+
" )\n",
82+
"\n",
83+
" q_history = q_model.fit(\n",
84+
" tr_images,\n",
85+
" train_labels,\n",
86+
" validation_data=(te_images, test_labels),\n",
87+
" batch_size=128,\n",
88+
" epochs=30,\n",
89+
" verbose=2,\n",
90+
" callbacks=[tensorboard_callback]\n",
91+
" )\n",
92+
"\n",
93+
"def model(variant, tr_layer, te_layer):\n",
94+
" tr_images = tr_layer.open(variant)\n",
95+
" te_images = te_layer.open(variant)\n",
96+
"\n",
97+
" label = ''.join(map(str,variant))\n",
98+
"\n",
99+
" run(tr_images, te_images, label)"
100+
]
101+
},
102+
{
103+
"cell_type": "code",
104+
"execution_count": null,
105+
"id": "ab5a65bf",
106+
"metadata": {},
107+
"outputs": [],
108+
"source": [
109+
"permutations = np.asarray(list(itertools.permutations(range(4))))\n",
110+
"\n",
111+
"#[model(variant = p, tr_layer = train_layer, te_layer= test_layer) for p in permutations[:1]]"
112+
]
113+
},
114+
{
115+
"cell_type": "code",
116+
"execution_count": null,
117+
"id": "80a45f19",
118+
"metadata": {},
119+
"outputs": [],
120+
"source": [
121+
"from matplotlib import pyplot as plt\n",
122+
"\n",
123+
"print(train_layer.open([0,1,2,3]).shape)\n",
124+
"\n",
125+
"post = train_layer.open([0,1,2,3])\n",
126+
"\n",
127+
"_min, _max = np.amin(post), np.amax(post)\n",
128+
"fig, axes = plt.subplots(1, 4, figsize=(16, 4))\n",
129+
"\n",
130+
"# Plot all output channels for quantum cnot\n",
131+
"for c in range(4):\n",
132+
" axes[c].imshow(post[0,:,:,c],vmin = _min, vmax = _max)"
133+
]
134+
},
135+
{
136+
"cell_type": "code",
137+
"execution_count": null,
138+
"id": "031c0127",
139+
"metadata": {},
140+
"outputs": [],
141+
"source": [
142+
"plt.imshow((train_layer.channel_merge(post))[0,:,:],vmin = _min, vmax = _max)"
143+
]
144+
},
145+
{
146+
"cell_type": "code",
147+
"execution_count": null,
148+
"id": "beb165f6",
149+
"metadata": {},
150+
"outputs": [],
151+
"source": [
152+
"\n",
153+
"\n",
154+
"for j in range(3):\n",
155+
" with ProcessPoolExecutor(8) as executor:\n",
156+
" runner = {\n",
157+
" executor.submit(model,variant = p, tr_layer = train_layer, te_layer= test_layer): p for p in permutations[8*j:8*(j+1)]\n",
158+
" }\n",
159+
" for future in as_completed(runner):\n",
160+
" runner.pop(future)\n",
161+
"# 1 min 8 sec"
162+
]
163+
},
164+
{
165+
"cell_type": "code",
166+
"execution_count": null,
167+
"id": "12b2c91c",
168+
"metadata": {},
169+
"outputs": [],
170+
"source": [
171+
"run(train_images,test_images,\"NO-FILTER\")"
172+
]
173+
}
174+
],
175+
"metadata": {
176+
"kernelspec": {
177+
"display_name": "QML-QPF",
178+
"language": "python",
179+
"name": "python3"
180+
},
181+
"language_info": {
182+
"codemirror_mode": {
183+
"name": "ipython",
184+
"version": 3
185+
},
186+
"file_extension": ".py",
187+
"mimetype": "text/x-python",
188+
"name": "python",
189+
"nbconvert_exporter": "python",
190+
"pygments_lexer": "ipython3",
191+
"version": "3.10.13"
192+
}
193+
},
194+
"nbformat": 4,
195+
"nbformat_minor": 5
196+
}

0 commit comments

Comments
 (0)