This commit is contained in:
korzerce84997 committed 2026-02-24 11:42:58 +01:00
1 parent 42965a4733
commit 15190ac52e
6 files changed
+7633

No files matched your search

File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+663
View File
@@ -0,0 +1,663 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "8698744b",
"metadata": {},
"source": [
"Bibliotheken importieren"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "a1be2d54",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"from pathlib import Path\n",
"\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn.preprocessing import StandardScaler\n",
"from sklearn.metrics import accuracy_score, f1_score, roc_auc_score, confusion_matrix, classification_report\n",
"\n",
"import tensorflow as tf\n",
"from tensorflow.keras import Input, layers, models, regularizers\n",
"\n",
"import joblib \n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"id": "9a2832a7",
"metadata": {},
"source": [
"Daten laden"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "f2a8a12d",
"metadata": {},
"outputs": [],
"source": [
"data_path = Path(r\"~/data-paulusjafahrsimulator-gpu/new_datasets/50s_25Hz_dataset.parquet\") \n",
"\n",
"df = pd.read_parquet(path=data_path)"
]
},
{
"cell_type": "markdown",
"id": "5192248c",
"metadata": {},
"source": [
"Labels erstellen"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "05b15322",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Label distribution:\n",
"label\n",
"1 4750\n",
"0 3484\n",
"Name: count, dtype: int64\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/tmp/ipykernel_2528/3529185502.py:9: SettingWithCopyWarning: \n",
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
"Try using .loc[row_indexer,col_indexer] = value instead\n",
"\n",
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
" low_all[\"label\"] = 0\n"
]
}
],
"source": [
"low_all = df[((df[\"PHASE\"] == \"baseline\") | \n",
" ((df[\"STUDY\"] == \"n-back\") & (df[\"PHASE\"] != \"baseline\") & (df[\"LEVEL\"].isin([1,4]))))] \n",
"\n",
"high_all = pd.concat([ \n",
" df[(df[\"STUDY\"]==\"n-back\") & (df[\"LEVEL\"].isin([2,3,5,6])) & (df[\"PHASE\"].isin([\"train\",\"test\"]))], \n",
" df[(df[\"STUDY\"]==\"k-drive\") & (df[\"PHASE\"]!=\"baseline\")] \n",
"]) \n",
"\n",
"low_all[\"label\"] = 0 \n",
"high_all[\"label\"] = 1 \n",
"data = pd.concat([low_all, high_all], ignore_index=True).drop_duplicates() \n",
"\n",
"print(\"Label distribution:\") \n",
"print(data[\"label\"].value_counts())"
]
},
{
"cell_type": "markdown",
"id": "9b44f8a4",
"metadata": {},
"source": [
"Feature-Auswahl"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "5c11e2fd",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['subjectID', 'start_time', 'STUDY', 'LEVEL', 'PHASE', 'FACE_AU01_mean', 'FACE_AU02_mean', 'FACE_AU04_mean', 'FACE_AU05_mean', 'FACE_AU06_mean', 'FACE_AU07_mean', 'FACE_AU09_mean', 'FACE_AU10_mean', 'FACE_AU11_mean', 'FACE_AU12_mean', 'FACE_AU14_mean', 'FACE_AU15_mean', 'FACE_AU17_mean', 'FACE_AU20_mean', 'FACE_AU23_mean', 'FACE_AU24_mean', 'FACE_AU25_mean', 'FACE_AU26_mean', 'FACE_AU28_mean', 'FACE_AU43_mean', 'Fix_count_short_66_150', 'Fix_count_medium_300_500', 'Fix_count_long_gt_1000', 'Fix_count_100', 'Fix_mean_duration', 'Fix_median_duration', 'Sac_count', 'Sac_mean_amp', 'Sac_mean_dur', 'Sac_median_dur', 'Blink_count', 'Blink_mean_dur', 'Blink_median_dur', 'Pupil_mean', 'Pupil_IPA', 'label']\n",
"Gefundene FACE_AU-Spalten: ['FACE_AU01_mean', 'FACE_AU02_mean', 'FACE_AU04_mean', 'FACE_AU05_mean', 'FACE_AU06_mean', 'FACE_AU07_mean', 'FACE_AU09_mean', 'FACE_AU10_mean', 'FACE_AU11_mean', 'FACE_AU12_mean', 'FACE_AU14_mean', 'FACE_AU15_mean', 'FACE_AU17_mean', 'FACE_AU20_mean', 'FACE_AU23_mean', 'FACE_AU24_mean', 'FACE_AU25_mean', 'FACE_AU26_mean', 'FACE_AU28_mean', 'FACE_AU43_mean']\n"
]
}
],
"source": [
"au_columns = [col for col in data.columns if col.lower().startswith(\"face\")] \n",
"print(data.columns.tolist())\n",
"\n",
"print(\"Gefundene FACE_AU-Spalten:\", au_columns)"
]
},
{
"cell_type": "markdown",
"id": "52aaa568",
"metadata": {},
"source": [
"Train-/Val- und Test-Split nach Subjects"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "78023e16",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(4116, 41) (1235, 41) (2883, 41)\n"
]
}
],
"source": [
"subjects = np.random.permutation(data[\"subjectID\"].unique()) \n",
"n = len(subjects) \n",
"n_train = int(n*0.66) \n",
"\n",
"train_subjects = subjects[:n_train] \n",
"test_subjects = subjects[n_train:] \n",
"train_subs, val_subs = train_test_split(train_subjects, test_size=0.2, random_state=42) \n",
"\n",
"train_df = data[data.subjectID.isin(train_subs)] \n",
"val_df = data[data.subjectID.isin(val_subs)] \n",
"test_df = data[data.subjectID.isin(test_subjects)] \n",
"\n",
"print(train_df.shape, val_df.shape, test_df.shape)"
]
},
{
"cell_type": "markdown",
"id": "4fbd22c4",
"metadata": {},
"source": [
"Normalisierung - StandardScaler global"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "13a6ec83",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Vorher (erste 5 Werte): FACE_AU01_mean FACE_AU02_mean FACE_AU04_mean\n",
"697 0.792161 0.804894 0.310528\n",
"698 0.793914 0.806557 0.312750\n",
"699 0.795915 0.803190 0.293604\n",
"700 0.790821 0.797190 0.299714\n",
"701 0.790045 0.793320 0.292109\n",
"Nachher (erste 5 Werte): FACE_AU01_mean FACE_AU02_mean FACE_AU04_mean\n",
"697 0.679178 1.116911 1.874625\n",
"698 0.709019 1.138696 1.913728\n",
"699 0.743082 1.094597 1.576792\n",
"700 0.656358 1.016024 1.684310\n",
"701 0.643142 0.965348 1.550483\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA0EAAAF0CAYAAADl1TLuAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAR29JREFUeJzt3X1cVGX+//H3CMNwo5CicqOk5uJdaJmmQbVqCOZN1tqu29qWpra1lsVDXdOfW2I3albqrm21tQSWmms32p0puBplZKtmpeXazaplSpSpeBcgXL8/+jLrMIAzwMDAeT0fj3nonLnOda7PnDPnw+ecM2dsxhgjAAAAALCIZg09AAAAAACoTxRBAAAAACyFIggAAACApVAEAQAAALAUiiAAAAAAlkIRBAAAAMBSKIIAAAAAWApFEAAAAABLoQgCAAAAYCkUQU3Ir371K4WEhOjo0aNVtrnxxhtlt9v13Xff1Xp548aNU/PmzWvdT13bt2+fbDZbpY++ffu6tN25c6dsNpvsdrsOHTpUZZ+FhYV66KGH1LdvX4WHh8vhcKhjx44aP368PvzwQ2e7rKysKpdts9n09ttv1yimKVOmyGazacSIEZW+/vbbb8tms+mll16q9PU777xTNpvNbfqGDRuUmJio0NBQtW7dWuPGjVNBQYFbuz//+c8aMWKE2rVrJ5vNpnHjxtUoDgBNU/m+Lzg4WPv373d7feDAgUpISPDZ8j3NR+X54dFHH/XZWGpq3LhxVeaON954w6XtqFGjZLPZdOedd1bb57vvvqvRo0erXbt2CgoKUkREhJKSkvTkk0/q5MmTznYdO3asctkDBw6sUTw//PCDHA6HbDabtm3bVmmb6raLH374QTabTenp6S7TT5w4obS0NMXGxio4OFgXX3yxVq5c6Tb/5s2bNXHiRPXp08c5jn379tUoFjRNgQ09ANSdCRMmaM2aNVqxYoUmTZrk9vqxY8e0evVqjRgxQlFRUQ0wwvo1efJkjRkzxmVaxST5j3/8Q5J05swZPffcc7rnnnvc+vnqq6+UmpqqgoIC3X777ZozZ46aN2+uffv2adWqVerTp4+OHj2qiIgI5zyZmZnq1q2bW189evTwOo6SkhItW7ZMkrRu3Tp9++23ateundf9VJSbm6uhQ4dq+PDhevXVV1VQUKB77rlHycnJ2rZtmxwOh7PtokWL1KtXL40cOVLPPvtsrZcNoGkqKirSn//8Zz3//PMNPZRGKSQkRBs3bnSbfnY+KSgocBZFy5cv16OPPqrg4GC3eWbPnq37779fSUlJeuCBB9S5c2edOnVKeXl5Sk9P1+eff65FixY5219++eWVFofh4eE1iuX5559XcXGxJCkjI8PtIGRNjRo1Slu3btX8+fPVpUsXrVixQr/73e9UVlbmkvP/9a9/acOGDerdu7fCw8NrfBASTZhBk3HmzBkTGxtr+vTpU+nrTz75pJFkXn/99Votp7i42JSUlJixY8easLCwWvXliVOnTnnVfu/evUaSeeSRR6pt99NPP5nIyEhz0UUXmXbt2pkuXbq4tTlz5ozp2bOnCQ8PNzt37qy0n7Vr15qTJ08aY4zJzMw0kszWrVu9GnN1XnzxRSPJDB8+3EgyDz30kFubTZs2GUnmxRdfrLSPO+64w1T8uF966aWmR48epqSkxDntvffeM5LME0884dK2tLTU+f+wsDAzduzYWkQEoKkp3/ddffXVplmzZuajjz5yeX3AgAHmwgsv9NnyPc1HnuaH2jp16pQpKyvzah5PY3jkkUdccsLy5cvd2qxatcpIMhMmTKh0HIWFhWb9+vXO5x06dDDDhw/3arznkpCQYNq2bWsuvfRSExERUWkur267+P77740kM3v2bOe0N99800gyK1ascGmbkpJiYmNjzZkzZ5zTzs5b5e/Z3r17axcUmhQuh2tCAgICNHbsWG3fvl07d+50ez0zM1MxMTEaOnSoJGnXrl269tpr1bJlS+cp5aVLl7rMU36Z1fPPP6+pU6eqXbt2cjgc+vLLL51tvvzySw0bNkzNmzdXXFycpk6dqqKiIpd+iouL9eCDD6pbt25yOBxq06aNbrnlFn3//fcu7Tp27KgRI0bolVdeUe/evRUcHKw5c+bU1VvkYs2aNTp8+LAmTpyosWPH6vPPP9fmzZvd2uzcuVMzZ86s8pT90KFDFRoa6pMxSj8fQQsKClJmZqbi4uKUmZkpY0yt+vz222+1detW3XTTTQoM/N8J4aSkJHXp0kWrV692ad+sWd3sKsovmdm4caNuvfVWRUZGKjw8XDfffLNOnjyp/Px8jR49Wuedd55iYmI0bdo0lZSUuPTh6bb0z3/+U6mpqYqJiVFISIi6d++uGTNmuFwCIv3vMhpPtmMA1Zs+fboiIyMrPate0d/+9jf98pe/VNu2bRUWFqaePXtqwYIFbp956eez4MnJyYqIiFBoaKi6d++uefPmubXz5nO8cOFCderUSc2bN1diYqK2bNni1mbbtm0aOXKkWrVqpeDgYPXu3VurVq1yaVO+X8vOztb48ePVpk0bhYaG+mz/8eyzzyoqKkpLly5VSEhIpWfn77//frVs2VJ//etfK70UukWLFkpNTfXJ+CTpgw8+0K5du3TTTTfp1ltv1bFjx/Tyyy/Xut/Vq1erefPm+s1vfuMy/ZZbbtHBgwf1wQcfOKfVVd6S/ve3yRtvvKHevXs7c0r5GbmsrCx1795dYWFh6tevX6WX/3myLX3//feaNGmSevTooebNm6tt27a66qqr9O6777q0O/uyTk+2Y1SOIqiJGT9+vGw2m9tO8bPPPtO///1vjR07VgEBAdqzZ4+SkpL06aef6q9//ateeeUV9ejRQ+PGjdOCBQvc+p05c6a+/vprPfXUU3r99dfVtm1bST9fqjVy5EglJyfr1Vdf1fjx47Vo0SI9/PDDznnLysp07bXXav78+RozZozefPNNzZ8/Xzk5ORo4cKBOnz7tsqwPP/xQf/rTn3TXXXdp3bp1uv766yX9fO1wZTvzqpSVlenMmTMuj7OLh4yMDDkcDt14443O9y0jI8Olj+zsbEnSdddd5/FyJam0tNRt2aWlpV71IUkHDhxQdna2rr32WrVp00Zjx47Vl19+qXfeecfrvs62a9cuSVKvXr3cXuvVq5fzdV+ZOHGiIiIitHLlSv35z3/WihUrdOutt2r48OG66KKL9NJLL2ns2LF67LHHtGTJEud83mxLX3zxhYYNG6aMjAytW7dOaWlpWrVqla655hq38XiyHQM4txYtWujPf/6z1q9fX+llXWf76quvNGbMGD3//PN64403NGHCBD3yyCO67bbbXNplZGRo2LBhKisrc+agu+66SwcOHHBp583n+G9/+5tycnK0ePFiLV++XCdPntSwYcN07NgxZ5tNmzbp8ssv19GjR/XUU0/p1Vdf1cUXX6zf/va3ysrKcutz/Pjxstvtev755/XSSy/Jbrc7DyRW/F5LdarLHXl5edq9e7duvvlmRUZG6vrrr9fGjRu1d+9eZ5tDhw5p165dSk1N9eoAnTHGbdkV86anynPp+PHjdcMNNyg0NNQtv9bErl271L17d5eDd9L/cpkvc9fHH3+smTNn6p577tErr7yiiIgIjRo1SrNnz9Y//vEPzZ07V8uXL9exY8c0YsQIl3zk6bb0448/Svr5UsY333xTmZmZuuCCCzRw4MBKL+fzZDtGNRr2RBR8YcCAAaZ169amuLjYOW3q1KlGkvn888+NMcbccMMNxuFwmK+//tpl3qFDh5rQ0FBz9OhRY8z/LrP65S9/6bacsWPHGklm1apVLtOHDRtmunbt6nz+wgsvGEnm5Zdfdmm3detWt0uvOnToYAICAsyePXvclnfVVVeZgICAc8ZffrlDZY+cnBxjjDH79u0zzZo1MzfccINzvgEDBpiwsDBTWFjonHb11VcbSeann34653KN+d8lIZU9PBl7Rffff7+RZNatW2eMMea///2vsdls5qabbnJp5+3lcMuXLzeSzPvvv+/W9g9/+IMJCgqqcky1uRyu/P2ZPHmyy/TrrrvOSDILFy50mX7xxRebSy65xPncm23pbGVlZaakpMTk5uYaSebjjz92vubpdgygamdfClxUVGQuuOAC07dvX+elWOe6HK60tNSUlJSY5557zgQEBJgff/zRGGPM8ePHTXh4uLniiiuqvbzM089xeX7o2bOny6VT//73v40k88ILLzindevWzfTu3dvlkmFjjBkxYoSJiYlxXm5VHvvNN9/sNq63337bBAQEmDlz5lQ59ooxVHxcfvnlzjbjx483kszu3buNMf/b9997773ONlu2bDGSzIwZM865zHIdOnSoMnc98MADHvdjjDEnT5404eHh5rLLLnOJzWazmS+//NKlrbeXw8XHx5shQ4a4tT148KCRZObOnVtpX7W9HK5Dhw4mJCTEHDhwwDnto48+MpJMTEyM85J4Y4xZs2aNkWRee+015zRPt6WKzpw5Y0pKSkxycrL51a9+5ZzuzXaMqnEmqAmaMGGCfvjhB7322muSfj6qtGzZMl155ZWKj4+XJG3cuFHJycmKi4tzmXfcuHE6deqU3n//fZfp5WdjKrLZbG5H1nv16uVyd6A33nhD5513nq655hqXo0sXX3yxoqOj3Y5u9OrVS126dHFb1r/+9S+dOXPGszdB0t13362tW7e6PPr37y/p50sDy8rKNH78eGf78ePH6+TJk/rnP//p8TKq8txzz7kt++zT9J4wxjgvgUtJSZEkderUSQMHDtTLL7+swsLCWo+zqjNr3pxxq4mKd7nr3r27JGn48OFu02u6Lf33v//VmDFjFB0drYCAANntdg0YMECStHv3bpfleLIdA/BMUFCQHnzwQW3bts3tcp+z7dixQyNHjlRkZKTzM3rzzTertLRUn3/+uaSfz3wUFhZq0qRJ59wvefM5Hj58uAICAlzaSXKLine truncated
"text/plain": [
"<Figure size 1000x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"scaler = StandardScaler() \n",
"scaler.fit(train_df[au_columns]) \n",
"\n",
"train_scaled = train_df.copy() \n",
"val_scaled = val_df.copy() \n",
"test_scaled = test_df.copy() \n",
"\n",
"train_scaled[au_columns] = scaler.transform(train_df[au_columns]) \n",
"val_scaled[au_columns] = scaler.transform(val_df[au_columns]) \n",
"test_scaled[au_columns] = scaler.transform(test_df[au_columns])\n",
"\n",
"#Normalisierung - Vorher-Nachher Vergleich\n",
"print(\"Vorher (erste 5 Werte):\", train_df[au_columns].iloc[:5, :3])\n",
"print(\"Nachher (erste 5 Werte):\", train_scaled[au_columns].iloc[:5, :3])\n",
"\n",
"#Histogramme - vor und nach Normalisierung\n",
"col = au_columns[0] # erste AU-Spalte\n",
"plt.figure(figsize=(10,4))\n",
"plt.subplot(1,2,1)\n",
"train_df[col].hist(bins=30)\n",
"plt.title(f\"Vorher: {col}\")\n",
"\n",
"plt.subplot(1,2,2)\n",
"train_scaled[col].hist(bins=30)\n",
"plt.title(f\"Nachher: {col}\")\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "367533dc",
"metadata": {},
"source": [
"Datenvorbereitung für CNN "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e5c1c8ae",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"X_train Shape: (4116, 20, 1)\n",
"X_val Shape: (1235, 20, 1)\n",
"X_test Shape: (2883, 20, 1)\n",
"Train Labels: [1741 2375]\n",
"Val Labels: [524 711]\n",
"Test Labels: [1219 1664]\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAz8AAAF0CAYAAAANVYfFAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAOhJJREFUeJzt3XtYVNXCx/HfyE1AmAQUREk45S3xFnlMMsW8lDdKMyvLvNDJ1CxS81ppZqBWaifLjmViXjtlauUlMY1Or/qmniy1y8mTpiaoqYEaAuJ6/+hhXscBZRAadX8/z7Ofx1l77TVrz+zB+c3ae22bMcYIAAAAAK5ylTzdAQAAAAD4MxB+AAAAAFgC4QcAAACAJRB+AAAAAFgC4QcAAACAJRB+AAAAAFgC4QcAAACAJRB+AAAAAFgC4QcAAACAJRB+gEvUvXt3+fv767fffiuxzgMPPCAfHx8dOnTokp/v4MGDmjBhgrZv317mNj777DPZbDZ99tlnjrIJEybIZrNdcv+uRkWv1/vvv39J7XzzzTfq37+/YmJiVLlyZVWpUkU33nijpk6dqmPHjjnqJSQkyGaz6Y477nBpY+/evbLZbHrppZdc+mez2bRp0yaXbfr166cqVaqUqo/9+vVztHX+8vHHH5dhrz2v6PUsbtm5c2eFPOeiRYs0Y8aMCmn7UhV91otbZs6c6VR32LBhstls6tq16wXbdPfYLm6Jjo4u0/4UFBQoIiLigp/Ri30GqlSpon79+rm0+9xzzyk6Olp+fn6qX7++Xn31VZdtd+3apcGDB6tly5YKDAx0+dsK4PLi7ekOAFe6pKQkLV++XIsWLdLgwYNd1mdnZ2vZsmXq2rWrwsPDL/n5Dh486PgPuWnTpmVq48Ybb9SmTZt0ww03XHJ/UDpvvvmmBg8erHr16umpp57SDTfcoIKCAm3dulVvvPGGNm3apGXLljlt88knn2j9+vW67bbbSv08I0eO1L/+9a9L6qu/v7/Wr1/vUl6/fv1LateT/vKXv2jhwoUu5dddd12FPN+iRYu0c+dOJScnV0j75WHNmjWy2+1OZTExMY5/FxQUaMGCBY66v/zyi2rWrOnSjrvHdknvhZ+fX5n24+OPP3b8sDRnzhz17NmzTO2cb/DgwZo/f76ef/55NW/eXJ988omeeOIJnThxQmPHjnXU27p1q5YvX65mzZqpXbt2+uijj8rl+QFUDMIPcIk6deqkyMhIvf3228WGn8WLFys3N1dJSUmX9DyFhYU6c+bMJbVRJDg4WDfffHO5tIWL27RpkwYNGqQOHTpo+fLlTl/yOnTooOHDh2vNmjVO29StW1dnzpzRyJEjtWXLllKNyt1xxx1as2aNPvroI3Xr1q3M/a1UqVKFHR+///67AgICKqTtC/H3978qjvnyfP3i4uIUFhZW4voVK1boyJEj6tKli1auXKl58+Y5femXynZsl/d7MWfOHPn6+qpNmzZau3atDhw4oFq1al1Sm7t27dKcOXP0wgsv6KmnnpL0x6jV0aNHNWnSJD366KMKCQmRJPXp00d9+/aVJL3//vuEH+Ayx2lvwCXy8vJS3759tW3bNu3YscNl/dy5c1WjRg116tRJkpSVlaWBAweqVq1a8vX1VUxMjJ577jmnYFN0atPUqVM1adIkxcTEyM/PTxs2bFDz5s0lSf3793ecLjJhwgTHtlu3blViYqJCQkJUuXJlNWvWTP/85z+d+lTcaW/FOb/tItHR0U6niKSlpclms2nDhg0aNGiQwsLCFBoaqh49eujgwYNO2+bl5Wn48OGKiIhQQECAWrdurW3btrm0WZxzT/maNm2aYmJiVKVKFbVs2VKbN292qrt161bdd999io6Olr+/v6Kjo3X//ffr559/dmn3l19+0SOPPKKoqCj5+voqMjJSPXv2dDlNsaCgQOPGjVNkZKSCg4PVvn17/fDDDxfssySlpKTIZrNp9uzZxf667evrq8TERKcyHx8fvfDCC9q2bZvefffdiz6H9MepPTfccIPGjBmjwsLCUm1TFmfPntXUqVNVv359+fn5qXr16nrooYd04MABp3oJCQmKjY3V559/rvj4eAUEBGjAgAGO9/HFF1/UlClTHO9RQkKC/vOf/6igoECjR49WZGSk7Ha7unfvrsOHD1fY/khSTk6ORowYoZiYGPn6+qpmzZpKTk7WqVOnnOq99tprat26tapXr67AwEA1atRIU6dOVUFBgdN+r1y5Uj///LPTaV1SyZ+9otckLS3NUVZ0qtaOHTvUsWNHBQUFqV27dpKk/Px8TZo0yfEeVKtWTf3799eRI0fK7TUpChVz585VVFSU5s6dK2OMU52yHNvl6eDBg1qzZo26deump556SmfPnnV6Dctq+fLlMsaof//+TuX9+/dXbm6uU6CrVKn8vkoVfWY2bdqk+Ph4x9+uuXPnSpJWrlypG2+8UQEBAWrUqJFLsJSkH3/8Ub1791b16tXl5+enBg0a6LXXXnOqc/r0aQ0fPlxNmzaV3W5XSEiIWrZsqRUrVri0Z7PZ9Nhjj2n+/Plq0KCBAgIC1KRJkyv2NFiA8AOUgwEDBshms+ntt992Kv/222/15Zdfqm/fvvLy8lJWVpb++te/6pNPPtGzzz6r1atXKykpSampqfrb3/7m0u7f//53rV+/Xi+99JJWr16tyMhIx3+CTz/9tDZt2qRNmzbp4YcfliRt2LBBt9xyi3777Te98cYbWrFihZo2bap77723XL4QXMzDDz8sHx8fLVq0SFOnTtVnn32mBx980KlO//79NWPGDPXv318rVqzQ3Xffre7du1/wmqnzvfbaa0pPT9eMGTO0cOFCnTp1Sp07d1Z2drajzt69e1WvXj3NmDFDn3zyiaZMmaLMzEw1b95cv/76q6PeL7/8oubNm2vZsmUaNmyYVq9erRkzZshut+v48eNOzzt27Fj9/PPPeuuttzR79mz9+OOP6tat2wWDRmFhodavX6+4uDhFRUWVeh8l6d5771VcXJyefvpppy/XJfHy8lJqaqp27dqlefPmufVc5ztz5ozTcu4+Dho0SKNGjVKHDh304Ycf6vnnn9eaNWsUHx/v9NpKUmZmph588EH17t1bq1atchodfe211/Q///M/eu211/TWW2/p+++/V7du3ZSUlKQjR47o7bff1tSpU7Vu3TrHMV6kKHC7c1yfv09nz56V9MdoSps2bTRv3jw9/vjjWr16tUaNGqW0tDQlJiY6feH/73//q969e2v+/Pn6+OOPlZSUpBdffFEDBw501Hn99dd1yy23KCIiwvEZLe5arNLIz89XYmKibrvtNq1YsULPPfeczp49qzvvvFOTJ09W7969tXLlSk2ePFnp6elKSEhQbm5uqdouGk0u7j0+cOCA1q5dqzvvvFPVqlVT3759tXv3bn3++edO25f12D7/vTj3/XBHWlqaCgsLNWDAALVv3161a9fW22+/7RLS3LVz505Vq1ZNERERTuWNGzd2rK8oWVlZ6t+/vx5++GGtWLFCjRo10oABAzRx4kSNGTNGI0eO1NKlS1WlShXdddddTj8wffvtt2revLl27typl19+WR9//LG6dOmixx9/XM8995yjXl5eno4dO6YRI0Zo+fLlWrx4sVq1aqUePXronXfecenTypUrNXPmTE2cOFFLly5VSEiIunfvrp9++qnCXgegwhgA5aJNmzYmLCzM5OfnO8qGDx9uJJn//Oc/xhhjBg4caKpUqWJ+/vlnp21feuklI8ns2rXLGGPMnj17jCRz3XXXObVnjDFbtmwxkszcuXNd+lC/fn3TrFkzU1BQ4FTetWtXU6NGDVNYWGiMMWbDhg1GktmwYYOjzvjx4835fxIkmfHjx7s8T+3atU3fvn0dj+fOnWskmcGDBzvVmzp1qpFkMjMzjTHG7Nq1y0gyo0aNcqq3ePFiI8mpzeIUvS6NGjUyZ86ccZR/+eWXRpJZvHhxidueOXPGnDx50gQGBppXXnnFUT5gwADj4+Njvv322xK3LXq9Onfu7FT+z3/+00gymzZtKnHbrKwsI8ncd999F9y3c7Vp08Y0bNjQGGPMunXrjCTz6quvGmP+/zV48cUXXfr33nvvGWOMadWqlalVq5bJzc01xhjTt29fExgYWKrn7tu3r5Hkstxyyy3GGGO+++67Yt/r//3f/zWSzNixY532Q5L59NNPneoW7UOTJk0cx6QxxsyYMcNIMomJiU71k5OTjSSTnZ3tKJs3b57x8vIy8+bNu+g+FfXj/OWBBx4wxhiTmppqKlWqZLZs2eK03fvvv28kmVWrVhXbbmFhoSkoKDDvvPOO8fLyMseOHXOs69Kli6ldu7bLNsV99s59Tc79XBe9F2+//bZT3aLPy9KlS53Ki/42vP766xd8PYo+6+cvNWvWdNSZOHGikWTWrFljjDHmp59+MjabzfTp08dRp6zHdnHPLckkJSWVuh1jjDl79qy5/vrrTc2aNR1/D4r27fxj7mKfgcDAQKe/Px06dDD16tUrtq6vr6955JFHil333nvvFfv+llbR67N161ZH2dGjR42Xl5fx9/c3v/zyi6N8+/btRpL5+9//7ii7/fbbTa1atZw+K8YY89hjj5nKlSs7HaPnOnPmjCkoKDBJSUmmWbNmTuskmfDwcJOTk+Moy8rKMpUqVTKpqall2k/Akxj5AcpJUlKSfv31V3344YeS/vhlc8GCBbr11ltVp04dSX9cmNu2bVtFRkY6/eJZdEpcRkaGU5uJiYny8fEp1fPv3r1b33//vR544AHH8xctnTt3VmZmZqlO0boU55/eUvQradGpZkX716tXL6d6PXv2lLd36S9B7NKli7y8vEp8Hkk6efKkRo0apeuvv17e3t7y9vZWlSpVdOrUKX333XeOeqtXr1bbtm3VoEGDS96/itCuXTt17NhREydO1IkTJ0q1zZQpU3TgwAG98sorxa4/e/Zsib/4S39ck7FLine truncated
"text/plain": [
"<Figure size 1000x400 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"X_train = train_scaled[au_columns].values[..., np.newaxis] \n",
"y_train = train_scaled[\"label\"].values \n",
"\n",
"X_val = val_scaled[au_columns].values[..., np.newaxis] \n",
"y_val = val_scaled[\"label\"].values \n",
"\n",
"X_test = test_scaled[au_columns].values[..., np.newaxis] \n",
"y_test = test_scaled[\"label\"].values\n",
"\n",
"#Shape-Kontrolle\n",
"print(\"X_train Shape:\", X_train.shape)\n",
"print(\"X_val Shape:\", X_val.shape)\n",
"print(\"X_test Shape:\", X_test.shape)\n",
"\n",
"#Label-Verteilung\n",
"print(\"Train Labels:\", np.bincount(y_train))\n",
"print(\"Val Labels:\", np.bincount(y_val))\n",
"print(\"Test Labels:\", np.bincount(y_test))\n",
"\n",
"#Histogramm nach Datenvorbereitung\n",
"col_idx = 0 #nur erste AU-Spalte\n",
"plt.figure(figsize=(10,4))\n",
"plt.hist(X_train[:, col_idx, 0], bins=30)\n",
"plt.title(f\"Verteilung nach CNN-Form: Feature {au_columns[col_idx]}\")\n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"id": "2dddde72",
"metadata": {},
"source": [
"CNN Architektur - mit Keras"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "4501c65a",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential_2\"</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1mModel: \"sequential_2\"\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ conv1d_6 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">18</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ batch_normalization_2 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">18</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span> │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalization</span>) │ │ │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ max_pooling1d_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling1D</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">9</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ conv1d_7 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">7</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">6,208</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ batch_normalization_3 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">7</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span> │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalization</span>) │ │ │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ global_average_pooling1d_3 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GlobalAveragePooling1D</span>) │ │ │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_4 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">4,160</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dropout_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_5 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">65</span> │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
"</pre>\n"
],
"text/plain": [
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ conv1d_6 (\u001b[38;5;33mConv1D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m18\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m128\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ batch_normalization_2 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m18\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m128\u001b[0m │\n",
"│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ │ │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ max_pooling1d_3 (\u001b[38;5;33mMaxPooling1D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m9\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ conv1d_7 (\u001b[38;5;33mConv1D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m7\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m6,208\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ batch_normalization_3 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m7\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m256\u001b[0m │\n",
"│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ │ │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ global_average_pooling1d_3 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
"│ (\u001b[38;5;33mGlobalAveragePooling1D\u001b[0m) │ │ │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_4 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m4,160\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dropout_2 (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_5 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m) │ \u001b[38;5;34m65\u001b[0m │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">10,945</span> (42.75 KB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m10,945\u001b[0m (42.75 KB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">10,753</span> (42.00 KB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m10,753\u001b[0m (42.00 KB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">192</span> (768.00 B)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m192\u001b[0m (768.00 B)\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"model = models.Sequential([\n",
" Input(shape=(len(au_columns),1)),\n",
" layers.Conv1D(32, kernel_size=3, activation=\"relu\"), \n",
" layers.BatchNormalization(), \n",
" layers.MaxPooling1D(pool_size=2), \n",
" \n",
" layers.Conv1D(64, kernel_size=3, activation=\"relu\"), \n",
" layers.BatchNormalization(), \n",
" layers.GlobalAveragePooling1D(), \n",
" \n",
" layers.Dense(64, activation=\"relu\", kernel_regularizer=regularizers.l2(0.001)), \n",
" layers.Dropout(0.6), # etwas stärkeres Dropout \n",
" layers.Dense(1, activation=\"sigmoid\")\n",
"])\n",
"\n",
"model.compile(\n",
" optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n",
" loss=\"binary_crossentropy\",\n",
" metrics=[\"accuracy\", tf.keras.metrics.AUC(name=\"auc\")]\n",
")\n",
"\n",
"model.summary()"
]
},
{
"cell_type": "markdown",
"id": "bc203cec",
"metadata": {},
"source": [
"Training - mit Callbacks"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "be371dbb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 4ms/step - accuracy: 0.9429 - auc: 0.9839 - loss: 0.1901 - val_accuracy: 0.9206 - val_auc: 0.9442 - val_loss: 0.3106 - learning_rate: 2.5000e-04\n",
"Epoch 2/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9420 - auc: 0.9863 - loss: 0.1799 - val_accuracy: 0.9271 - val_auc: 0.9437 - val_loss: 0.2897 - learning_rate: 2.5000e-04\n",
"Epoch 3/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9508 - auc: 0.9869 - loss: 0.1764 - val_accuracy: 0.9247 - val_auc: 0.9421 - val_loss: 0.3190 - learning_rate: 2.5000e-04\n",
"Epoch 4/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9443 - auc: 0.9855 - loss: 0.1819 - val_accuracy: 0.9255 - val_auc: 0.9454 - val_loss: 0.3098 - learning_rate: 2.5000e-04\n",
"Epoch 5/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9431 - auc: 0.9866 - loss: 0.1755 - val_accuracy: 0.9279 - val_auc: 0.9432 - val_loss: 0.3023 - learning_rate: 2.5000e-04\n",
"Epoch 6/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9476 - auc: 0.9865 - loss: 0.1704 - val_accuracy: 0.9247 - val_auc: 0.9445 - val_loss: 0.3061 - learning_rate: 2.5000e-04\n",
"Epoch 7/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9485 - auc: 0.9865 - loss: 0.1682 - val_accuracy: 0.9279 - val_auc: 0.9423 - val_loss: 0.3132 - learning_rate: 2.5000e-04\n",
"Epoch 8/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9484 - auc: 0.9884 - loss: 0.1624 - val_accuracy: 0.9287 - val_auc: 0.9423 - val_loss: 0.3191 - learning_rate: 1.2500e-04\n",
"Epoch 9/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9496 - auc: 0.9885 - loss: 0.1611 - val_accuracy: 0.9320 - val_auc: 0.9409 - val_loss: 0.3137 - learning_rate: 1.2500e-04\n",
"Epoch 10/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9436 - auc: 0.9880 - loss: 0.1662 - val_accuracy: 0.9279 - val_auc: 0.9424 - val_loss: 0.3159 - learning_rate: 1.2500e-04\n",
"Epoch 11/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9427 - auc: 0.9876 - loss: 0.1657 - val_accuracy: 0.9312 - val_auc: 0.9415 - val_loss: 0.3128 - learning_rate: 1.2500e-04\n",
"Epoch 12/100\n",
"\u001b[1m129/129\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9523 - auc: 0.9898 - loss: 0.1504 - val_accuracy: 0.9255 - val_auc: 0.9421 - val_loss: 0.3188 - learning_rate: 1.2500e-04\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAAIhCAYAAACsQmneAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAhUFJREFUeJzt3Xd4VGXexvHvZDLphUBIAUJHejMohGJPFJSisiIixQUVQRfE3QUEBVHBBqKrsKICrwXMoiioKEQB6aIIWECKlFASQk9InWTm/eOQgZAASUgyw+T+XNdcmTlz5pznzJNy55nfeY7JbrfbERERERFxUx7OboCIiIiISHlS4BURERERt6bAKyIiIiJuTYFXRERERNyaAq+IiIiIuDUFXhERERFxawq8IiIiIuLWFHhFRERExK0p8IqIiIiIW1PgFZFSMZlMxbqtXLnyivYzceJETCZTqV67cuXKMmmDq7n77rvx9fXl1KlTF12nX79+WCwWjhw5UuztmkwmJk6c6Hhckvdv0KBB1K1bt9j7Ot+MGTOYO3duoeX79u3DZDIV+Vx5y/++O3bsWIXvW0TKnqezGyAiV6f169cXePz888+zYsUKli9fXmB5s2bNrmg/Q4YM4Y477ijVa6+99lrWr19/xW1wNYMHD+aLL75g3rx5DBs2rNDzp0+f5vPPP+euu+4iPDy81PupqPdvxowZhIaGMmjQoALLIyMjWb9+PQ0aNCjX/YuI+1PgFZFS6dChQ4HH1atXx8PDo9DyC2VkZODn51fs/dSqVYtatWqVqo1BQUGXbc/VqGvXrtSoUYPZs2cXGXjnz59PZmYmgwcPvqL9OPv98/b2dsv+E5GKp5IGESk3N910Ey1atGDVqlV07NgRPz8//v73vwMQHx9PXFwckZGR+Pr60rRpU8aMGUN6enqBbRRV0lC3bl3uuusuvv32W6699lp8fX1p0qQJs2fPLrBeUR/JDxo0iICAAHbv3k23bt0ICAggKiqKp556iuzs7AKvP3jwIL179yYwMJAqVarQr18/fvrpp8t+zL5161ZMJhPvv/9+oee++eYbTCYTixcvBuDo0aM88sgjREVF4e3tTfXq1enUqRPffffdRbdvNpsZOHAgmzZt4rfffiv0/Jw5c4iMjKRr164cPXqUYcOG0axZMwICAggLC+OWW25h9erVF91+vouVNMydO5fGjRvj7e1N06ZN+eCDD4p8/XPPPUf79u2pWrUqQUFBXHvttbz//vvY7XbHOnXr1uWPP/7ghx9+cJTB5JdGXKykYc2aNdx6660EBgbi5+dHx44d+frrrwu10WQysWLFCh577DFCQ0OpVq0a99xzD4cPH77ssRfX4sWLiYmJwc/Pj8DAQGJjYwt9+lGcPt68eTN33XUXYWFheHt7U6NGDe68804OHjxYZm0Vqcw0wisi5SopKYkHH3yQf//730yePBkPD+P/7F27dtGtWzdGjhyJv78/f/75Jy+//DIbN24sVBZRlK1bt/LUU08xZswYwsPDee+99xg8eDANGzbkhhtuuORrrVYrPXr0YPDgwTz11FOsWrWK559/nuDgYJ599lkA0tPTufnmmzlx4gQvv/wyDRs25Ntvv6VPnz6XbVvr1q1p27Ytc+bMKTTKOnfuXMLCwujWrRsA/fv355dffuHFF1/kmmuu4dSpU/zyyy8cP378kvv4+9//zksvvcTs2bN5/fXXHcu3bdvGxo0bGTNmDGazmRMnTgAwYcIEIiIiOHPmDJ9//jk33XQT33//PTfddNNlj+fC9j/00EP07NmTqVOncvr0aSZOnEh2drajb/Pt27ePRx99lNq1awOwYcMGnnjiCQ4dOuR4nz///HN69+5NcHAwM2bMAIyR3Yv54YcfiI2NpVWrVrz//vt4e3szY8YMunfvzvz58wv1z5AhQ7jzzjuZN28eBw4c4F//+hcPPvhgsb7HLmfevHn069ePuLg45s+fT3Z2Nq+88orjve3cuTNw+T5OT08nNjaWevXq8fbbbxMeHk5ycjIrVqwgLS3titspIoBdRKQMDBw40O7v719g2Y033mgH7N9///0lX2uz2exWq9X+ww8/2AH71q1bHc9NmDDBfuGvqjp16th9fHzs+/fvdyzLzMy0V61a1f7oo486lq1YscIO2FesWFGgnYD9f//7X4FtduvWzd64cWPH47ffftsO2L/55psC6z366KN2wD5nzpxLHtObb75pB+w7duxwLDtx4oTd29vb/tRTTzmWBQQE2EeOHHnJbV3MjTfeaA8NDbXn5OQ4lj311FN2wL5z584iX5Obm2u3Wq32W2+91X733XcXeA6wT5gwwfH4wvcvLy/PXqNGDfu1115rt9lsjvX27dtnt1gs9jp16ly0rXl5eXar1WqfNGmSvVq1agVe37x5c/uNN95Y6DV79+4t9F536NDBHhYWZk9LSytwTC1atLDXqlXLsd05c+bYAfuwYcMKbPOVV16xA/akpKSLttVuP/d9d/To0YseT40aNewtW7a05+XlOZanpaXZw8LC7B07dnQsu1wf//zzz3bA/sUXX1yyTSJSeippEJFyFRISwi233FJo+Z49e3jggQeIiIjAbDZjsVi48cYbAdi+fftlt9umTRvHyCGAj48P11xzDfv377/sa00mE927dy+wrFWrVgVe+8MPPxAYGFjohLm+fftedvtgzJLg7e1d4OP4/FHAhx56yLHs+uuvZ+7cubzwwgts2LABq9VarO2DcfLasWPHHOURubm5fPTRR3Tp0oVGjRo51vvvf//Ltddei4+PD56enlgsFr7//vtivc/n27FjB4cPH+aBBx4oUGZSp04dOnbsWGj95cuXc9tttxEcHOzo42effZbjx4+TkpJSon2DMRL6448/0rt3bwICAhzLzWYz/fv35+DBg+zYsaPAa3r06FHgcatWrQCK9X1yKfnvRf/+/QuMbAcEBHDvvfeyYcMGMjIygMv3ccOGDQkJCWH06NH897//Zdu2bVfUNhEpTIFXRMpVZGRkoWVnzpyhS5cu/Pjjj7zwwgusXLmSn376iYULFwKQmZl52e1Wq1at0DJvb+9ivdbPzw8fH59Cr83KynI8Pn78eJEzHBR31oOqVavSo0cPPvjgA/Ly8gCjHOD666+nefPmjvXi4+MZOHAg7733HjExMVStWpUBAwaQnJx82X3klwLMmTMHgCVLlnDkyJECZRTTpk3jscceo3379nz22Wds2LCBn376iTvuuKNY79X58j+Cj4iIKPTchcs2btxIXFwcAO+++y5r167lp59+Yty4cUDx+vhCJ0+exG63F/k9VaNGjQJtzHfh90l+uURp9n++/P1crC02m42TJ08Cl+/j4OBgfvjhB9q0acPTTz9N8+bNqVGjBhMmTCjRP0AicnGq4RWRclXUHLrLly/n8OHDrFy50jGqC1xyXtmKVq1aNTZu3FhoeXGCaL6HHnqIBQsWkJCQQO3atfnpp5+YOXNmgXVCQ0OZPn0606dPJzExkcWLFzNmzBhSUlL49ttvL7l9X19f+vbty7vvvktSUhKzZ88mMDCQv/3tb451PvroI2666aZC+y1NbWh+eCzqPbhw2SeffILFYuGrr74q8M/FF198UeL95gsJCcHDw4OkpKRCz+WfiBYaGlrq7ZdE/ntxsbZ4eHgQEhLiaNPl+rhly5Z88skn2O12fv31V+bOncukSZPw9fVlzJgxFXJMIu5MI7wiUuHyQ/CFJye98847zmhOkW688UbS0tL45ptvCiz/5JNPir2NuLg4atasyZw5c5gzZw4+Pj6XLImoXbs2jz/+OLGxsfzyyy/F2sfgwYPJy8vj1VdfZcmSJdx///0Fpn0zmUyF3udff/210EwCxdG4cWMiIyOZP39+gZkW9u/fz7p16wqsazKZ8PT0xGw2O5ZlZmby4YcfFtpucUfm/f39ad++PQsXLiywvs1m46OPPqJWrVpcc801JT6u0mjcuDE1a9Zk3rx5Bd6L9PR0PvvsM8fMDRe6XB+bTCZat27N66+/TpUqVYr9fSAil6YRXhGpcB07diQkJIShQ4cyYcIELBYLH3/8MVu3bnV20xwGDhzI66+/zoMPPsgLL7xAw4YN+eabb1i6dClAoRkJimI2mxkwYADTpk0jKCiIe+65h+DgYMfzp0+f5uabb+aBBx6gSZMmBAYG8tNPP/Htt99yzz33FKud7dq1o1WrVkyfPh273V5oVoi77rqL559/ngkTJnDjjTeyY8cOJk2aRL169cjNzS3BO2Ic8/PPP8+QIUO4++67efjhhzl16hQTJ04sVNJw5513Mm3aNB544AEeeeQRjh8/zmuvvVbkDAz5o5vx8fHUr18fHx8fWrZsWWQbpkyZQmxsLDfffDP//Oc/8fLyYsaMGfz+++/Mnz+/1Fflu5gvv/ySwMDAQst79+7NK6+8Qr9+/bjrrrt49NFHyc7O5tVXX+XUqVO89NJLQPH6+KuvvmLGjBn06tWL+vXrY7fbWbhwIadOnSI2NrZMj0ekslLgFZEKV61aNb7++mueeuopHnzwQfz9/enZsyfx8fFce+21zm4eYIwmLl++nJEjR/Lvf/8bk8lEXFwcM2bMoFu3blSpUqVY23nooYeYMmUKR48eLXCyGhgn2rVv354PP/yQffv2YbVaqV27NqNHj+bf//53sds6ePBgRowYQbNmzWjfvn2B58aNG0dGRgbvv/8+r7zyCs2aNeO///0vn3/+eakuuZwfqF9++WXuuece6taty9NPP80PP/xQYHu33HILs2fP5uWXX6Z79+7UrFmThx9+mLCwsEKh/LnnniMpKYmHH36YtLQ06tSpw759+4rc/4033sjy5cuZMGECgwYNwmaz0bp1axYvXsxdd91V4uO5nPx5oy9kt9t54IEH8Pf3Z8qUKfTp0wez2UyHDh1YsWKF4yS+4vRxo0aNqFKlCq+88gqHDx/Gy8uLxo0bM3fLine truncated
"text/plain": [
"<Figure size 800x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAsUAAAIhCAYAAACmHseMAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAmSxJREFUeJzs3XlYVHX/xvH3sC+yKCjihrvinkuo5Z6apqVWbmnuabb5mM9TVlaaZdlPs0VNLfdcsrLNLbfKcs3cLbdUXFAEFRQUBji/P46OIaiAwAxwv66Lq5kzZ875zBzIe77zXSyGYRiIiIiIiBRgTvYuQERERETE3hSKRURERKTAUygWERERkQJPoVhERERECjyFYhEREREp8BSKRURERKTAUygWERERkQJPoVhERERECjyFYhEREREp8BSKRcTGYrFk6Ofnn3++q/O8+eabWCyWLD33559/zpYaHE3nzp3x9PTk4sWLt9zniSeewNXVlbNnz2b4uBaLhTfffNN2PzPvX9++fSlbtmyGz/VvU6ZMYfbs2Wm2Hzt2DIvFku5juWn48OFYLBY6dOhg1zpExHG42LsAEXEcmzZtSnX/rbfeYv369axbty7V9mrVqt3VeQYOHMiDDz6YpefWrVuXTZs23XUNjmbAgAF8++23LFiwgKFDh6Z5PCYmhqVLl9KhQweCgoKyfJ7cev+mTJlCYGAgffv2TbU9ODiYTZs2UaFChRw9/+1YrVbmz58PwMqVKzl16hQlS5a0Wz0i4hgUikXEpmHDhqnuFy1aFCcnpzTbbxYfH4+Xl1eGz1OqVClKlSqVpRp9fX3vWE9e1K5dO0qUKMHMmTPTDcULFy7kypUrDBgw4K7OY+/3z93d3e7X77vvvuPcuXM89NBDLFu2jDlz5vDKK6/YtaZbyezflohknbpPiEimNG/enBo1avDrr7/SuHFjvLy86N+/PwCLFy+mTZs2BAcH4+npSWhoKC+//DJxcXGpjpFe94myZcvSoUMHVq5cSd26dfH09KRq1arMnDkz1X7pff3ft29fChUqxOHDh2nfvj2FChWidOnSvPjiiyQkJKR6/smTJ3nsscfw8fHB39+fJ554gm3btt3xK/1du3ZhsVj4/PPP0zy2YsUKLBYL33//PQDnzp3jqaeeonTp0ri7u1O0aFHuu+8+1qxZc8vjOzs706dPH7Zv386ePXvSPD5r1iyCg4Np164d586dY+jQoVSrVo1ChQpRrFgxWrZsyYYNG255/Otu1X1i9uzZVKlSBXd3d0JDQ5k7d266zx89ejRhYWEUKVIEX19f6taty+eff45hGLZ9ypYty759+/jll19sXW6ud8O4VfeJ3377jVatWuHj44OXlxeNGzdm2bJlaWq0WCysX7+ep59+msDAQAICAujSpQunT5++42u/7vPPP8fNzY1Zs2ZRunRpZs2alar+6/7++2969OhBUFAQ7u7ulClThieffDLV79SpU6ds19rNzY0SJUrw2GOP2bq4XK/52LFjqY6d3nXIjr8tgC1bttCxY0cCAgLw8PCgQoUKDBs2DIANGzZgsVhYuHBhmufNnTsXi8XCtm3bMvxeiuQnCsUikmkRERH06tWLnj17snz5clvL5qFDh2jfvj2ff/45K1euZNiwYXz55Zd07NgxQ8fdtWsXL774Iv/5z3/47rvvqFWrFgMGDODXX3+943OtVisPP/wwrVq14rvvvqN///588MEHvPfee7Z94uLiaNGiBevXr+e9997jyy+/JCgoiG7dut3x+LVr1+aee+5h1qxZaR6bPXs2xYoVo3379gD07t2bb7/9ltdff52ffvqJzz77jAceeIDo6OjbnqN///5YLJY0HwT279/P1q1b6dOnD87Ozpw/fx6AN954g2XLljFr1izKly9P8+bNs9TXevbs2fTr14/Q0FC+/vprXnvtNd5666003WbADLWDBw/myy+/5JtvvqFLly4899xzvPXWW7Z9li5dSvny5bnnnnvYtGkTmzZtYunSpbc8/y+//ELLli2JiYnh888/Z+HChfj4+NCxY0cWL16cZv+BAwfi6urKggULGD9+PD///DO9evXK0Gs9efIkP/30E4888ghFixalT58+HD58OM3v2K5du2jQoAGbN29mzJgxrFixgnHjxpGQkEBiYiJgBuIGDRqwdOlShg8fzooVK5g0aRJ+fn5cuHAhQ/Xc7G7/tlatWkWTJk0IDw9n4sSJrFixgtdee80W0ps0acI999zD5MmT05z7k08+oUGDBjRo0CBLtYvkeYaIyC306dPH8Pb2TrWtWbNmBmCsXbv2ts9NSUkxrFar8csvvxiAsWvXLttjb7zxhnHz/35CQkIMDw8P4/jx47ZtV65cMYoUKWIMHjzYtm39+vUGYKxf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 truncated
"text/plain": [
"<Figure size 800x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAAIhCAYAAACsQmneAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAbdJJREFUeJzt3Xl0FFXCxuG30+nsCSSELEBYRQiyL7KpgAoIguI2uICgqCA6I4POCCoquDDqgHwzCgKyKKig4zojIlFEUcQgEhRBULawJISEJUBI0umu749KGpoESCCkm+L3nFMnXdW13Oob5c3tW/faDMMwBAAAAFhUgK8LAAAAAJxLBF4AAABYGoEXAAAAlkbgBQAAgKUReAEAAGBpBF4AAABYGoEXAAAAlkbgBQAAgKUReAEAAGBpBF4AZ8Vms5VrWbZs2Vld5+mnn5bNZjujY5ctW1YpZfA3N9xwg0JDQ3XgwIGT7nPHHXfI4XBoz5495T6vzWbT008/7VmvyOc3dOhQ1a9fv9zXOt7UqVM1d+7cUtu3bdsmm81W5ntVafTo0bLZbOrXr59PywGg4gJ9XQAA57fvv//ea/2ZZ57RV199paVLl3ptb9as2Vld55577tE111xzRse2bdtW33///VmXwd8MGzZMH330kd5++22NHDmy1PsHDx7Uhx9+qH79+ik+Pv6Mr1NVn9/UqVMVGxuroUOHem1PTEzU999/r0aNGp3T65+K0+nU/PnzJUmLFy/Wrl27VLt2bZ+VB0DFEHgBnJVOnTp5rdesWVMBAQGltp8oLy9PYWFh5b5OnTp1VKdOnTMqY1RU1GnLcz7q06ePatWqpdmzZ5cZeN955x0dPXpUw4YNO6vr+PrzCw4O9nn9ffzxx9q7d6+uvfZaffrpp3rjjTf02GOP+bRMAMqPLg0Azrnu3burefPm+uabb9SlSxeFhYXp7rvvliQtXLhQvXr1UmJiokJDQ5WcnKwxY8boyJEjXucoq0tD/fr11a9fPy1evFht27ZVaGiomjZtqtmzZ3vtV9ZX8kOHDlVERIT++OMP9e3bVxEREUpKStLDDz+sgoICr+N37typm2++WZGRkapevbruuOMOrVq16rRfs69du1Y2m02zZs0q9d5nn30mm82mTz75RJK0d+9e3XfffUpKSlJwcLBq1qyprl276osvvjjp+e12u4YMGaLVq1frl19+KfX+nDlzlJiYqD59+mjv3r0aOXKkmjVrpoiICMXFxenKK6/U8uXLT3r+Eifr0jB37lw1adJEwcHBSk5O1ptvvlnm8ePHj1fHjh0VExOjqKgotW3bVrNmzZJhGJ596tevr19//VVff/21pxtMSdeIk3Vp+Pbbb3XVVVcpMjJSYWFh6tKliz799NNSZbTZbPrqq690//33KzY2VjVq1NCNN96o3bt3n/beS8yaNUtBQUGaM2eOkpKSNGfOHK/yH3+tbdu2levzW7x4sa666ipVq1ZNYWFhSk5O1sSJE8tdJgDlR+AFUCUyMjI0aNAg3X777Vq0aJGnRfL3339X3759NWvWLC1evFijRo3Su+++q/79+5frvGvXrtXDDz+sv/71r/r444/VsmVLDRs2TN98881pj3U6nbruuut01VVX6eOPP9bdd9+tl19+WS+88IJnnyNHjqhHjx766quv9MILL+jdd99VfHy8Bg4ceNrzt2rVSm3atNGcOXNKvTd37lzFxcWpb9++kqTBgwfro48+0pNPPqklS5bo9ddf19VXX62cnJxTXuPuu++WzWYrFfLXr1+v1NRUDRkyRHa7Xfv27ZMkPfXUU/r00081Z84cNWzYUN27dz+jvs1z587VXXfdpeTkZL3//vt64okn9Mwzz5TqyiKZgXX48OF699139cEHH+jGG2/Un//8Zz3zzDOefT788EM1bNhQbdq00ffff6/vv/9eH3744Umv//XXX+vKK6/UwYMHNWvWLL3zzjuKjIxU//79tXDhwlL733PPPXI4HHr77bf14osvatmyZRo0aFC57nXnzp1asmSJrr/+etWsWVNDhgzRH3/8Ua7fsZOZNWuW+vbtK7fbrddee03//e9/9Ze//EU7d+4843MCOAUDACrRkCFDjPDwcK9t3bp1MyQZX3755SmPdbvdhtPpNL7++mtDkrF27VrPe0899ZRx4v+y6tWrZ4SEhBjbt2/3bDt69KgRExNjDB8+3LPtq6++MiQZX331lVc5JRnvvvuu1zn79u1rNGnSxLP+6quvGpKMzz77zGu/4cOHG5KMOXPmnPKe/vWvfxmSjI0bN3q27du3zwgODjYefvhhz7aIiAhj1KhRpzzXyXTr1s2IjY01CgsLPdsefvhhQ5KxadOmMo8pKioynE6ncdVVVxk33HCD13uSjKeeesqzfuLn53K5jFq1ahlt27Y13G63Z79t27YZDofDqFev3knL6nK5DKfTaUyYMMGoUaOG1/GXXHKJ0a1bt1LHbN26tdRn3alTJyMuLs44dOiQ1z01b97cqFOnjue8c+bMMSQZI0eO9Drniy++aEgyMjIyTlrWEhMmTDAkGYsXLzYMwzC2bNli2Gw2Y/DgwV77lVxr69atXttP/PwOHTpkREVFGZdddpnX/QM4d2jhBVAloqOjdeWVV5bavmXLFt1+++1KSEiQ3W6Xw+FQt27dJEkbNmw47Xlbt26tunXretZDQkJ08cUXa/v27ac91mazlWpJbtmypdexX3/9tSIjI0s9MHfbbbed9vySOUpCcHCw19fx77zzjgoKCnTXXXd5tl166aWaO3eunn32Wa1cuVJOp7Nc55fMh9eys7M93SOKioo0f/58XX755WrcuLFnv9dee01t27ZVSEiIAgMD5XA49OWXX5brcz7exo0btXv3bt1+++1e3Uzq1aunLl26lNp/6dKluvrqq1WtWjVPHT/55JPKyclRVlZWha4tma3uP/zwg26++WZFRER4ttvtdg0ePFg7d+7Uxo0bvY657rrrvNZbtmwpSaf9PTEMw9ONoWfPnpKkBg0aqHv37nr//feVm5tb4fKvWLFCubm5Gjly5BmPPAKgYgi8AKpEYmJiqW2HDx/W5Zdfrh9++EHPPvusli1bplWrVumDDz6QJB09evS0561Ro0apbcHBweU6NiwsTCEhIaWOzc/P96zn5OSUOcJBeUc9iImJ0XXXXac333xTLpdLktkd4NJLL9Ull1zi2W/hwoUaMmSIXn/9dXXu3FkxMTG68847lZmZedpr3HzzzapWrZqn68SiRYu0Z88er4fVJk+erPvvv18dO3bU+++/r5UrV2rVqlW65ppryvVZHa+km0VCQkKp907clpqaql69ekmSZs6cqe+++06rVq3S448/Lql8dXyi/fv3yzCMMn+natWq5VXGEif+ngQHB5fr+kuXLtXWrVt1yy23KDc3VwcOHNCBAwf0pz/9SXl5eXrnnXcqXP69e/dK0hk/hAmg4hilAUCVKKsla+nSpdq9e7eWLVvmadWVdMpxZatajRo1lJqaWmp7eYJoibvuukvvvfeeUlJSVLduXa1atUrTpk3z2ic2NlZTpkzRlClTlJ6erk8++URjxoxRVlaWFi9efMrzh4aG6rbbbtPMmTOVkZGh2bNnKzIyUrfccotnn/nz56t79+6lrnvo0KFy30eJkvBY1mdw4rYFCxbI4XDof//7n9cfFx999FGFr1siOjpaAQEBysjIKPVeyYNosbGxZ3z+45U8cDh58mRNnjy5zPeHDx8uSZ77O/Ghx+zsbK/1mjVrShL9dYEqRAsvAJ8pCcElrW0lpk+f7ovilKlbt246dOiQPvvsM6/tCxYsKPc5evXqpdq1a2vOnDmaM2eOQkJCTtklom7dunrwwQfVs2dP/fTTT+W6xrBhw+RyufTSSy9p0aJFuvXWW72GfbPZbKU+559//rnUOMrl0aRJEyUmJuqdd97xGqlg+/btWrFihde+NptNgYGBstvtnm1Hjx7VvHnzSp23vC3z4eHh6tixoz744AOv/d1ut+bPn686dero4osvrvB9nWj//v368MMP1bVrV3311VellpLROtatWydJnlElfv75Z6/zlHQ1KdGlSxdVq1ZNr732WqmRHgCcG7TwAvCZLl26KDo6WiNGjNBTTz0lh8Oht956S2vXrvV10TyGDBmil19+WYMGDdKzzz6riy66SJ999pk+//xzSVJAwOnbDex2u+68805NnjxZUVFRuvHGG1WtWjXP+wcPHlSPHj10++23q2nTpoqMjNSqVau0ePFi3XjjjeUqZ/v27dWyZUtNmTJFhmGUGnu3X79+euaZZ/TUU0+pW7du2rhxoyZMmKAGDRqoqKioAp+Iec/PPPOM7rnnHt1www269957deDAAT399NOlujRce+21mjx5sm6//Xbdd999ysnJ0T//+c9S4VuSWrRooQULFmjhwoVq2LChQkJC1KJFizLLMHHiRPXs2VM9evTQI488oqCgIE2dOlXr1q3TO++8Uyl9Y9966y3l5+frL3/5i7p3717q/Ro1auitt97SrFmz9PLLL6tDhw5q0qSJHnnkERUVFSk6Oloffvihvv32W6/jIiIiNGnSJN1zzz26+uqrde+99yo+Pl5//PGH1q5dq1deeeWsyw7AGy28AHymRo0a+vTTTxUWFqZBgwbp7rvvVkRERJnDSvlKeHi4li5dqu7du+vvf/+7brrpJqWnp2vq1KmSpOrVq5frPHfddZcKCgq0d+9er4fVJPOr8I4dO2revHm644471KdPH73++ut69NFHNXPmzHKXddiwYTIMQ82aNVPHjh293nv88cf18MMPa9asWbr22mv1+uuv67XXXtNll11W7vOfeK3XX39d69ev14033qgJEyboscceK/Vg4pVXXqnZs2frl19+Uf/+/fX444/r5ptv1pgxY0qdc/z48erWrZvuvfdeXXrppaccmq5bt25aunSpwsPDNXToUN16660Line truncated
"text/plain": [
"<Figure size 800x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"callbacks = [ \n",
" tf.keras.callbacks.EarlyStopping( monitor=\"val_loss\", patience=10, restore_best_weights=True ), \n",
" tf.keras.callbacks.ReduceLROnPlateau( monitor=\"val_loss\", factor=0.5, patience=5, min_lr=1e-6 ), \n",
" tf.keras.callbacks.ModelCheckpoint( \"cnn_best_model.keras\", save_best_only=True, monitor=\"val_loss\" ) \n",
"]\n",
"\n",
"history = model.fit(\n",
" X_train, y_train, \n",
" validation_data=(X_val, y_val), \n",
" epochs=100, \n",
" batch_size=32, \n",
" callbacks=callbacks \n",
")\n",
"\n",
"# Trainingsverlauf plotten\n",
"def plot_history(history, metric): \n",
" plt.figure(figsize=(8,6)) \n",
" plt.plot(history.history[metric], label=f\"Train {metric}\") \n",
" plt.plot(history.history[f\"val_{metric}\"], label=f\"Val {metric}\") \n",
" plt.xlabel(\"Epochs\") \n",
" plt.ylabel(metric.capitalize()) \n",
" plt.title(f\"Training vs Validation {metric.capitalize()}\")\n",
" plt.legend()\n",
" plt.grid(True)\n",
" plt.show()\n",
"\n",
"# Funktionsaufrufe NACH der Definition\n",
"plot_history(history, \"loss\")\n",
"plot_history(history, \"accuracy\")\n",
"plot_history(history, \"auc\")"
]
},
{
"cell_type": "markdown",
"id": "ff5c5462",
"metadata": {},
"source": [
"Evaluation"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "fd803602",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m91/91\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 4ms/step\n",
"Test Accuracy: 0.9448491155046826\n",
"Test F1: 0.9538193435957014\n",
"Test AUC: 0.937195821764372\n",
"Confusion Matrix:\n",
" [[1082 137]\n",
" [ 22 1642]]\n",
" precision recall f1-score support\n",
"\n",
" 0 0.98 0.89 0.93 1219\n",
" 1 0.92 0.99 0.95 1664\n",
"\n",
" accuracy 0.94 2883\n",
" macro avg 0.95 0.94 0.94 2883\n",
"weighted avg 0.95 0.94 0.94 2883\n",
"\n"
]
}
],
"source": [
"y_test_pred_proba = model.predict(X_test).ravel() \n",
"y_test_pred = (y_test_pred_proba > 0.5).astype(int) \n",
"\n",
"print(\"Test Accuracy:\", accuracy_score(y_test, y_test_pred)) \n",
"print(\"Test F1:\", f1_score(y_test, y_test_pred)) \n",
"print(\"Test AUC:\", roc_auc_score(y_test, y_test_pred)) \n",
"print(\"Confusion Matrix:\\n\", confusion_matrix(y_test, y_test_pred)) \n",
"print(classification_report(y_test, y_test_pred)) "
]
},
{
"cell_type": "markdown",
"id": "4edb792b",
"metadata": {},
"source": [
"Model speichern "
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "1a805bf6",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['scaler_cnn_v2.joblib']"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.save(\"cnn_model_full_v2.keras\") \n",
"\n",
"# Scaler speichern \n",
"joblib.dump(scaler, \"scaler_cnn_v2.joblib\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,308 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d48f2e13",
"metadata": {},
"source": [
"Importe"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e34b838d",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np \n",
"import pandas as pd \n",
"import joblib \n",
"import seaborn as sns \n",
"import matplotlib.pyplot as plt \n",
"\n",
"from sklearn.metrics import ( \n",
" confusion_matrix, \n",
" roc_curve, auc, \n",
" precision_recall_curve, \n",
" f1_score, \n",
" balanced_accuracy_score \n",
")\n",
" \n",
"import tensorflow as tf"
]
},
{
"cell_type": "markdown",
"id": "324554b5",
"metadata": {},
"source": [
"Modell und Scaler laden"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4acc3d2f",
"metadata": {},
"outputs": [],
"source": [
"model = tf.keras.models.load_model(\"hybrid_fusion_model_V2.keras\") \n",
"scaler_au = joblib.load(\"scaler_au_V2.joblib\") \n",
"scaler_eye = joblib.load(\"scaler_eye_V2.joblib\")\n",
"\n",
"print(\"Modell & Scaler erfolgreich geladen.\")"
]
},
{
"cell_type": "markdown",
"id": "4271cbee",
"metadata": {},
"source": [
"Features laden"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8342ea10",
"metadata": {},
"outputs": [],
"source": [
"au_columns = [...] \n",
"eye_columns = [...]"
]
},
{
"cell_type": "markdown",
"id": "4a58b20c",
"metadata": {},
"source": [
"Preprocessing"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b683be47",
"metadata": {},
"outputs": [],
"source": [
"def preprocess_sample(df, au_columns, eye_columns, scaler_au, scaler_eye):\n",
" # AUs\n",
" X_au = df[au_columns].values\n",
" X_au = scaler_au.transform(X_au).reshape(len(df), len(au_columns), 1)\n",
"\n",
" # Eye\n",
" X_eye = df[eye_columns].values\n",
" X_eye = scaler_eye.transform(X_eye)\n",
"\n",
" return X_au, X_eye"
]
},
{
"cell_type": "markdown",
"id": "9dc99a3d",
"metadata": {},
"source": [
"Predict-Funktion"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "00295aa6",
"metadata": {},
"outputs": [],
"source": [
"def predict_workload(df, model, au_columns, eye_columns, scaler_au, scaler_eye):\n",
" X_au, X_eye = preprocess_sample(df, au_columns, eye_columns, scaler_au, scaler_eye)\n",
"\n",
" probs = model.predict([X_au, X_eye]).flatten()\n",
" preds = (probs > 0.5).astype(int)\n",
" \n",
" return preds, probs"
]
},
{
"cell_type": "markdown",
"id": "5753516b",
"metadata": {},
"source": [
"Testdaten laden"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8875b0ee",
"metadata": {},
"outputs": [],
"source": [
"test_data = pd.read_csv(\"test_data.csv\") # oder direkt aus Notebook 1 exportieren \n",
"\n",
"X_au_test = test_data[au_columns].values[..., np.newaxis] \n",
"X_eye_test = test_data[eye_columns].values \n",
"y_test = test_data[\"label\"].values \n",
"groups_test = test_data[\"subjectID\"].values \n",
"\n",
"X_au_test_scaled = scaler_au.transform(X_au_test.reshape(len(X_au_test), -1)).reshape(X_au_test.shape) \n",
"X_eye_test_scaled = scaler_eye.transform(X_eye_test)"
]
},
{
"cell_type": "markdown",
"id": "332a3a07",
"metadata": {},
"source": [
"Vorhersagen"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b5f58ece",
"metadata": {},
"outputs": [],
"source": [
"y_prob = model.predict([X_au_test_scaled, X_eye_test_scaled]).flatten() \n",
"y_pred = (y_prob > 0.5).astype(int)"
]
},
{
"cell_type": "markdown",
"id": "3bc5c66c",
"metadata": {},
"source": [
"Konfusionsmatrix"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "40648dd7",
"metadata": {},
"outputs": [],
"source": [
"cm = confusion_matrix(y_test, y_pred) \n",
"plt.figure(figsize=(6,5)) \n",
"sns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\", \n",
" xticklabels=[\"Pred 0\", \"Pred 1\"], \n",
" yticklabels=[\"True 0\", \"True 1\"]) \n",
"plt.title(\"Konfusionsmatrix - Testdaten\") \n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "e79ad8a6",
"metadata": {},
"source": [
"ROC"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dd93f15c",
"metadata": {},
"outputs": [],
"source": [
"fpr, tpr, _ = roc_curve(y_test, y_prob) \n",
"roc_auc = auc(fpr, tpr) \n",
"\n",
"plt.figure(figsize=(7,6)) \n",
"plt.plot(fpr, tpr, label=f\"AUC = {roc_auc:.3f}\") \n",
"plt.plot([0,1], [0,1], \"k--\") \n",
"plt.xlabel(\"False Positive Rate\") \n",
"plt.ylabel(\"True Positive Rate\") \n",
"plt.title(\"ROC‑Kurve – Testdaten\") \n",
"plt.legend() \n",
"plt.grid(True) \n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "2eaaf2a0",
"metadata": {},
"source": [
"Precision-Recall"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "601e5dc9",
"metadata": {},
"outputs": [],
"source": [
"precision, recall, _ = precision_recall_curve(y_test, y_prob) \n",
"plt.figure(figsize=(7,6)) \n",
"plt.plot(recall, precision) \n",
"plt.xlabel(\"Recall\") \n",
"plt.ylabel(\"Precision\") \n",
"plt.title(\"Precision‑Recall‑Kurve – Testdaten\")\n",
"plt.grid(True) \n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "270af771",
"metadata": {},
"source": [
"Scores"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e2e7da5b",
"metadata": {},
"outputs": [],
"source": [
"print(\"F1‑Score:\", f1_score(y_test, y_pred)) \n",
"print(\"Balanced Accuracy:\", balanced_accuracy_score(y_test, y_pred))"
]
},
{
"cell_type": "markdown",
"id": "c6e22e1a",
"metadata": {},
"source": [
"Subject-Performance"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "731aaf73",
"metadata": {},
"outputs": [],
"source": [
"df_eval = pd.DataFrame({ \n",
" \"subject\": groups_test, \n",
" \"y_true\": y_test, \n",
" \"y_pred\": y_pred \n",
"}) \n",
"\n",
"subject_perf = df_eval.groupby(\"subject\").apply( \n",
" lambda x: balanced_accuracy_score(x[\"y_true\"], x[\"y_pred\"]) \n",
") \n",
"\n",
"print(\"\\n=== Balanced Accuracy pro Proband ===\") \n",
"print(subject_perf.sort_values())"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}