-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
977 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,394 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stderr", | ||
"output_type": "stream", | ||
"text": [ | ||
"2024-12-02 10:50:03.729385: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX_VNNI FMA\n", | ||
"To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", | ||
"2024-12-02 10:50:03.793060: I tensorflow/core/util/port.cc:104] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n", | ||
"2024-12-02 10:50:03.794942: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n", | ||
"2024-12-02 10:50:03.794954: I tensorflow/compiler/xla/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n", | ||
"2024-12-02 10:50:06.943195: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n", | ||
"2024-12-02 10:50:06.943319: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n", | ||
"2024-12-02 10:50:06.943333: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"import os \n", | ||
"import pickle\n", | ||
"import hashlib\n", | ||
"\n", | ||
"import keras\n", | ||
"from tensorflow.keras.optimizers import Adam\n", | ||
"from tensorflow.keras.layers import BatchNormalization\n", | ||
"from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\n", | ||
"from tensorflow.keras.losses import BinaryCrossentropy \n", | ||
"from sklearn.metrics import accuracy_score\n", | ||
"import numpy as np\n", | ||
"\n", | ||
"from qkeras.qlayers import QDense\n", | ||
"from qkeras.quantizers import ternary\n", | ||
"\n", | ||
"os.environ['PATH'] = os.environ['XILINX_VIVADO'] + '/bin:' + os.environ['PATH']\n", | ||
"keras.utils.set_random_seed(32)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Download data" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Setup data" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"train_data_dir = \"../data/malab_05282024/npz/\"\n", | ||
"test_data_dir = \"../data/malab_05282024/npz/\"\n", | ||
"start_location = 100\n", | ||
"window_size = 400\n", | ||
"end_window = start_location + window_size" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 4, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"\"\"\"Loadning training split\"\"\"\n", | ||
"x_train_path = os.path.join(train_data_dir, f'0528_X_train_0_770.npy')\n", | ||
"y_train_path = os.path.join(train_data_dir, f'0528_y_train_0_770.npy')\n", | ||
"\n", | ||
"assert os.path.exists(x_train_path), f\"ERROR: File {x_train_path} does not exist.\"\n", | ||
"assert os.path.exists(y_train_path), f\"ERROR: File {y_train_path} does not exist.\"\n", | ||
"\n", | ||
"X_train_val = np.load(x_train_path)\n", | ||
"y_train_val = np.load(y_train_path)\n", | ||
"\n", | ||
"# Insure same dataset is loaded \n", | ||
"assert hashlib.md5(X_train_val).hexdigest() == 'b61226c86b7dee0201a9158455e08ffb', \"Checksum failed. Wrong file was loaded or file may be corrupted.\"\n", | ||
"assert hashlib.md5(y_train_val).hexdigest() == 'c59ce37dc7c73d2d546e7ea180fa8d31', \"Checksum failed. Wrong file was loaded or file may be corrupted.\"\n", | ||
"\n", | ||
"# Get readout window\n", | ||
"X_train_val = X_train_val[:,start_location*2:end_window*2]\n", | ||
"assert len(X_train_val[0]) == (end_window-start_location)*2, f\"ERROR: X_test sample size {len(X_train_val[0])} does not match (start window, end window) ({start_location},{end_window}) size.\"" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 5, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"\"\"\"Loading testing split\"\"\"\n", | ||
"x_test_path = os.path.join(test_data_dir, f'0528_X_test_0_770.npy')\n", | ||
"y_test_path = os.path.join(test_data_dir, f'0528_y_test_0_770.npy')\n", | ||
"\n", | ||
"assert os.path.exists(x_test_path), f\"ERROR: File {x_test_path} does not exist.\"\n", | ||
"assert os.path.exists(y_test_path), f\"ERROR: File {y_test_path} does not exist.\"\n", | ||
"\n", | ||
"X_test = np.load(x_test_path)\n", | ||
"y_test = np.load(y_test_path)\n", | ||
"\n", | ||
"# Insure same dataset is loaded \n", | ||
"assert hashlib.md5(X_test).hexdigest() == 'b7d85f42522a0a57e877422bc5947cde', \"Checksum failed. Wrong file was loaded or file may be corrupted.\"\n", | ||
"assert hashlib.md5(y_test).hexdigest() == '8c9cce1821372380371ade5f0ccfd4a2', \"Checksum failed. Wrong file was loaded or file may be corrupted.\"\n", | ||
"\n", | ||
"# Get readout window\n", | ||
"X_test = X_test[:,start_location*2:end_window*2]\n", | ||
"assert len(X_test[0]) == (end_window-start_location)*2, f\"ERROR: X_test sample size {len(X_test[0])} does not match (start window, end window) ({start_location},{end_window}) size.\"" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Construct the model\n", | ||
" \n", | ||
"QKeras is \"Quantized Keras\" for deep heterogeneous quantization of ML models. We're using QDense layer instead of Dense. We're also training with model sparsity, since QKeras layers are prunable." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 6, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"WARNING:tensorflow:From /data/jcampos/miniforge3/envs/ml4qick-env/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/liveness.py:83: Analyzer.lamba_check (from tensorflow.python.autograph.pyct.static_analysis.liveness) is deprecated and will be removed after 2023-09-23.\n", | ||
"Instructions for updating:\n", | ||
"Lambda fuctions will be no more assumed to be used in the statement where they are used, or at least in the same block. https://github.com/tensorflow/tensorflow/issues/56089\n" | ||
] | ||
}, | ||
{ | ||
"name": "stderr", | ||
"output_type": "stream", | ||
"text": [ | ||
"2024-12-02 10:51:09.801613: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n", | ||
"2024-12-02 10:51:09.801630: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n", | ||
"2024-12-02 10:51:09.801640: I tensorflow/compiler/xla/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (correlator7.fnal.gov): /proc/driver/nvidia/version does not exist\n", | ||
"2024-12-02 10:51:09.801767: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX_VNNI FMA\n", | ||
"To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n" | ||
] | ||
}, | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Model: \"sequential\"\n", | ||
"_________________________________________________________________\n", | ||
" Layer (type) Output Shape Param # \n", | ||
"=================================================================\n", | ||
" fc1 (QDense) (None, 4) 3204 \n", | ||
" \n", | ||
" batchnorm1 (BatchNormalizat (None, 4) 16 \n", | ||
" ion) \n", | ||
" \n", | ||
" fc2 (QDense) (None, 1) 5 \n", | ||
" \n", | ||
"=================================================================\n", | ||
"Total params: 3,225\n", | ||
"Trainable params: 3,217\n", | ||
"Non-trainable params: 8\n", | ||
"_________________________________________________________________\n", | ||
"None\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"model = keras.models.Sequential()\n", | ||
"model.add(QDense(\n", | ||
" 4, \n", | ||
" activation=None, \n", | ||
" name='fc1',\n", | ||
" input_shape=(800,), \n", | ||
" kernel_quantizer=ternary(),\n", | ||
" bias_quantizer=ternary(),\n", | ||
"))\n", | ||
"model.add(BatchNormalization(name='batchnorm1'))\n", | ||
"model.add(QDense(\n", | ||
" 1, \n", | ||
" name='fc2', \n", | ||
" activation='sigmoid', \n", | ||
" kernel_quantizer=ternary(),\n", | ||
" bias_quantizer=ternary(),\n", | ||
"))\n", | ||
"\n", | ||
"print(model.summary())" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Train the model" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 7, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"init_learning_rate = 1e-3\n", | ||
"validation_split = 0.05 # 45,000 sample size \n", | ||
"batch_size = 256\n", | ||
"epochs = 50\n", | ||
"early_stopping_patience = 10\n", | ||
"\n", | ||
"checkpoint_dir = f'checkpoints/'\n", | ||
"checkpoint_filename = f'qkeras_ckp_model_best.h5'\n", | ||
"ckp_filename = os.path.join(checkpoint_dir, checkpoint_filename)\n", | ||
"\n", | ||
"if os.path.exists(checkpoint_dir) == False:\n", | ||
" print(f'Checkpoint directory {checkpoint_dir} does not exist.')\n", | ||
" print('Creating directory...')\n", | ||
" os.mkdir(checkpoint_dir)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 8, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Epoch 1/50\n", | ||
"3340/3340 [==============================] - 9s 2ms/step - loss: 0.1959 - accuracy: 0.9558 - val_loss: 0.1810 - val_accuracy: 0.9581\n", | ||
"Epoch 2/50\n", | ||
"3340/3340 [==============================] - 10s 3ms/step - loss: 0.1802 - accuracy: 0.9592 - val_loss: 0.1770 - val_accuracy: 0.9583\n", | ||
"Epoch 3/50\n", | ||
"3340/3340 [==============================] - 3s 800us/step - loss: 0.1787 - accuracy: 0.9595 - val_loss: 0.1783 - val_accuracy: 0.9584\n", | ||
"Epoch 4/50\n", | ||
"3340/3340 [==============================] - 8s 2ms/step - loss: 0.1782 - accuracy: 0.9598 - val_loss: 0.1776 - val_accuracy: 0.9585\n", | ||
"Epoch 5/50\n", | ||
"3340/3340 [==============================] - 9s 3ms/step - loss: 0.1792 - accuracy: 0.9593 - val_loss: 0.1770 - val_accuracy: 0.9583\n", | ||
"Epoch 6/50\n", | ||
"3340/3340 [==============================] - 6s 2ms/step - loss: 0.1791 - accuracy: 0.9593 - val_loss: 0.1796 - val_accuracy: 0.9582\n", | ||
"Epoch 7/50\n", | ||
"3340/3340 [==============================] - 6s 2ms/step - loss: 0.1784 - accuracy: 0.9598 - val_loss: 0.1783 - val_accuracy: 0.9588\n", | ||
"Epoch 8/50\n", | ||
"3340/3340 [==============================] - 2s 671us/step - loss: 0.1779 - accuracy: 0.9597 - val_loss: 0.1783 - val_accuracy: 0.9584\n", | ||
"Epoch 9/50\n", | ||
"3340/3340 [==============================] - 6s 2ms/step - loss: 0.1779 - accuracy: 0.9601 - val_loss: 0.1783 - val_accuracy: 0.9586\n", | ||
"Epoch 10/50\n", | ||
"3340/3340 [==============================] - 11s 3ms/step - loss: 0.1778 - accuracy: 0.9599 - val_loss: 0.1777 - val_accuracy: 0.9587\n", | ||
"Epoch 11/50\n", | ||
"3340/3340 [==============================] - 8s 2ms/step - loss: 0.1778 - accuracy: 0.9599 - val_loss: 0.1775 - val_accuracy: 0.9584\n", | ||
"Epoch 12/50\n", | ||
"3340/3340 [==============================] - 11s 3ms/step - loss: 0.1779 - accuracy: 0.9599 - val_loss: 0.1781 - val_accuracy: 0.9583\n", | ||
"Epoch 13/50\n", | ||
"3340/3340 [==============================] - 11s 3ms/step - loss: 0.1779 - accuracy: 0.9599 - val_loss: 0.1779 - val_accuracy: 0.9584\n", | ||
"Epoch 14/50\n", | ||
"3340/3340 [==============================] - 6s 2ms/step - loss: 0.1779 - accuracy: 0.9599 - val_loss: 0.1775 - val_accuracy: 0.9586\n", | ||
"Epoch 15/50\n", | ||
"3340/3340 [==============================] - 8s 2ms/step - loss: 0.1778 - accuracy: 0.9600 - val_loss: 0.1772 - val_accuracy: 0.9585\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"train = True\n", | ||
"\n", | ||
"if train: \n", | ||
" opt = Adam(learning_rate=init_learning_rate)\n", | ||
" callbacks = [\n", | ||
" EarlyStopping(\n", | ||
" monitor='val_loss',\n", | ||
" patience=early_stopping_patience,\n", | ||
" restore_best_weights=True,\n", | ||
" ),\n", | ||
" ] \n", | ||
" model.compile(\n", | ||
" optimizer=opt, \n", | ||
" loss=BinaryCrossentropy(from_logits=False), \n", | ||
" metrics=['accuracy']\n", | ||
" )\n", | ||
" history = model.fit(\n", | ||
" X_train_val, \n", | ||
" y_train_val, \n", | ||
" batch_size=batch_size,\n", | ||
" epochs=epochs, \n", | ||
" validation_split=validation_split, \n", | ||
" shuffle=True, \n", | ||
" callbacks=callbacks,\n", | ||
" )\n", | ||
" \n", | ||
" model.save_weights(os.path.join(checkpoint_dir, 'qkeras_model_best.h5'))\n", | ||
" # Save the history dictionary\n", | ||
" with open(os.path.join(checkpoint_dir, f'qkeras_training_history.pkl'), 'wb') as f:\n", | ||
" pickle.dump(history.history, f) \n", | ||
"else: \n", | ||
" model.load_weights(os.path.join(checkpoint_dir, checkpoint_filename))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Check performance" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 28, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"1563/1563 [==============================] - 1s 484us/step\n", | ||
"1563/1563 [==============================] - 1s 359us/step\n", | ||
"3125/3125 [==============================] - 1s 391us/step\n", | ||
"\n", | ||
"===================================\n", | ||
" Accuracy 0.95999\n", | ||
" Fidelity 0.979995\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"# get ground and excited indices \n", | ||
"e_indices = np.where(y_test == 1)[0]\n", | ||
"g_indices = np.where(y_test == 0)[0]\n", | ||
"\n", | ||
"# separate ground and excited samples \n", | ||
"Xe_test = X_test[e_indices]\n", | ||
"ye_test = y_test[e_indices]\n", | ||
"\n", | ||
"Xg_test = X_test[g_indices]\n", | ||
"yg_test = y_test[g_indices]\n", | ||
"\n", | ||
"# compute total correct for excited state \n", | ||
"ye_pred = model.predict(Xe_test)\n", | ||
"ye_pred = np.where(ye_pred < 0.5, 0, 1).reshape(-1)\n", | ||
"e_accuracy = accuracy_score(ye_test, ye_pred)\n", | ||
"\n", | ||
"total_correct = (ye_test==ye_pred).astype(np.int8).sum()\n", | ||
"total_incorrect = (ye_test!=ye_pred).astype(np.int8).sum()\n", | ||
"\n", | ||
"# compute total correct for ground state \n", | ||
"yg_pred = model.predict(Xg_test)\n", | ||
"yg_pred = np.where(yg_pred < 0.5, 0, 1)\n", | ||
"g_accuracy = accuracy_score(yg_test, yg_pred)\n", | ||
"\n", | ||
"total_correct = (yg_test==yg_pred).astype(np.int8).sum()\n", | ||
"total_incorrect = (yg_test!=yg_pred).astype(np.int8).sum()\n", | ||
"\n", | ||
"# compute fidelity \n", | ||
"test_fidelity = 0.5*(e_accuracy + g_accuracy)\n", | ||
"test_fidelity = 1/2 + (0.5*test_fidelity)\n", | ||
"\n", | ||
"y_pred = model.predict(X_test)\n", | ||
"test_acc = accuracy_score(y_test, np.where(y_pred < 0.5, 0, 1).reshape(-1))\n", | ||
"\n", | ||
"print('\\n===================================')\n", | ||
"print(' Accuracy', test_acc)\n", | ||
"print(' Fidelity', test_fidelity)" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "ml4qick-test-env", | ||
"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.10.14" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |