From c866d10597a5cbe6506f1d22930c51691181487e Mon Sep 17 00:00:00 2001 From: Stefan Ene Date: Tue, 20 Aug 2024 19:50:03 -0700 Subject: [PATCH 1/3] added initial DLLA changes --- STEF_DLLA_testing.ipynb | 218 +++++++++++++++++++++++++++ src/scarr/engines/dl_la.py | 253 ++++++++++++++++++++++++++++++++ src/scarr/modeling/dl_models.py | 50 +++++++ 3 files changed, 521 insertions(+) create mode 100644 STEF_DLLA_testing.ipynb create mode 100644 src/scarr/engines/dl_la.py create mode 100644 src/scarr/modeling/dl_models.py diff --git a/STEF_DLLA_testing.ipynb b/STEF_DLLA_testing.ipynb new file mode 100644 index 0000000..44441e4 --- /dev/null +++ b/STEF_DLLA_testing.ipynb @@ -0,0 +1,218 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## DL-LA Attack Using SCARR" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Run the framework imports and setup the trace handlers, the engine, and engine's container" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "opened zarr file cs5_group0_even.zarr\n", + "opened zarr file cs5_group1_even.zarr\n" + ] + } + ], + "source": [ + "import asyncio\n", + "import sys\n", + "import nest_asyncio\n", + "nest_asyncio.apply()\n", + "\n", + "from scarr.engines.dl_la import DL_LA as dlla\n", + "\n", + "from scarr.file_handling.trace_handler import TraceHandler as th\n", + "\n", + "from scarr.container.container import Container, ContainerOptions\n", + "\n", + "handler1 = th(fileName='cs5_group0_even.zarr', batchSize=5000)\n", + "handler2 = th(fileName='cs5_group1_even.zarr', batchSize=5000)\n", + "\n", + "# engine = dlla('MLP', train_float=0.90, num_epochs=10) # params: model_type, training_float, num_epochs\n", + "engine = dlla('MLP', train_float=0.90, num_epochs=2) # params: model_type, training_float, num_epochs\n", + "container = Container(options=ContainerOptions(engine=engine, handler=handler1, handler2=handler2), Async=True)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/2, Average Loss: 0.25054582030842193\n", + "Epoch 2/2, Average Loss: 0.25013674188297413\n" + ] + }, + { + "ename": "TypeError", + "evalue": "An asyncio.Future, a coroutine or an awaitable is required", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43masyncio\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43mengine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcontainer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel_building\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# params: container, train_only=False, validate_only=False \u001b[39;00m\n", + "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/nest_asyncio.py:28\u001b[0m, in \u001b[0;36m_patch_asyncio..run\u001b[0;34m(main, debug)\u001b[0m\n\u001b[1;32m 26\u001b[0m loop \u001b[38;5;241m=\u001b[39m asyncio\u001b[38;5;241m.\u001b[39mget_event_loop()\n\u001b[1;32m 27\u001b[0m loop\u001b[38;5;241m.\u001b[39mset_debug(debug)\n\u001b[0;32m---> 28\u001b[0m task \u001b[38;5;241m=\u001b[39m \u001b[43masyncio\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mensure_future\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmain\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 29\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 30\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m loop\u001b[38;5;241m.\u001b[39mrun_until_complete(task)\n", + "File \u001b[0;32m/opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/tasks.py:615\u001b[0m, in \u001b[0;36mensure_future\u001b[0;34m(coro_or_future, loop)\u001b[0m\n\u001b[1;32m 610\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mensure_future\u001b[39m(coro_or_future, \u001b[38;5;241m*\u001b[39m, loop\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[1;32m 611\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Wrap a coroutine or an awaitable in a future.\u001b[39;00m\n\u001b[1;32m 612\u001b[0m \n\u001b[1;32m 613\u001b[0m \u001b[38;5;124;03m If the argument is a Future, it is returned directly.\u001b[39;00m\n\u001b[1;32m 614\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 615\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_ensure_future\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcoro_or_future\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mloop\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mloop\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/tasks.py:630\u001b[0m, in \u001b[0;36m_ensure_future\u001b[0;34m(coro_or_future, loop)\u001b[0m\n\u001b[1;32m 628\u001b[0m called_wrap_awaitable \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 629\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 630\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mAn asyncio.Future, a coroutine or an awaitable \u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m 631\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mis required\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 633\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m loop \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 634\u001b[0m loop \u001b[38;5;241m=\u001b[39m events\u001b[38;5;241m.\u001b[39m_get_event_loop(stacklevel\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m4\u001b[39m)\n", + "\u001b[0;31mTypeError\u001b[0m: An asyncio.Future, a coroutine or an awaitable is required" + ] + } + ], + "source": [ + "engine.run(container, model_building=True) # params: container, train_only=False, validate_only=False " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# engine.save_model('model.pth') # params: path\n", + "# engine.load_model(container, 'model.pth') # params: container, path" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "engine.run(container, model_validation=True) # params: container, train_only=False, validate_only=False " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n" + ] + } + ], + "source": [ + "acc = engine.get_accuracy()\n", + "print(acc)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get the sensitivity analysis values and print to chart" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'NoneType' object has no attribute 'numpy'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[6], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m sens \u001b[38;5;241m=\u001b[39m \u001b[43mengine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_sensitivity\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/scarr/engines/dl_la.py:227\u001b[0m, in \u001b[0;36mDL_LA.get_sensitivity\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 226\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mget_sensitivity\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m--> 227\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msensitivity\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnumpy\u001b[49m()\n", + "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'numpy'" + ] + } + ], + "source": [ + "sens = engine.get_sensitivity()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Scarr Plot of DL-LA Sensitivity\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAArMAAAGCCAYAAADzKUuOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB9+UlEQVR4nO3dd3gUVdsG8HtDCSAkgEBCCYjSRYooGkRBaYIFLKioELG9IKiIyksUxE/UYEFFRfRFERERG0VRkAgCKk1KpCmKIqEkQQUSQieZ749xk9nNlilnds7s3r/rypVkd/bMszOzM8+eOcWjKIoCIiIiIiIXinM6ACIiIiIis5jMEhEREZFrMZklIiIiItdiMktERERErsVkloiIiIhci8ksEREREbkWk1kiIiIici0ms0RERETkWkxmiYiIiMi1mMwSERERkWvFdDK7YsUKXHPNNahXrx48Hg/mzZvn+PrmzJmDnj174swzz4TH40FWVpatMRERERG5WUwns0eOHEHbtm0xefJkadZ35MgRdO7cGc8991xEYiIiIiJys/JOB+Ck3r17o3fv3kGfP3HiBB5//HF8+OGHOHToEFq3bo3nnnsOXbt2tWV9ADBw4EAAwJ9//mlqHURERESxJKZrZsMZPnw4Vq1ahdmzZ2PTpk3o378/rrzySvz2229Oh0ZEREREYDIbVHZ2Nt5991188sknuPTSS3HOOefgkUceQefOnfHuu+86HR4RERERgclsUJs3b0ZRURGaNWuGqlWrlvwsX74cv//+OwDgl19+gcfjCfkzevRoh98JERERUfSK6TazoRQWFqJcuXJYv349ypUr5/Nc1apVAQBnn302fv7555DlnHnmmbbFSERERBTrmMwG0b59exQVFWH//v249NJLAy5TsWJFtGjRIsKREREREZFXTCezhYWF2LFjR8n/O3fuRFZWFmrWrIlmzZrhtttuw6BBgzBx4kS0b98ef/31F5YsWYI2bdrgqquuErq+hg0bAgAOHDiA7Oxs7Nu3DwCwfft2AEBycjKSk5OtvF0iIiKiqONRFEVxOginLFu2DJdffnmZx9PS0jB9+nScOnUKTz/9NGbMmIG9e/eiVq1auPjii/F///d/OO+884SvDwCmT5+OwYMHl1lm3LhxePLJJw2vk4iIiCiaxXQyS0RERETuxtEMiIiIiMi1mMwSERER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ySwRERERuRaTWSIiIiJyLSazRERERORa5Z0OINIURQEAFBQUOBwJEREREQXizdO8eVsoMZfMHj58GACQkpLicCREREREFMrhw4eRmJgYchmPoifljSLFxcXYt28fqlWrBo/HY/v6CgoKkJKSgt27dyMhIcH29ZF43Ifux33oftyH7sb9536R3oeKouDw4cOoV68e4uJCt4qNuZrZuLg4NGjQIOLrTUhI4AfY5bgP3Y/70P24D92N+8/9IrkPw9XIerEDGBERERG5FpNZIiIiInItJrM2i4+Px7hx4xAfH+90KGQS96H7cR+6H/ehu3H/uZ/M+zDmOoARERERUfRgzSwRERERuRaTWSIiIiJyLSazRERERORaTGaJiIiIyLWYzNps8uTJOOuss1CpUiVcdNFFWLt2rdMhxaQVK1bgmmuuQb169eDxeDBv3jyf5xVFwRNPPIG6deuicuXK6N69O3777TefZQ4cOIDbbrsNCQkJqF69Ou666y4UFhb6LLNp0yZceumlqFSpElJSUvD888/b/dZiQkZGBi688EJUq1YNderUQb9+/bB9+3afZY4fP45hw4bhzDPPRNWqVXHDDTcgLy/PZ5ns7GxcddVVqFKlCurUqYNHH30Up0+f9llm2bJlOP/88xEfH48mTZpg+vTpdr+9mDBlyhS0adOmZMD11NRULFy4sOR57j/3mTBhAjweD0aMGFHyGPej3J588kl4PB6fnxYtWpQ879r9p5BtZs+erVSsWFGZNm2asnXrVuWee+5RqlevruTl5TkdWsz56quvlMcff1yZM2eOAkCZO3euz/MTJkxQEhMTlXnz5ik//fSTcu211yqNGzdWjh07VrLMlVdeqbRt21ZZvXq18t133ylNmjRRBgwYUPJ8fn6+kpSUpNx2223Kli1blA8//FCpXLmy8tZbb0XqbUatXr16Ke+++66yZcsWJSsrS+nTp4/SsGFDpbCwsGSZIUOGKCkpKcqSJUuUdevWKRdffLHSqVOnkudPnz6ttG7dWunevbuyceNG5auvvlJq1aqlpKenlyzzxx9/KFWqVFFGjhypbNu2TXnttdeUcuXKKYsWLYro+41Gn3/+ufLll18qv/76q7J9+3blscceUypUqKBs2bJFURTuP7dZu3atctZZZylt2rRRHnzwwZLHuR/lNm7cOOXcc89VcnJySn7++uuv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WloarrzyShQXFwMA8vLycM8996Bp06ZITExEQkICCgsLkZ2dHTReb2z+8R4/fhwFBQUljzVs2BD169cv+T81NRXFxcU+bYq9duzYgaNHj6JHjx4+73HGjBkl72/o0KGYPXs22rVrh1GjRmHlypVBty8RkR7sAEZEZFKFChV8/vd4PD6PeTweAChJOgsLC3HNNdfgueeeK1NW3bp1Q66rdevWaN26Ne677z4MGTIEl156KZYvX47LL78caWlp+OeffzBp0iQ0atQI8fHxSE1NxcmTJ4PG640tVLxGFRYWAgC+/PJLnwQYAOLj4wEAvXv3xq5du/DVV18hMzMT3bp1w7Bhw/Diiy+aWicREZNZIqIIOf/88/HZZ5/hrLPOQvny5k+/rVq1AgAcOXIEAPDDDz/gjTfeQJ8+fQAAu3fvDtmpzIjs7Gzs27cP9erVAwCsXr0acXFxaN68ecC44uPjkZ2djS5dugQts3bt2khLS0NaWhouvfRSPProo0xmicg0JrNERBEybNgwTJ06FQMGDMCoUaNQs2ZN7NixA7Nnz8bbb7+NcuXKlXnN0KFDUa9ePVxxxRVo0KABcnJy8PTTT6N27dpITU0FADRt2hTvv/8+LrjgAhQUFODRRx9F5cqVhcRcqVIlpKWl4cUXX0RBQQEeeOAB3HTTTUhOTi6zbLVq1fDII4/goYceQnFxMTp37oz8/Hz88MMPSEhIQFpaGp544gl06NAB5557Lk6cOIEFCxagZcuWQmIlotjENrNERBFSr149/PDDDygqKkLPnj1x3nnnYcSIEahevTri4gKfjrt3747Vq1ejf//+aNasGW644QZUqlQJS5YswZlnngkAeOedd3Dw4EGcf/75GDhwIB544AHUqVNHSMxNmjTB9ddfjz59+qBnz55o06YN3njjjaDLjx8/HmPHjkVGRgZatmyJK6+8El9++SUaN24MAKhYsSLS09PRpk0bXHbZZShXrhxmz54tJFYiik0eRVEUp4MgIiL5PPnkk5g3bx6ysrKcDoWIKCjWzBIRERGRazGZJSIiIiLXYjMDIiIiInIt1swSERERkWsxmSUiIiIi12IyS0RERESuxWSWiIiIiFyLySwRERERuRaTWSIiIiJyLSazRERERORaTGaJiIiIyLWYzBIRERGRa/0//DMiIuHXtN0AAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "print('Scarr Plot of DL-LA Sensitivity')\n", + "fig, ax = plt.subplots(figsize=(8, 4))\n", + "ax.plot(sens, color='red')\n", + "\n", + "ax.set_xlabel('Time Samples')\n", + "ax.set_ylabel('Sensitivity')\n", + "\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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 +} diff --git a/src/scarr/engines/dl_la.py b/src/scarr/engines/dl_la.py new file mode 100644 index 0000000..dbc0bc7 --- /dev/null +++ b/src/scarr/engines/dl_la.py @@ -0,0 +1,253 @@ +from .engine import Engine +from ..modeling.dl_models import DL_Models as dlm +import numpy as np +from concurrent.futures import ThreadPoolExecutor + +import torch +import torch.nn as nn +import torch.optim as optim +from math import floor + +np.seterr(divide='ignore', invalid='ignore') + + +class DL_LA(Engine): + + def __init__(self, model_type, train_float, num_epochs) -> None: + # remember construction parameters + self.model_type = model_type + self.train_float = train_float + self.num_epochs = num_epochs + # initialize values needed + self.samples_len = 0 + self.batch_size = 0 + self.traces_len = 0 + self.batches_num = 0 + self.counted_batches = 0 + self.data_dtype = None + self.sensitivity = None + # validation values + self.accuracy = 0 + self.actual_labels = None + self.pred_labels = None + self.predicted_classes = None + + + def populate(self, container): + # initialize dimensional variables + self.samples_len = container.min_samples_length + self.traces_len = container.min_traces_length + self.batch_size = container.data.batch_size + self.batches_num = int(self.traces_len/self.batch_size) + # assign per-tile train and validation data + for tile in container.tiles: + (tile_x, tile_y) = tile + # config batches + container.configure(tile_x, tile_y, [0]) + container.configure2(tile_x, tile_y, [0]) + + + def fetch_training_batch(self, container, i): + batch1 = container.get_batch_index(i)[-1] + batch2 = container.get_batch_index2(i)[-1] + current_data = np.concatenate((batch1, batch2), axis=0) + label1 = np.zeros(len(batch1)) + label2 = np.ones(len(batch2)) + current_labels = np.concatenate((label1, label2), axis=0) + current_labels = np.eye(2)[current_labels.astype(int)] # one-hot encode labels + return current_data, current_labels + + + def fetch_validation_batch(self, container, i, batch_size): + batch1 = container.get_batch_index(i)[-1] + batch2 = container.get_batch_index2(i)[-1] + current_data = np.concatenate((batch1, batch2), axis=0) + label1 = np.zeros(batch_size) + label2 = np.ones(batch_size) + current_labels = np.concatenate((label1, label2), axis=0) + return current_data, current_labels + + + def train_model(self, container): + # start model + if self.model_type == 'MLP': + self.model = dlm.MLP(self.samples_len) + elif self.model_type == 'CNN': + self.model = dlm.CNN(self.samples_len) + else: + print("Invalid model type entered") + return + # define loss function and optimizer + self.criterion = nn.MSELoss() + self.optimizer = optim.Adam(self.model.parameters(), lr=0.01) + + # begin traininig + for epoch in range(self.num_epochs): + self.counted_batches = 0 + epoch_loss = 0.0 + accumulated_gradients = None + workers = 2 + if not container.fetch_async: + workers = 1 + + with ThreadPoolExecutor(max_workers=workers) as executor: + future = executor.submit(self.fetch_training_batch, container, 0) + for i in range(floor((self.traces_len/self.batch_size)*self.train_float)): + # wait for prev batch + current_data, current_labels = future.result() + # begin async next batch fatch + if container.fetch_async: + future = executor.submit(self.fetch_training_batch, container, i+1) + + # allocate batch tensors + batch_X = torch.tensor(current_data, dtype=torch.float32, requires_grad=True) + batch_Y = torch.tensor(current_labels, dtype=torch.float32) + # DL + # foward pass + outputs = self.model(batch_X) + # calculate loss + loss = self.criterion(outputs, batch_Y) + # backward pass and optimization + self.optimizer.zero_grad() + loss.backward() + + # accumulate gradients for sensitivity analysis + if accumulated_gradients is None: + accumulated_gradients = batch_X.grad.data.clone() + else: + accumulated_gradients += batch_X.grad.data + + self.optimizer.step() + + # accumulate loss + epoch_loss += loss.item() + self.counted_batches += 1 + + # begin sync next batch fatch + if not container.fetch_async: + future = executor.submit(self.fetch_training_batch, container, i+1) + + # sensitivity stuff + average_gradients = accumulated_gradients / self.counted_batches if self.counted_batches > 0 else 0 + self.sensitivity = average_gradients.abs().mean(dim=0) + # final training stuff + average_loss = epoch_loss / self.counted_batches if self.counted_batches > 0 else 0 + print(f"Epoch {epoch+1}/{self.num_epochs}, Average Loss: {average_loss}") + + + def validate_model(self, container): + # get new data + X_new = np.empty((2*(self.batches_num-self.counted_batches)*self.batch_size, self.samples_len), dtype=self.data_dtype) + Y_test = np.empty((2*(self.batches_num-self.counted_batches)*self.batch_size), dtype=self.data_dtype) + workers = 2 + if not container.fetch_async: + workers = 1 + + with ThreadPoolExecutor(max_workers=workers) as executor: + future = executor.submit(self.fetch_validation_batch, container, self.counted_batches, self.batch_size) + + for i in range(self.counted_batches, self.batches_num): + # wait for prev batch + current_data, current_labels = future.result() + # begin async next batch fatch + if container.fetch_async: + future = executor.submit(self.fetch_validation_batch, container, i+1, self.batch_size) + + start_idx = (i-self.counted_batches) * self.batch_size + end_idx = start_idx + 2 * self.batch_size + X_new[start_idx:end_idx] = current_data + Y_test[start_idx:end_idx] = current_labels + + # begin sync next batch fatch + if not container.fetch_async: + future = executor.submit(self.fetch_validation_batch, container, i+1, self.batch_size) + + # save labels + self.actual_labels = Y_test[:] + # make new data into tensors + X_new_tensor = torch.tensor(X_new, dtype=torch.float32) + + # set model to evaluation mode + self.model.eval() + + # make predictions + with torch.no_grad(): + predictions = self.model(X_new_tensor) + + # convert raw outputs to probabilites + probabilities = torch.softmax(predictions, dim=1) + + # get predicted class + self.predicted_classes = torch.argmax(probabilities, dim=1) + # copy locally for sensitivity + self.pred_labels = self.predicted_classes.numpy(force=True) + + # print predictions + # print("Predicted classes:\n", self.predicted_classes) + # calculate accuracy + correct_predictions = (self.predicted_classes == torch.tensor(Y_test)).sum().item() + self.accuracy = correct_predictions / len(Y_test) + # print("Accuracy:", accuracy) + + # clean print message + print("Made", self.predicted_classes.size(dim=0), "predictions with", f"{self.accuracy:.2%}", "% accuracy using the", self.model_type, "model.") + + + def run(self, container, model_building=False, model_validation=False): + if model_building: + # initialize vars and arrays + self.populate(container) + # being pytorch stuff + device = ( + # "cpu" + "cuda" + if torch.cuda.is_available() + else "mps" + if torch.backends.mps.is_available() + else "cpu" + ) + # start model + if self.model_type == 'MLP': + self.model = dlm.MLP(self.samples_len).to(device) + elif self.model_type == 'CNN': + self.model = dlm.CNN(self.samples_len).to(device) + else: + print(">> Invalid model type entered") + return + # begin training + self.train_model(container) + # begin validating if true + if model_validation: + self.validate_model(container) + + + def save_model(self, path): + torch.save(self.model.state_dict(), path) + + + def load_model(self, container, path): + # populate initial values as if for training + self.populate(container) + self.counted_batches = floor((self.traces_len/self.batch_size)*self.train_float) + # select and load model + if self.model_type == 'MLP': + self.model = dlm.MLP(self.samples_len) + elif self.model_type == 'CNN': + self.model = dlm.CNN(self.samples_len) + else: + print("Invalid model type entered") + return + self.model.load_state_dict(torch.load(path)) + print("Loaded", self.model_type, "model from memory") + + + def print_info(self): + print("> trace dimentions:", self.traces_len, self.samples_len) + + + def get_accuracy(self): + return self.accuracy + + def get_sensitivity(self): + return self.sensitivity.numpy() + \ No newline at end of file diff --git a/src/scarr/modeling/dl_models.py b/src/scarr/modeling/dl_models.py new file mode 100644 index 0000000..1e51ec5 --- /dev/null +++ b/src/scarr/modeling/dl_models.py @@ -0,0 +1,50 @@ +import torch +import torch.nn as nn + + +class DL_Models: + + # Multi-Layered Perceptron + class MLP(nn.Module): + def __init__(self, samples_len): + super().__init__() + self.flatten = nn.Flatten() + self.linear_relu_stack = nn.Sequential( + nn.Linear(samples_len, 120), + nn.ReLU(), + nn.BatchNorm1d(120), + nn.Linear(120, 90), + nn.ReLU(), + nn.BatchNorm1d(90), + nn.Linear(90, 50), + nn.ReLU(), + nn.BatchNorm1d(50), + nn.Linear(50, 2), + nn.Softmax(dim=1) + ) + def forward(self, x): + x = self.flatten(x) + logits = self.linear_relu_stack(x) + return logits + + + # Convolutional Neural Network + class CNN(nn.Module): + def __init__(self, samples_len): + super().__init__() + self.flatten = nn.Flatten() + self.linear_relu_stack = nn.Sequential( + nn.Flatten(start_dim=1), + nn.Unflatten(1, (1, samples_len)), + nn.Conv1d(in_channels=1, out_channels=16, kernel_size=3), + nn.ReLU(), + nn.MaxPool1d(kernel_size=4), + nn.Flatten(), + nn.Linear(16 * ((samples_len - 2) // 4), 2), + nn.Sigmoid() + ) + + def forward(self, x): + x = self.flatten(x) + logits = self.linear_relu_stack(x) + return logits From c29e36e18e88b7716c483c82b1d9e8d77dfb864f Mon Sep 17 00:00:00 2001 From: Stefan Ene Date: Tue, 20 Aug 2024 20:51:48 -0700 Subject: [PATCH 2/3] removed DLLA script --- STEF_DLLA_testing.ipynb | 218 ---------------------------------------- 1 file changed, 218 deletions(-) delete mode 100644 STEF_DLLA_testing.ipynb diff --git a/STEF_DLLA_testing.ipynb b/STEF_DLLA_testing.ipynb deleted file mode 100644 index 44441e4..0000000 --- a/STEF_DLLA_testing.ipynb +++ /dev/null @@ -1,218 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## DL-LA Attack Using SCARR" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Run the framework imports and setup the trace handlers, the engine, and engine's container" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "opened zarr file cs5_group0_even.zarr\n", - "opened zarr file cs5_group1_even.zarr\n" - ] - } - ], - "source": [ - "import asyncio\n", - "import sys\n", - "import nest_asyncio\n", - "nest_asyncio.apply()\n", - "\n", - "from scarr.engines.dl_la import DL_LA as dlla\n", - "\n", - "from scarr.file_handling.trace_handler import TraceHandler as th\n", - "\n", - "from scarr.container.container import Container, ContainerOptions\n", - "\n", - "handler1 = th(fileName='cs5_group0_even.zarr', batchSize=5000)\n", - "handler2 = th(fileName='cs5_group1_even.zarr', batchSize=5000)\n", - "\n", - "# engine = dlla('MLP', train_float=0.90, num_epochs=10) # params: model_type, training_float, num_epochs\n", - "engine = dlla('MLP', train_float=0.90, num_epochs=2) # params: model_type, training_float, num_epochs\n", - "container = Container(options=ContainerOptions(engine=engine, handler=handler1, handler2=handler2), Async=True)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch 1/2, Average Loss: 0.25054582030842193\n", - "Epoch 2/2, Average Loss: 0.25013674188297413\n" - ] - }, - { - "ename": "TypeError", - "evalue": "An asyncio.Future, a coroutine or an awaitable is required", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43masyncio\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43mengine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcontainer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel_building\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# params: container, train_only=False, validate_only=False \u001b[39;00m\n", - "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/nest_asyncio.py:28\u001b[0m, in \u001b[0;36m_patch_asyncio..run\u001b[0;34m(main, debug)\u001b[0m\n\u001b[1;32m 26\u001b[0m loop \u001b[38;5;241m=\u001b[39m asyncio\u001b[38;5;241m.\u001b[39mget_event_loop()\n\u001b[1;32m 27\u001b[0m loop\u001b[38;5;241m.\u001b[39mset_debug(debug)\n\u001b[0;32m---> 28\u001b[0m task \u001b[38;5;241m=\u001b[39m \u001b[43masyncio\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mensure_future\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmain\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 29\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 30\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m loop\u001b[38;5;241m.\u001b[39mrun_until_complete(task)\n", - "File \u001b[0;32m/opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/tasks.py:615\u001b[0m, in \u001b[0;36mensure_future\u001b[0;34m(coro_or_future, loop)\u001b[0m\n\u001b[1;32m 610\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mensure_future\u001b[39m(coro_or_future, \u001b[38;5;241m*\u001b[39m, loop\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[1;32m 611\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Wrap a coroutine or an awaitable in a future.\u001b[39;00m\n\u001b[1;32m 612\u001b[0m \n\u001b[1;32m 613\u001b[0m \u001b[38;5;124;03m If the argument is a Future, it is returned directly.\u001b[39;00m\n\u001b[1;32m 614\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 615\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_ensure_future\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcoro_or_future\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mloop\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mloop\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/tasks.py:630\u001b[0m, in \u001b[0;36m_ensure_future\u001b[0;34m(coro_or_future, loop)\u001b[0m\n\u001b[1;32m 628\u001b[0m called_wrap_awaitable \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 629\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 630\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mAn asyncio.Future, a coroutine or an awaitable \u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m 631\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mis required\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 633\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m loop \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 634\u001b[0m loop \u001b[38;5;241m=\u001b[39m events\u001b[38;5;241m.\u001b[39m_get_event_loop(stacklevel\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m4\u001b[39m)\n", - "\u001b[0;31mTypeError\u001b[0m: An asyncio.Future, a coroutine or an awaitable is required" - ] - } - ], - "source": [ - "engine.run(container, model_building=True) # params: container, train_only=False, validate_only=False " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# engine.save_model('model.pth') # params: path\n", - "# engine.load_model(container, 'model.pth') # params: container, path" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "engine.run(container, model_validation=True) # params: container, train_only=False, validate_only=False " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - } - ], - "source": [ - "acc = engine.get_accuracy()\n", - "print(acc)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Get the sensitivity analysis values and print to chart" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "'NoneType' object has no attribute 'numpy'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[6], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m sens \u001b[38;5;241m=\u001b[39m \u001b[43mengine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_sensitivity\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/scarr/engines/dl_la.py:227\u001b[0m, in \u001b[0;36mDL_LA.get_sensitivity\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 226\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mget_sensitivity\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m--> 227\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msensitivity\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnumpy\u001b[49m()\n", - "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'numpy'" - ] - } - ], - "source": [ - "sens = engine.get_sensitivity()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Scarr Plot of DL-LA Sensitivity\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAArMAAAGCCAYAAADzKUuOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB9+UlEQVR4nO3dd3gUVdsG8HtDCSAkgEBCCYjSRYooGkRBaYIFLKioELG9IKiIyksUxE/UYEFFRfRFERERG0VRkAgCKk1KpCmKIqEkQQUSQieZ749xk9nNlilnds7s3r/rypVkd/bMszOzM8+eOcWjKIoCIiIiIiIXinM6ACIiIiIis5jMEhEREZFrMZklIiIiItdiMktERERErsVkloiIiIhci8ksEREREbkWk1kiIiIici0ms0RERETkWkxmiYiIiMi1mMwSERERkWvFdDK7YsUKXHPNNahXrx48Hg/mzZvn+PrmzJmDnj174swzz4TH40FWVpatMRERERG5WUwns0eOHEHbtm0xefJkadZ35MgRdO7cGc8991xEYiIiIiJys/JOB+Ck3r17o3fv3kGfP3HiBB5//HF8+OGHOHToEFq3bo3nnnsOXbt2tWV9ADBw4EAAwJ9//mlqHURERESxJKZrZsMZPnw4Vq1ahdmzZ2PTpk3o378/rrzySvz2229Oh0ZEREREYDIbVHZ2Nt5991188sknuPTSS3HOOefgkUceQefOnfHuu+86HR4RERERgclsUJs3b0ZRURGaNWuGqlWrlvwsX74cv//+OwDgl19+gcfjCfkzevRoh98JERERUfSK6TazoRQWFqJcuXJYv349ypUr5/Nc1apVAQBnn302fv7555DlnHnmmbbFSERERBTrmMwG0b59exQVFWH//v249NJLAy5TsWJFtGjRIsKREREREZFXTCezhYWF2LFjR8n/O3fuRFZWFmrWrIlmzZrhtttuw6BBgzBx4kS0b98ef/31F5YsWYI2bdrgqquuErq+hg0bAgAOHDiA7Oxs7Nu3DwCwfft2AEBycjKSk5OtvF0iIiKiqONRFEVxOginLFu2DJdffnmZx9PS0jB9+nScOnUKTz/9NGbMmIG9e/eiVq1auPjii/F///d/OO+884SvDwCmT5+OwYMHl1lm3LhxePLJJw2vk4iIiCiaxXQyS0RERETuxtEMiIiIiMi1mMwSERER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ySwRERERuRaTWSIiIiJyLSazRERERORa5Z0OINIURQEAFBQUOBwJEREREQXizdO8eVsoMZfMHj58GACQkpLicCREREREFMrhw4eRmJgYchmPoifljSLFxcXYt28fqlWrBo/HY/v6CgoKkJKSgt27dyMhIcH29ZF43Ifux33oftyH7sb9536R3oeKouDw4cOoV68e4uJCt4qNuZrZuLg4NGjQIOLrTUhI4AfY5bgP3Y/70P24D92N+8/9IrkPw9XIerEDGBERERG5FpNZIiIiInItJrM2i4+Px7hx4xAfH+90KGQS96H7cR+6H/ehu3H/uZ/M+zDmOoARERERUfRgzSwRERERuRaTWSIiIiJyLSazRERERORaTGaJiIiIyLWYzNps8uTJOOuss1CpUiVcdNFFWLt2rdMhxaQVK1bgmmuuQb169eDxeDBv3jyf5xVFwRNPPIG6deuicuXK6N69O3777TefZQ4cOIDbbrsNCQkJqF69Ou666y4UFhb6LLNp0yZceumlqFSpElJSUvD888/b/dZiQkZGBi688EJUq1YNderUQb9+/bB9+3afZY4fP45hw4bhzDPPRNWqVXHDDTcgLy/PZ5ns7GxcddVVqFKlCurUqYNHH30Up0+f9llm2bJlOP/88xEfH48mTZpg+vTpdr+9mDBlyhS0adOmZMD11NRULFy4sOR57j/3mTBhAjweD0aMGFHyGPej3J588kl4PB6fnxYtWpQ879r9p5BtZs+erVSsWFGZNm2asnXrVuWee+5RqlevruTl5TkdWsz56quvlMcff1yZM2eOAkCZO3euz/MTJkxQEhMTlXnz5ik//fSTcu211yqNGzdWjh07VrLMlVdeqbRt21ZZvXq18t133ylNmjRRBgwYUPJ8fn6+kpSUpNx2223Kli1blA8//FCpXLmy8tZbb0XqbUatXr16Ke+++66yZcsWJSsrS+nTp4/SsGFDpbCwsGSZIUOGKCkpKcqSJUuUdevWKRdffLHSqVOnkudPnz6ttG7dWunevbuyceNG5auvvlJq1aqlpKenlyzzxx9/KFWqVFFGjhypbNu2TXnttdeUcuXKKYsWLYro+41Gn3/+ufLll18qv/76q7J9+3blscceUypUqKBs2bJFURTuP7dZu3atctZZZylt2rRRHnzwwZLHuR/lNm7cOOXcc89VcnJySn7++uuv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WloarrzyShQXFwMA8vLycM8996Bp06ZITExEQkICCgsLkZ2dHTReb2z+8R4/fhwFBQUljzVs2BD169cv+T81NRXFxcU+bYq9duzYgaNHj6JHjx4+73HGjBkl72/o0KGYPXs22rVrh1GjRmHlypVBty8RkR7sAEZEZFKFChV8/vd4PD6PeTweAChJOgsLC3HNNdfgueeeK1NW3bp1Q66rdevWaN26Ne677z4MGTIEl156KZYvX47LL78caWlp+OeffzBp0iQ0atQI8fHxSE1NxcmTJ4PG640tVLxGFRYWAgC+/PJLnwQYAOLj4wEAvXv3xq5du/DVV18hMzMT3bp1w7Bhw/Diiy+aWicREZNZIqIIOf/88/HZZ5/hrLPOQvny5k+/rVq1AgAcOXIEAPDDDz/gjTfeQJ8+fQAAu3fvDtmpzIjs7Gzs27cP9erVAwCsXr0acXFxaN68ecC44uPjkZ2djS5dugQts3bt2khLS0NaWhouvfRSPProo0xmicg0JrNERBEybNgwTJ06FQMGDMCoUaNQs2ZN7NixA7Nnz8bbb7+NcuXKlXnN0KFDUa9ePVxxxRVo0KABcnJy8PTTT6N27dpITU0FADRt2hTvv/8+LrjgAhQUFODRRx9F5cqVhcRcqVIlpKWl4cUXX0RBQQEeeOAB3HTTTUhOTi6zbLVq1fDII4/goYceQnFxMTp37oz8/Hz88MMPSEhIQFpaGp544gl06NAB5557Lk6cOIEFCxagZcuWQmIlotjENrNERBFSr149/PDDDygqKkLPnj1x3nnnYcSIEahevTri4gKfjrt3747Vq1ejf//+aNasGW644QZUqlQJS5YswZlnngkAeOedd3Dw4EGcf/75GDhwIB544AHUqVNHSMxNmjTB9ddfjz59+qBnz55o06YN3njjjaDLjx8/HmPHjkVGRgZatmyJK6+8El9++SUaN24MAKhYsSLS09PRpk0bXHbZZShXrhxmz54tJFYiik0eRVEUp4MgIiL5PPnkk5g3bx6ysrKcDoWIKCjWzBIRERGRazGZJSIiIiLXYjMDIiIiInIt1swSERERkWsxmSUiIiIi12IyS0RERESuxWSWiIiIiFyLySwRERERuRaTWSIiIiJyLSazRERERORaTGaJiIiIyLWYzBIRERGRa/0//DMiIuHXtN0AAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "print('Scarr Plot of DL-LA Sensitivity')\n", - "fig, ax = plt.subplots(figsize=(8, 4))\n", - "ax.plot(sens, color='red')\n", - "\n", - "ax.set_xlabel('Time Samples')\n", - "ax.set_ylabel('Sensitivity')\n", - "\n", - "plt.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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 -} From 59abe7a24a251632ad80881114d87b5641fd0960 Mon Sep 17 00:00:00 2001 From: Stefan Ene Date: Wed, 21 Aug 2024 16:43:47 -0700 Subject: [PATCH 3/3] added torch to requirements --- pyproject.toml | 1 + requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index a0a3b5a..2335db8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ 'numpy<2', 'numba', 'zarr[jupyter]', + 'torch', 'ruff', 'mpmath', 'matplotlib', diff --git a/requirements.txt b/requirements.txt index 7dbfd65..e91cd92 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ numpy<2 numba zarr[jupyter] +torch ruff mpmath matplotlib