{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/kleinsteuber/anaconda3/envs/pytorch-gpu/lib/python3.10/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Found 2 sessions\n", "Session 'Beaver_01' at folder: /home/kleinsteuber/vscode/ResizedSessions256_NoBackup/VIELAAS_Spring_Session01-VIELAAS_Beaver_01\n", "Loaded scans.\n" ] } ], "source": [ "%load_ext autoreload\n", "%autoreload 2\n", "\n", "from glob import glob\n", "from torchinfo import summary\n", "import numpy as np\n", "from sklearn.neighbors import KernelDensity\n", "from sklearn.linear_model import LogisticRegression\n", "import matplotlib.pyplot as plt\n", "from tqdm import tqdm\n", "import pandas as pd\n", "\n", "from py.Dataset import Dataset\n", "from py.Labels import LABELS\n", "from py.ImageUtils import display_images\n", "from py.FileUtils import load\n", "\n", "DIR = '/home/kleinsteuber/vscode/ResizedSessions256_NoBackup' # dataset directory\n", "SESSION = \"beaver_01\"\n", "TRAIN_NAME = \"ae2_deep_noise_sparse\"\n", "\n", "ds = Dataset(DIR)\n", "session = ds.create_session(SESSION)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "lapse_losses, lapse_encodings, lapse_labels = load(f\"./ae_train_NoBackup/{TRAIN_NAME}/eval/{session.name}_lapse.pickle\")\n", "motion_losses, motion_encodings, motion_labels = load(f\"./ae_train_NoBackup/{TRAIN_NAME}/eval/{session.name}_motion.pickle\")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "kde = KernelDensity(kernel=\"gaussian\", bandwidth=0.2).fit(lapse_encodings)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "preds = kde.score_samples(motion_encodings)\n", "y_anom = preds[motion_labels == 1]\n", "y_norm = preds[motion_labels == 0]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "count 7.400000e+01\n", "mean -2.073727e+07\n", "std 6.007246e+07\n", "min -3.089760e+08\n", "25% -1.017565e+07\n", "50% -7.924425e+06\n", "75% -2.720522e+06\n", "max 3.167954e+02\n", "dtype: float64" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.Series(y_norm).describe()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "count 6.210000e+02\n", "mean -2.110057e+08\n", "std 3.090626e+08\n", "min -1.801623e+09\n", "25% -1.874621e+08\n", "50% -7.601582e+07\n", "75% -4.367579e+07\n", "max -7.580517e+05\n", "dtype: float64" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.Series(y_anom).describe()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(621, 2)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.array([preds[motion_labels == 1], motion_losses[motion_labels == 1]]).transpose().shape" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.8935251798561151" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mode = \"loss\"\n", "\n", "if mode == \"kde\":\n", " y_anom = preds[motion_labels == 1]\n", " y_norm = preds[motion_labels == 0]\n", " X = np.concatenate([y_norm, y_anom]).reshape((-1, 1))\n", " y = np.concatenate([-np.ones_like(y_norm), np.ones_like(y_anom)])\n", "elif mode == \"loss\":\n", " y_anom = motion_losses[motion_labels == 1]\n", " y_norm = motion_losses[motion_labels == 0]\n", " X = np.concatenate([y_norm, y_anom]).reshape((-1, 1))\n", " y = np.concatenate([-np.ones_like(y_norm), np.ones_like(y_anom)])\n", "elif mode == \"loss,kde\" or mode == \"kde,loss\":\n", " y_anom = np.array([preds[motion_labels == 1], motion_losses[motion_labels == 1]]).transpose()\n", " y_norm = np.array([preds[motion_labels == 0], motion_losses[motion_labels == 0]]).transpose()\n", " X = np.concatenate([y_norm, y_anom])\n", " y = np.concatenate([-np.ones((y_norm.shape[0])), np.ones((y_anom.shape[0]))])\n", "else:\n", " raise ValueError(\"unknown mode\")\n", "\n", "clf = LogisticRegression().fit(X, y)\n", "clf.score(X, y)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Accuracy: 0.894\n", "True anomalous rate (must be high!): 1.000 \t - How many animals are detected as animals? (recall)\n", "True normal rate (higher is better): 0.000 \t - How many empties are detected as empties?\n", "False anomalous rate (lower is better): 1.000 \t - How many empties are detected as animals?\n", "False normal rate (must be low!): 0.000 \t - How many animals are detected as empties?\n", "Precision (higher is better): 0.894 \t - How many detected animals are actually animals?\n" ] } ], "source": [ "def eval_test(df_threshold = 0):\n", " test_results = np.where(clf.decision_function(X) >= df_threshold, np.ones(y.shape[0]), -np.ones(y.shape[0]))\n", "\n", " accuracy = np.mean(test_results == y)\n", " tar = np.sum((test_results == 1) & (y == 1)) / np.sum(y == 1)\n", " tnr = np.sum((test_results == -1) & (y == -1)) / np.sum(y == -1)\n", " far = np.sum((test_results == 1) & (y == -1)) / np.sum(y == -1)\n", " fnr = np.sum((test_results == -1) & (y == 1)) / np.sum(y == 1)\n", " precision = (np.sum((test_results == 1) & (y == 1)) / np.sum(test_results == 1)) if np.any(test_results == 1) else 0\n", "\n", " return accuracy, tar, tnr, far, fnr, precision\n", "\n", "accuracy, tar, tnr, far, fnr, precision = eval_test()\n", "\n", "print(f\"Accuracy: {accuracy:.3f}\")\n", "print(f\"True anomalous rate (must be high!): {tar:.3f} \\t - How many animals are detected as animals? (recall)\")\n", "print(f\"True normal rate (higher is better): {tnr:.3f} \\t - How many empties are detected as empties?\")\n", "print(f\"False anomalous rate (lower is better): {far:.3f} \\t - How many empties are detected as animals?\")\n", "print(f\"False normal rate (must be low!): {fnr:.3f} \\t - How many animals are detected as empties?\")\n", "print(f\"Precision (higher is better): {precision:.3f} \\t - How many detected animals are actually animals?\")" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "150 points\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "150it [00:00, 2539.24it/s]\n" ] } ], "source": [ "df_threshold_range = (2.12, 2.135, 0.0001)\n", "num_points = len(np.arange(*df_threshold_range))\n", "print(f\"{num_points} points\")\n", "eval_results = np.empty((num_points, 7))\n", "\n", "for i, df_threshold in tqdm(enumerate(np.arange(*df_threshold_range))):\n", " metrics = eval_test(df_threshold)\n", " eval_results[i] = [df_threshold, *metrics]" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "image/png": "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tXJycrRu3brD1nrvvfdq4sSJqq2tPezrv/rqqxo6dKhycnJ0/fXXq6amRpJvBPOOO+7QoEGDNGrUKO3atUuS9NRTTykzM1MDBgzQhAkTmvRndzgENQAIBfUjasfQ9bEeG18DQGDV1NTo888/1znnnCNJuu666/T0009rwYIFeuyxx3TTTTdJkm655RaNHDlSS5Ys0cKFC5WVlSVJeumll7RgwQLNnz9fTz31lPLz8494vo8//lhjx4494jFvvvmmLr74Yl1yySWaPHnyIY/55JNPdO655zbpe12+fLlycnLk9XoPemzBggV6+eWXNWfOHH377bd6/vnntWjRIknS6tWrdcUVV2jRokXq2rXrfl+vXr1aa9as0dy5c7V48WItWLBAs2bN0vLly/Xwww9r+vTpWrJkiZ588kmdcMIJOuecc/yjgj169DhknXfddZd27typl19+WdOmTTvk669cuVJvvvmmvv76ay1evFher1evvfaaJKmkpESDBg3SwoULNXLkSP3+97+XJD3yyCNatGiRli5dqkmTJjXpz+5w6PoIAKGgmWvUJDa+BhB6ut3zv6C87sZHzjri42VlZcrJydHGjRs1ePBgjR49WsXFxZo9e7YuvPBC/3EVFRWSpOnTp+tf//qXJN/6tuRk3y/OnnrqKb3//vuSpM2bN2vNmjVq3br1Yc/79ddf67HHHjvs4/PmzVNaWpq6du2qTp066aqrrtKePXvUqlUrSdKvf/1rf5D59ttvG/En0ThfffWVzjvvPMXHx0uSzj//fH355Zc655xz1LVrVx1//PH+Yxt+PXXqVE2dOlUDBw6U5FsDt2bNGi1ZskQXXHCB2rRpI0lKTU1tVB1/+MMfNGzYMP/o5OFef+nSpVqwYIGGDBkiyXc927b1dUT2eDy6+OKLJUk/+9nPdP7550uSBgwYoMsuu0znnntuk0Pu4TCiBgChoJnt+SUpq25EbTmdHwGgWerXqP3www+qrKzUM888o9raWqWkpPjXiy1evFgrV6487GvMmDFD06ZN0zfffKMlS5Zo4MCBR+wauH79enXu3FlRUVGHPWby5MlatWqVunXrph49emjfvn169913/Y8/+uijWrt2rR566CFdeeWVBz1/8+bN/sYkB44aZWVlacmSJYdcV2ZZ1mFrqg9vh/rasiz95je/8f95rV27VldffbUsyzqm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KVG/fv304IMPStJ+X69cuVJ//vOf9fXXXysyMlI33XSTXnvtNZ155pm69tprNWvWLGVkZKigoECpqam64YYblJCQoDvvvPOgGh5++GGddtppeumll1RYWKihQ4cedfRqz549mj59uqZMmaJx48bp66+/1gsvvKAhQ4Zo8eLFysnJ2e/4NWvWaPLkyXr++ed10UUX6d1339XPfvYznX/++br22mslSb/73e/04osv6pe//KXOOeccnX322brgggv2e53y8nJNnDhRn3/+uXr37q0rrrhCzz77rG677TZJUps2bbRw4UL9/e9/12OPPaYXXnhBjz32mJ555hmdeOKJKi4uVkxMTGMv3WExogYAbhfgETWpQedHWvQDQEAlJSXpiiuu0FNPPXXQY48//riOO+44DRs2zL92LRDmzZunU045RWlpaYqIiNBll12mWbNmSZK8Xq9++tOf+o9t+PXnn3+uBQsWaMiQIcrJydHnn3+u9evX69tvv9XJJ5+sjIwMSVJqaupRa5g6daoeeeQR5eTk6JRTTlF5ebk2bdp0xOeMGzdOxhj1799f7dq1U//+/eXxeJSVlaWNGzcedHxGRoY/vA0ePNh/zLJlyzRixAj1799fr732mpYvX37E865evVoZGRnq3bu3JOnKK6/0/3lJ0vnnn3/QOU488UT96le/0lNPPaXCwkJFRDR/PIwRNQBwu7LArlGTxNRHAKGhGSNfwXTbbbdp0KBB+vnPf77f/bfffrvuvPNOvffee7riiiu0bt26/UZmampqNHjwYEm+9Vz1o2CS1LNnT23atElFRUVKTEzc73WP1BgqJiZGXq/3kF9blqUrr7xSf/rTn/Z7zpQpU2SMadL3bFmW3n33XR133HH73b9jx47DPqd+CqfH4/F/Xv91dXX1YY+XfIGzfurjxIkT9cEHHyg7O1uvvPKKZsyYcdRaj6T+PF6v11/HPffco7POOksfffSRjj/+eE2bNk19+vQ54uscDSNqAOB2Ae76KEnd28QrOsKjvD1l2lvWtMXsAIAjS01N1UUXXaQXX3zxkI+ff/75ys3N1T//+c/97vd6vf7GJA1DmiTFxcXp6quv1i233KLKykpJ0rZt2/Tqq69q2LBhmjlzpnbv3q2amhpNnjxZI0eOPGqdo0aN0jvvvKOdO3dKkgoKCvTDDz9o+PDhmjlzpjZs2OC/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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "metrics_names = [\"Accuracy\", \"Recall/TAR - Correct keeps\", \"TNR - Correct eliminations\", \"FAR\", \"FNR\", \"Precision\"]\n", "enable_metrics = [1, 2]\n", "plt.figure(figsize=(15, 10))\n", "for i, metrics_name in enumerate(metrics_names):\n", " if i in enable_metrics:\n", " plt.plot(eval_results[:,0], eval_results[:,(i+1)], label=metrics_name, linewidth=2)\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "threshold = 0.599999999999774, recall = 1.0, tnr = 1.0\n" ] } ], "source": [ "i = 0\n", "while eval_results[i+1,2] >= 0.99:\n", " i += 1\n", "print(f\"threshold = {eval_results[i,0]}, recall = {eval_results[i,2]}, tnr = {eval_results[i,3]}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3.10.4 ('pytorch-gpu')", "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.4" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "17cd5c528a3345b75540c61f907eece919c031d57a2ca1e5653325af249173c9" } } }, "nbformat": 4, "nbformat_minor": 2 }