{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6cf3da8a",
   "metadata": {},
   "source": [
    "# Modul 4: Teori"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a43b5f1",
   "metadata": {},
   "source": [
    "## Pyodide-bemærkning (Python direkte i Browseren)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fdf208a4",
   "metadata": {},
   "source": [
    "Koden i denne Notebook er beregnet til at blive kørt lokalt på din egen computer og ikke direkte i browseren via Pyodide. Årsagen er, at vi bruger `scikit-learn` til at downloade hele MNIST-datasættet. Dette er en data-tung operation, som involverer download af en stor fil, hvilket ikke umiddelbart understøttes eller er praktisk i et browser-baseret miljø som Pyodide."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd249e1e",
   "metadata": {},
   "source": [
    "## Digitale billeder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "0c3d4815",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from sklearn.datasets import fetch_openml\n",
    "# Hent MNIST (784 = 28x28 pixels)\n",
    "mnist = fetch_openml('mnist_784', version=1, as_frame=False)\n",
    "X, y = mnist.data, mnist.target.astype('int64')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "cacd749c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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fePiiy8u9KEAgCIw6wHobQr+GefNmzfHxRdfHDt27IhjjjkmzjzzzFi1alUcc8wxhT4UAFAEZj0AvU3Bg/NDDz1U6KcEAEqIWQ9Ab9Ptn3EGAACAclbwK85wMMOHD89d279//9y1f/zHf5y79swzz8xde9RRR+WunT59eu7a3mbz5s25a2+//fbctZ/4xCdy1+7atSt37X/+53/mrm1sbMxdC0DhnXbaablrv//97+eurampyV2bZVnu2q7Mv7feeit37dFHH5279vTTT89d++yzz+au7crfl8JyxRkAAAASBGcAAABIEJwBAAAgQXAGAACABMEZAAAAEgRnAAAASBCcAQAAIEFwBgAAgATBGQAAABIEZwAAAEgQnAEAACBBcAYAAIAEwRkAAAASBGcAAABIqMiyLCt2E7+rubk5ampqit0GB3Hqqafmrl2+fHnuWudGz9ba2pq79s///M9z1+7evTt3bVds3bo1d+2vf/3r3LVr167NXdsbNTU1RXV1dbHb6HHMe0rR4Ycfnrv2gx/8YO7a++67L3ftsGHDctdWVFTkru1KhHj22Wdz1y5YsCB37UMPPZS7titrdeONN+aunT9/fu5aOudg894VZwAAAEgQnAEAACBBcAYAAIAEwRkAAAASBGcAAABIEJwBAAAgQXAGAACABMEZAAAAEgRnAAAASBCcAQAAIEFwBgAAgATBGQAAABIEZwAAAEgQnAEAACChX7EboDxt3Lgxd+2OHTty19bU1OSu7W2efvrp3LU7d+7MXXv22Wfnrn3rrbdy19577725awEgIuLb3/527tqLL764gJ30bB/84Adz1x555JG5axsbG3PXTpgwIXftqFGjctdSOlxxBgAAgATBGQAAABIEZwAAAEgQnAEAACBBcAYAAIAEwRkAAAASBGcAAABIEJwBAAAgQXAGAACABMEZAAAAEgRnAAAASBCcAQAAIEFwBgAAgATBGQAAABL6FbsBytP//M//5K69/vrrc9d+9KMfzV37H//xH7lrb7/99ty1XbFmzZrctX/yJ3+Su3bPnj25az/wgQ/krv3sZz+buxYAIiLGjBmTu/ZP//RPc9dWVFTkru2KxsbG3LU//OEPc9d+7Wtfy127ZcuW3LVd+f9zv/71r3PXnnPOOblri3VuUFiuOAMAAECC4AwAAAAJgjMAAAAkCM4AAACQIDgDAABAguAMAAAACYIzAAAAJAjOAAAAkCA4AwAAQILgDAAAAAmCMwAAACQIzgAAAJAgOAMAAECC4AwAAAAJFVmWZcVu4nc1NzdHTU1NsdugRFVXV+eu3bVrV+7ab3/727lrr7jiity1n/rUp3LXPvjgg7lrgd9qamrq0r897J95T8qpp56au3b58uW5a4v13/rjjz+eu/biiy/OXXvWWWflrh01alTu2n/4h3/IXfurX/0qd21XvPPOO7lrX3/99dy1Xfnf6Nlnn81d2xsdbN674gwAAAAJgjMAAAAkdDo4P/XUU3H++edHfX19VFRUxCOPPNLu8SzL4uabb46hQ4fGwIEDY9KkSfHiiy8Wql8AoJuZ9QDQXqeD8549e2L06NGxaNGi/T6+YMGCuP322+Puu++Op59+Oo444oiYMmVKvPnmm11uFgDofmY9ALTXr7MFU6dOjalTp+73sSzLYuHChXHjjTfGxz/+8YiI+M53vhNDhgyJRx55JC666KKudQsAdDuzHgDaK+hnnDds2BDbtm2LSZMmtd1XU1MT48aNi5UrVxbyUABAEZj1APRGnb7inLJt27aIiBgyZEi7+4cMGdL22O9raWmJlpaWttvNzc2FbAkAKKA8sz7CvAegvBX9W7Xnz58fNTU1bduxxx5b7JYAgAIz7wEoZwUNznV1dRERsX379nb3b9++ve2x3zd37txoampq2zZt2lTIlgCAAsoz6yPMewDKW0GDc0NDQ9TV1cWyZcva7mtubo6nn346zjjjjP3WVFZWRnV1dbsNAChNeWZ9hHkPQHnr9Gecd+/eHevWrWu7vWHDhlizZk3U1tbG8OHDY/bs2XHbbbfFiSeeGA0NDXHTTTdFfX19TJs2rZB9AwDdxKwHgPY6HZyfeeaZOPvss9tuz5kzJyIiZsyYEYsXL44bbrgh9uzZE1dddVXs3LkzzjzzzHjiiSdiwIABhesaAOg2Zj0AtNfp4DxhwoTIsuyAj1dUVMSXvvSl+NKXvtSlxgCA4jDrAaC9on+rNgAAAJSygv6OM3S3Yv3uZ1NTU1GOe+WVV+auffjhh3PXtra25q4FgIiI97///blrr7/++ty1NTU1uWtfe+213LVbt27NXfvP//zPuWt3796du/Zf/uVfilLb2wwcODB37V/91V/lrr3kkkty17IvV5wBAAAgQXAGAACABMEZAAAAEgRnAAAASBCcAQAAIEFwBgAAgATBGQAAABIEZwAAAEgQnAEAACBBcAYAAIAEwRkAAAASBGcAAABIEJwBAAAgQXAGAACAhH7FbgDKwa233pq7dsyYMblrzzrrrNy1kyZNyl37k5/8JHctAD1HZWVl7tqvfe1ruWvPO++83LW7du3KXfvpT386d+0zzzyTu3bgwIG5a+nZhg8fXuwW+P+54gwAAAAJgjMAAAAkCM4AAACQIDgDAABAguAMAAAACYIzAAAAJAjOAAAAkCA4AwAAQILgDAAAAAmCMwAAACQIzgAAAJAgOAMAAECC4AwAAAAJgjMAAAAk9Ct2A1AO9uzZk7v2yiuvzF377LPP5q79v//3/+auffLJJ3PXPvPMM7lrFy1alLs2y7LctQDs3x/90R/lrj3vvPMK2EnHffzjH89d29jYWMBOgJ7EFWcAAABIEJwBAAAgQXAGAACABMEZAAAAEgRnAAAASBCcAQAAIEFwBgAAgATBGQAAABIEZwAAAEgQnAEAACBBcAYAAIAEwRkAAAASBGcAAABIEJwBAAAgoV+xG4Cebv369blrL7vssty199xzT+7aSy+9tCi1RxxxRO7a73znO7lrt27dmrsWoCf7xje+kbu2oqIid21jY2NRauFA+vTJf72xtbW1gJ1QLK44AwAAQILgDAAAAAmCMwAAACQIzgAAAJAgOAMAAECC4AwAAAAJgjMAAAAkCM4AAACQIDgDAABAguAMAAAACYIzAAAAJAjOAAAAkCA4AwAAQILgDAAAAAn9it0AcGBLlizJXfviiy/mrv3GN76Ru3bixIm5a//2b/82d+2IESNy1/7N3/xN7tpXXnkldy3AofDRj340d+2pp56auzbLsty1jz32WO5a6A6tra25a7vy38KaNWty11JYrjgDAABAguAMAAAACZ0Ozk899VScf/75UV9fHxUVFfHII4+0e/yyyy6LioqKdtu5555bqH4BgG5m1gNAe50Oznv27InRo0fHokWLDrjPueeeG1u3bm3bHnzwwS41CQAcOmY9ALTX6S8Hmzp1akydOjW5T2VlZdTV1eVuCgAoHrMeANrrls84r1ixIgYPHhwjR46Mz3zmM7Fjx47uOAwAUCRmPQC9ScF/jurcc8+NCy64IBoaGmL9+vXxhS98IaZOnRorV66Mvn377rN/S0tLtLS0tN1ubm4u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1gPAvjoVnLMsO+g+AwYMiEWLFsWiRYtyNwUAFIdZDwD76tLvOAMAAEBPl/t3nCGvIUOG5K79wz/8w9y13/rWt3LXnnTSSblry9HTTz+du/arX/1q7tpHH300d21ra2vuWgAKr2/fvrlrr7nmmty106dPz13bld8XP/HEE3PXFstPf/rT3LVPPvlk7tqbb745dy0UiyvOAAAAkCA4AwAAQILgDAAAAAmCMwAAACQIzgAAAJAgOAMAAECC4AwAAAAJgjMAAAAkCM4AAACQIDgDAABAguAMAAAACYIzAAAAJAjOAAAAkCA4AwAAQEK/YjdA8dTW1uau/fa3v5279tRTT81de/zxx+euLUc//elPc9d+/etfz1374x//OHftG2+8kbsWgMJbuXJl7tp///d/z107duzY3LVdUVdXl7t2yJAhBeyk43bs2JG79qGHHspd+9nPfjZ3LfQ2rjgDAABAguAMAAAACYIzAAAAJAjOAAAAkCA4AwAAQILgDAAAAAmCMwAAACQIzgAAAJAgOAMAAECC4AwAAAAJgjMAAAAkCM4AAACQIDgDAABAguAMAAAACf2K3QAR48aNy117/fXX56497bTTcte+973vzV1bjl5//fXctbfffnvu2r/927/NXbtnz57ctQD0HJs3b85de8EFF+Su/Yu/+IvctTfeeGPu2mL5+7//+9y1d911V+7adevW5a4FOs4VZwAAAEgQnAEAACBBcAYAAIAEwRkAAAASBGcAAABIEJwBAAAgQXAGAACABMEZAAAAEgRnAAAASBCcAQAAIEFwBgAAgATBGQAAABIEZwAAAEgQnAEAACChIsuyrNhN/K7m5uaoqakpdhuH1Fe+8pXctddff30BOzk0fv7zn+eu/dGPfpS79u23385d+/Wvfz137c6dO3PXAsXX1NQU1dXVxW6jx+mN8x6A0nWwee+KMwAAACQIzgAAAJAgOAMAAECC4AwAAAAJgjMAAAAkCM4AAACQIDgDAABAguAMAAAACYIzAAAAJAjOAAAAkCA4AwAAQILgDAAAAAmCMwAAACQIzgAAAJBQkWVZVuwmfldzc3PU1NQUuw0AiIiIpqamqK6uLnYbPY55D0ApOdi8d8UZAAAAEgRnAAAASOhUcJ4/f36MHTs2qqqqYvDgwTFt2rRYu3Ztu30mTJgQFRUV7barr766oE0DAN3DrAeA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vn0L0vOB3HbbbVFVVRVnn312PPLII916LAAoFz1h1m/YsCGOO+64eO211+KYY47plmNAufFWbSiyc845J2666aZ4+eWX47777mu7f3+fe3rjjTfiL//yL2PQoEFRVVUVH/vYx+KVV17Z521Uv/+5p+OOOy7+67/+KxobG9veQjZhwoS2/devXx/r16/vcM8vvvhifPOb34xvfOMbuQc+APQW5TbrjzvuuLx/VeixBGcoAZdeemlERPzkJz9J7nfZZZfFHXfcEeedd1783d/9XQwcODD+9E//9KDPv3Dhwhg2bFicdNJJce+998a9994bX/ziF9senzhxYkycOLHD/c6ePTvOPvvsOO+88zpcAwC9WbnNeqA9l4qgBAwbNixqamqSrwQ/++yz8d3vfjdmz54d3/zmNyMi4pprronLL788/vM//zP5/NOmTYsbb7wxBg0aFJ/61Ke61Ou//Mu/xE9+8pODHhMA+K1ymvXAvlxxhhJx5JFHJr9x84knnoiI3wzQ33Xttdd2+dgvvfRSh37O4q233orrrrsurr766vjDP/zDLh8XAHqTcpj1wP4JzlAidu/eHVVVVQd8/OWXX44+ffpEQ0NDu/tPOOGE7m6tzTe/+c147bXXYt68eYfsmADQU5TDrAf2z1u1oQRs3rw5mpqaSnowNjU1xW233RbXXHNNNDc3R3Nzc0T85v8EZFkWL730Uhx++OExePDgIncKAKWnHGY9cGCuOEMJuPfeeyMiYsqUKQfcZ8SIEdHa2hobNmxod/+6des6dIzf/9bOzvr1r38du3fvjgULFkRDQ0Pb9v3vfz9ef/31aGhoiKuuuqpLxwCAnqocZj1wYIIzFNny5cvjy1/+cjQ0NMQll1xywP3eHbR33nlnu/vvuOOODh3niCOOiJ07d+73sY78RMXgwYNjyZIl+2xnn312DBgwIJYsWRJz587tUC8A0JuUy6wHDsxbteEQevzxx+OFF16It99+O7Zv3x7Lly+PpUuXxogRI+Kxxx6LAQMGHLB2zJgxMX369Fi4cGHs2LEjTj/99GhsbIz//u//joiDv8o8ZsyYuOuuu+K2226LE044IQYPHhznnHNORETbz1OkvjTk8MMPj2nTpu1z/yOPPBI/+9nP9vsYAPQ25Tzr33XvvffGyy+/HK+//npERDz11FNx2223RcRvflZrxIgRB30O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Xmcue6l5X4rnQ6myVh1nrTrOWnWcteq4Ul2rjs77foewpw7p06dPDBs27KD7VVdXl9SClzJr1XHWquOsVcdZq44rtbWqqakpdgs9VkfmfamdD6XMWnWcteo4a9Vx1qrjSnGtOjLvvYQOAAAACYIzAAAAJJRdcK6srIxbbrklKisri91KybNWHWetOs5adZy16jhrxe9yPnScteo4a9Vx1qrjrFXHlftaldyXgwEAAEApKbsrzgAAAHAoCc4AAACQIDgDAABAguAMAAAACWUVnBctWhTHHXdcDBgwIMaNGxc/+9nPit1SSbr11lujoqKi3XbSSScVu62S8NRTT8X5558f9fX1UVFREY888ki7x7Msi5tvvjmGDh0aAwcOjEmTJsWLL75YnGaL7GBrddlll+1znp177rnFabaI5s+fH2PHjo2qqqoYPHhwTJs2LdauXdtunzfffDNmzpwZRx99dBx55JExffr02L59e5E6Lp6OrNWECRP2Oa+uvvrqInVMsZj3B2fWH5hZ33FmfceY9R3Xk2d92QTnhx9+OObMmRO33HJLPPvsszF69OiYMmVKvPrqq8VurSR94AMfiK1bt7Zt//Zv/1bslkrCnj17YvTo0bFo0aL9Pr5gwYK4/fbb4+67746nn346jjjiiJgyZUq8+eabh7jT4jvYWkVEnHvuue3OswcffPAQdlgaGhsbY+bMmbFq1apYunRp7N27NyZPnhx79uxp2+e6666LH/7wh/G9730vGhsbY8uWLXHBBRcUsevi6MhaRURceeWV7c6rBQsWFKljisG87zizfv/M+o4z6zvGrO+4Hj3rszJx2mmnZTNnzmy7/c4772T19fXZ/Pnzi9hVabrllluy0aNHF7uNkhcR2ZIlS9put7a2ZnV1ddlXv/rVtvt27tyZVVZWZg8++GAROiwdv79WWZZlM2bMyD7+8Y8XpZ9S9uqrr2YRkTU2NmZZ9ptz6LDDDsu+973vte3zi1/8IouIbOXKlcVqsyT8/lplWZadddZZ2Wc/+9niNUXRmfcdY9Z3jFnfcWZ9x5n1HdeTZn1ZXHF+6623YvXq1TFp0qS2+/r06ROTJk2KlStXFrGz0vXiiy9GfX19HH/88XHJJZfExo0bi91SyduwYUNs27at3XlWU1MT48aNc54dwIoVK2Lw4MExcuTI+MxnPhM7duwodktF19TUFBERtbW1ERGxevXq2Lt3b7vz6qSTTorhw4f3+vPq99fqXffff38MGjQoTj755Jg7d268/vrrxWiPIjDvO8es7zyzvvPM+n2Z9R3Xk2Z9v2I30BGvvfZavPPOOzFkyJB29w8ZMiReeOGFInVVusaNGxeLFy+OkSNHxtatW2PevHnxkY98JJ5//vmoqqoqdnsla9u2bRER+z3P3n2M3zr33HPjggsuiIaGhli/fn184QtfiKlTp8bKlSujb9++xW6vKFpbW2P27Nnx4Q9/OE4++eSI+M151b9//zjqqKPa7dvbz6v9rVVExCc/+ckYMWJE1NfXx3PPPRef//znY+3atfGDH/ygiN1yqJj3HWfW52PWd45Zvy+zvuN62qwvi+BM50ydOrXtz6NGjYpx48bFiBEj4rvf/W5cccUVReyMnuSiiy5q+/Mpp5wSo0aNive9732xYsWKmDhxYhE7K56ZM2fG888/73OGHXCgtbrqqqva/nzKKafE0KFDY+LEibF+/fp43/ved6jbhJJl1nMomPX7Mus7rqfN+rJ4q/agQYOib9+++3wz3fbt26Ourq5IXZWPo446Kt7//vfHunXrit1KSXv3XHKe5XP88cfHoEGDeu15NmvWrPjRj34UTz75ZAwbNqzt/rq6unjrrbdi586d7fbvzefVgdZqf8aNGxcR0WvPq97GvM/PrO8Ys75rzHqzvqN64qwvi+Dcv3//GDNmTCxbtqztvtbW1li2bFmcccYZReysPOzevTvWr18fQ4cOLXYrJa2hoSHq6uranWfNzc3x9NNPO886YPPmzbFjx45ed55lWRazZs2KJUuWxPLly6OhoaHd42PGjInDDjus3Xm1du3a2LhxY687rw62VvuzZs2aiIhed171VuZ9fmZ9x5j1XWPWm/UH05Nnfdm8VXvOnDkxY8aM+NCHPhSnnXZaLFy4MPbs2ROXX355sVsrOZ/73Ofi/PPPjxEjRsSWLVvilltuib59+8bFF19c7NaKbvfu3e1ezdqwYUOsWbMmamtrY/jw4TF79uy47bbb4sQTT4yGhoa46aabor6+PqZNm1a8posktVa1tbUxb968mD59etTV1cX69evjhhtuiBNOOCGmTJlSxK4PvZkzZ8YDDzwQjz76aFRVVbV9lqmmpiYGDhwYNTU1ccUVV8ScOXOitrY2qqur49prr40zzjgjTj/99CJ3f2gdbK3Wr18fDzzwQJx33nlx9NFHx3PPPRfXXXddjB8/PkaNGlXk7jlUzPuOMesPzKzvOLO+Y8z6juvRs764X+rdOXfccUc2fPjwrH///tlpp52WrVq1qtgtlaQLL7wwGzp0aNa/f//sve99b3bhhRdm69atK3ZbJeHJJ5/MImKfbcaMGVmW/eZnKm666aZsyJAhWWVlZTZx4sRs7dq1xW26SFJr9frrr2eTJ0/OjjnmmOywww7LRowYkV155ZXZtm3bit32Ibe/NYqI7J577mnb54033siuueaa7D3veU92+OGHZ5/4xCeyrVu3Fq/pIjnYWm3cuDEbP358Vltbm1VWVmYnnHBCdv3112dNTU3FbZxDzrw/OLP+wMz6jjPrO8as77iePOsrsizLuieSAwAAQPkri884AwAAQLEIzgAAAJAgOAMAAECC4AwAAAAJgjMAAAAkCM4AAACQIDgDAABAguAMAAAACYIzAAAAJAjOAAAAkCA4AwAAQILgDAAAAAn/H2DL5itN7cLuAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1200x1200 with 4 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(12, 12))\n",
    "plt.subplot(221)\n",
    "plt.imshow(X[0].reshape(28, 28), cmap='gray')\n",
    "plt.title(f\"Digit: {y[0]}\")\n",
    "plt.subplot(222)\n",
    "plt.imshow(X[1].reshape(28, 28), cmap='gray')\n",
    "plt.title(f\"Digit: {y[1]}\")\n",
    "plt.subplot(223)\n",
    "plt.imshow(X[2].reshape(28, 28), cmap='gray')\n",
    "plt.title(f\"Digit: {y[2]}\")\n",
    "plt.subplot(224)\n",
    "plt.imshow(X[3].reshape(28, 28), cmap='gray')\n",
    "plt.title(f\"Digit: {y[3]}\")\n",
    "# vis grafen\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af74256c",
   "metadata": {},
   "source": [
    "## Vektorfunktioner"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1232974e",
   "metadata": {},
   "source": [
    "Lad $d,k \\in \\mathbb{N}$. En vektorfunktion af flere variable er en funktion af formen\n",
    "\n",
    "\\begin{equation*}\n",
    "        \\pmb{f} \\colon \\operatorname{dom}(\\pmb{f}) \\to \\mathbb{R}^k, \\text{\\; hvor }\\operatorname{dom}(\\pmb{f}) \\subseteq \\mathbb{R}^d.\n",
    "\\end{equation*}\n",
    "\n",
    "Altså har en vektorfunktion $\\pmb{f} = \\pmb{x} \\mapsto \\pmb{f}(\\pmb{x})$:\n",
    "* Input (domænet): vektorer $\\pmb{x}$ i $\\mathbb{R}^d$\n",
    "* Output (kodomænet): vektorer $\\pmb{f}(\\pmb{x})$ i $\\mathbb{R}^k$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6cdfc9f",
   "metadata": {},
   "source": [
    "### Input $\\pmb{x}_0$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a16d61da",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 700x700 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Vis det tredje billede fra træningssættet\n",
    "x0 = X[2].reshape(28, 28)\n",
    "plt.figure(figsize=(7, 7))\n",
    "plt.imshow(x0, cmap='gray')\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6162841e",
   "metadata": {},
   "source": [
    "### Output $\\pmb{f}(\\pmb{x}_0)$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b379ec1",
   "metadata": {},
   "source": [
    "* Output:  \n",
    "\n",
    "<p style=\"text-align: center;\">\"Dette er cifret 4\"</p>\n",
    "\n",
    "---\n",
    "\n",
    "\n",
    "* Ideelt output:\n",
    "\n",
    "\\begin{equation*}\n",
    "         \\pmb{f}(\\pmb{x}_0) = \\begin{bmatrix} 0 \\\\ 0 \\\\ 0 \\\\ 0 \\\\ 1 \\\\ 0 \\\\ 0 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix} \n",
    "\\end{equation*}\n",
    "\n",
    "<p style=\"text-align: center;\">Dette betyder: \"100% sikker på, at dette er cifret 4\"</p>\n",
    "\n",
    "---\n",
    "\n",
    "* Mere realistisk output:\n",
    "\n",
    "\\begin{equation*}\n",
    "         \\pmb{f}(\\pmb{x}_0) = \\begin{bmatrix} 0.01 \\\\ 0.03 \\\\ 0.01 \\\\ 0.01 \\\\ 0.87 \\\\ 0.01 \\\\ 0.01 \\\\ 0.03 \\\\ 0.01 \\\\ 0.01 \\end{bmatrix} \n",
    "\\end{equation*}\n",
    "\n",
    "<p style=\"text-align: center;\">Dette betyder: \"87% sikker på, at dette er cifret 4. Lille sandsynlighed (3%) for, at det er 1 eller 7.\"</p>\n",
    "\n",
    "---\n",
    "\n",
    "* Under alle omstændigheder: **Outputtet er en vektor af sandsynligheder i $\\mathbb{R}^{10}$. Derfor er $\\operatorname{co\\text{-}dom}(\\pmb{f})=\\mathbb{R}^{10}$**."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0d60287",
   "metadata": {},
   "source": [
    "### Hvad med inputtet?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7af8838b",
   "metadata": {},
   "source": [
    "Det er faktisk en matrix på størrelse 28x28:\n",
    "\n",
    "$$\n",
    "%\\tiny\n",
    "\\scriptsize\n",
    "\\begin{bmatrix}\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 67 & 232 & 39 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 62 & 81 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 120 & 180 & 39 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 126 & 163 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2 & 153 & 210 & 40 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 220 & 163 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 27 & 254 & 162 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 222 & 163 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 183 & 254 & 125 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 46 & 245 & 163 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 198 & 254 & 56 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 120 & 254 & 163 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 23 & 231 & 254 & 29 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 159 & 254 & 120 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 163 & 254 & 216 & 16 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 159 & 254 & 67 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 14 & 86 & 178 & 248 & 254 & 91 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 159 & 254 & 85 & 0 & 0 & 0 & 47 & 49 & 116 & 144 & 150 & 241 & 243 & 234 & 179 & 241 & 252 & 40 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 150 & 253 & 237 & 207 & 207 & 207 & 253 & 254 & 250 & 240 & 198 & 143 & 91 & 28 & 5 & 233 & 250 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 119 & 177 & 177 & 177 & 177 & 177 & 98 & 56 & 0 & 0 & 0 & 0 & 0 & 102 & 254 & 220 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 169 & 254 & 137 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 169 & 254 & 57 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 169 & 254 & 57 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 169 & 255 & 94 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 169 & 254 & 96 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 169 & 254 & 153 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 169 & 255 & 153 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 96 & 254 & 153 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
    "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\n",
    "\\end{bmatrix}\n",
    "$$\n",
    "\n",
    "Men det er ikke umiddelbart en (søjle)vektor!\n",
    "\n",
    "Vi kan gøre den om til en vektor ved at stakke billedets rækker oven på hinanden. Dette kaldes *flattening* (udfladning) af billedet i Python."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "573cd0ac",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Søjle-repræsentation af billedet (784 tal):\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [ 67],\n",
       "       [232],\n",
       "       [ 39],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [ 62],\n",
       "       [ 81],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [120],\n",
       "       [180],\n",
       "       [ 39],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [126],\n",
       "       [163],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  2],\n",
       "       [153],\n",
       "       [210],\n",
       "       [ 40],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [220],\n",
       "       [163],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [ 27],\n",
       "       [254],\n",
       "       [162],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [222],\n",
       "       [163],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [183],\n",
       "       [254],\n",
       "       [125],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [ 46],\n",
       "       [245],\n",
       "       [163],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [198],\n",
       "       [254],\n",
       "       [ 56],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [120],\n",
       "       [254],\n",
       "       [163],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [ 23],\n",
       "       [231],\n",
       "       [254],\n",
       "       [ 29],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [159],\n",
       "       [254],\n",
       "       [120],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [163],\n",
       "       [254],\n",
       "       [216],\n",
       "       [ 16],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [159],\n",
       "       [254],\n",
       "       [ 67],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [ 14],\n",
       "       [ 86],\n",
       "       [178],\n",
       "       [248],\n",
       "       [254],\n",
       "       [ 91],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [159],\n",
       "       [254],\n",
       "       [ 85],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [ 47],\n",
       "       [ 49],\n",
       "       [116],\n",
       "       [144],\n",
       "       [150],\n",
       "       [241],\n",
       "       [243],\n",
       "       [234],\n",
       "       [179],\n",
       "       [241],\n",
       "       [252],\n",
       "       [ 40],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [150],\n",
       "       [253],\n",
       "       [237],\n",
       "       [207],\n",
       "       [207],\n",
       "       [207],\n",
       "       [253],\n",
       "       [254],\n",
       "       [250],\n",
       "       [240],\n",
       "       [198],\n",
       "       [143],\n",
       "       [ 91],\n",
       "       [ 28],\n",
       "       [  5],\n",
       "       [233],\n",
       "       [250],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [119],\n",
       "       [177],\n",
       "       [177],\n",
       "       [177],\n",
       "       [177],\n",
       "       [177],\n",
       "       [ 98],\n",
       "       [ 56],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [102],\n",
       "       [254],\n",
       "       [220],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [169],\n",
       "       [254],\n",
       "       [137],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [169],\n",
       "       [254],\n",
       "       [ 57],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [169],\n",
       "       [254],\n",
       "       [ 57],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [169],\n",
       "       [255],\n",
       "       [ 94],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [169],\n",
       "       [254],\n",
       "       [ 96],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [169],\n",
       "       [254],\n",
       "       [153],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [169],\n",
       "       [255],\n",
       "       [153],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [ 96],\n",
       "       [254],\n",
       "       [153],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0],\n",
       "       [  0]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Udskriv som søjle med 784 tal\n",
    "print(\"\\nSøjle-repræsentation af billedet (784 tal):\")\n",
    "x0.reshape(784,1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bae1772e",
   "metadata": {},
   "source": [
    "Så vi kan tænke på inputtet som vektorer i $\\mathbb{R}^{784}$! Det vil sige"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "334a4498",
   "metadata": {},
   "source": [
    "### En AI funktion"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4196afcf",
   "metadata": {},
   "source": [
    "**AI'en er en vektorfunktion med $d=784$, $k=10$.**\n",
    "\n",
    "I maskinlæring kaldes funktionen for en model, og den specifikke AI-funktion afhænger typisk af tusindvis eller millioner af parametre (kaldet vægte). For hvert sæt af parametre/vægte får vi en ny AI-funktion. Sådanne funktioner (også dybe neurale netværk) er ikke særligt komplicerede, men ofte lange at skrive eksplicit. De er bygget af\n",
    "\n",
    "* Sammensætning af simple vektorfunktioner $\\pmb{g} \\circ \\pmb{h}$\n",
    "* De simple funktioner er normalt kun:\n",
    "        1. Affine vektorfunktioner $\\pmb{x} \\mapsto A \\pmb{x} + \\pmb{b}$ (elementerne i matrixen $A$ og vektoren $\\pmb{b}$ er parametrene/vægtene)\n",
    "        2. En ikke-lineær aktiveringsfunktion, fx ReLU.\n",
    "\n",
    "Antallet af sammensætninger $\\pmb{g}_1 \\circ \\pmb{g}_2 \\circ \\pmb{g}_3 \\circ \\cdots \\circ \\pmb{g}_N$ beskriver netværkets **dybde**."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff1aa3a8",
   "metadata": {},
   "source": [
    "## Neurale netværk"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dd40506f",
   "metadata": {},
   "source": [
    "Hvordan ser disse \"AI-funktioner\" ud?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a88e3b4f",
   "metadata": {},
   "source": [
    "### Generel notation for et feedforward ReLU-netværk"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8787b403",
   "metadata": {},
   "source": [
    "Et feedforward-netværk beregner outputtet ved sekventielt at føre input gennem en række lag. For hvert lag $\\ell$ beregnes først en **pre-aktivering** (også kaldet **logits**), $z^{(\\ell)}$, efterfulgt af en **aktivering** (eller **hidden state**), $h^{(\\ell)}$.\n",
    "\n",
    "\\begin{equation*}\n",
    "\\begin{aligned}\n",
    "&h^{(0)} = x \\in \\mathbb{R}^{n_0} &&\\text{(Input)}\\\\\n",
    "&z^{(\\ell)} = W_\\ell h^{(\\ell-1)} + b_\\ell, && \\ell = 1,2,\\dots,L &&\\text{(Logits)}\\\\\n",
    "&h^{(\\ell)} =\n",
    "\\begin{cases}\n",
    "\\sigma (z^{(\\ell)}), & \\ell < L, \\\\\n",
    "z^{(\\ell)}, & \\ell = L,\n",
    "\\end{cases}\n",
    "&&\\text{(Activation)}\n",
    "\\end{aligned}\n",
    "\\end{equation*}\n",
    "\n",
    "hvor\n",
    "\n",
    "* $h^{(0)}$ er input-vektoren $x$.\n",
    "* $W_\\ell \\in \\mathbb{R}^{n_\\ell \\times n_{\\ell-1}}$ er vægtmatricen for lag $\\ell$.\n",
    "* $b_\\ell \\in \\mathbb{R}^{n_\\ell}$ er bias-vektoren.\n",
    "* $\\sigma:\\mathbb{R}\\to\\mathbb{R}$ er en ikke-lineær aktiveringsfunktion (anvendt koordinatvis) typisk **ReLU**:\n",
    "\n",
    "\\begin{equation*}\n",
    "    \\sigma(z) = \\max(0,z)\n",
    "    \\quad\\text{(ReLU)}\n",
    "\\end{equation*}\n",
    "\n",
    "* $n_0=d$ er inputdimensionen, $n_L=k$ outputdimensionen. \n",
    "\n",
    "Vi siger kort at netværket er af **formen** $n_0 \\to n_1 \\to \\cdots \\to n_L$. \n",
    "\n",
    "Netværkets samlede funktion $\\Phi: \\mathbb{R}^d \\to \\mathbb{R}^k$ giver det endelige output:\n",
    "\n",
    "\\begin{equation*}\n",
    "\\Phi(x) = z^{(L)} = W_L h^{(L-1)} + b_L,\n",
    "\\end{equation*}\n",
    "\n",
    "idet sidste lag her er lineært (uden ReLU-aktivering).\n",
    "\n",
    "![Et neuralt netværk](images/DNN_example_crop.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cda12e61",
   "metadata": {},
   "source": [
    "### Shallow netværk (ét skjult lag med L=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6990a90",
   "metadata": {},
   "source": [
    "For et **shallow** netværk $\\Phi:\\mathbb{R}^2\\to\\mathbb{R}$ med ét skjult lag af størrelse $n$:\n",
    "\n",
    "\\begin{equation*}\n",
    "\\Phi(x) = W_2  \\, \\sigma(W_1 x + b_1) + b_2,\n",
    "\\end{equation*}\n",
    "\n",
    "hvor\n",
    "\n",
    "* $x \\in \\mathbb{R}^2$,\n",
    "* $W_1 \\in \\mathbb{R}^{n\\times 2},\\ b_1 \\in \\mathbb{R}^{n},$\n",
    "* $W_2 \\in \\mathbb{R}^{1\\times n},\\ b_2 \\in \\mathbb{R}.$\n",
    "\n",
    "\n",
    "**Illustration af lagene**:\n",
    "\n",
    "\\begin{equation*}\n",
    "h^{(0)} \\xrightarrow{W_1,b_1} z^{(1)} \\xrightarrow{\\sigma} h^{(1)}\n",
    "\\xrightarrow{W_2,b_2} z^{(2)} \\xrightarrow{\\sigma} h^{(2)} \\xrightarrow{W_3,b_3} z^{(3)} = \\Phi(x)\n",
    "\\end{equation*}\n",
    "\n",
    "Hvert ReLU-lag opdeler rummet i *lineære regioner* bestemt af ligningerne $ (W_\\ell h^{(\\ell-1)} + b_\\ell)_i = 0 $, så $\\Phi$ er en **stykkevist lineær funktion** på $\\mathbb{R}^d$."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4662f8d2",
   "metadata": {},
   "source": [
    "### Generel formel for et ReLU-netværk med $L=3$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0605b183",
   "metadata": {},
   "source": [
    "Vi betragter en funktion\n",
    "\n",
    "\\begin{equation*}\n",
    "\\Phi:\\mathbb{R}^{n_0}\\to\\mathbb{R}^{n_3}\n",
    "\\end{equation*}\n",
    "defineret som et **fuldt forbundet netværk** med to skjulte lag:\n",
    "\n",
    "\\begin{equation*}\n",
    "\\begin{aligned}\n",
    "h^{(0)} &= x \\in \\mathbb{R}^{n_0}, \\\\[2pt]\n",
    "z^{(1)} &= W_1 h^{(0)} + b_1,\\\\\n",
    "h^{(1)} &= \\sigma \\bigl(z^{(1)}\\bigr), \\\\[4pt]\n",
    "z^{(2)} &= W_2 h^{(1)} + b_2,\\\\\n",
    "h^{(2)} &= \\sigma \\bigl(z^{(2)}\\bigr), \\\\[4pt]\n",
    "z^{(3)} &= W_3 h^{(2)} + b_3,\\\\\n",
    "h^{(3)} &= z^{(3)}.\n",
    "\\end{aligned}\n",
    "\\end{equation*}\n",
    "\n",
    "hvor $n_0 = d$, $n_3 = k$, og\n",
    "\n",
    "* $W_1 \\in \\mathbb{R}^{n_1\\times n_0},\\ b_1\\in\\mathbb{R}^{n_1}$\n",
    "* $W_2 \\in \\mathbb{R}^{n_2\\times n_1},\\ b_2\\in\\mathbb{R}^{n_2}$\n",
    "* $W_3 \\in \\mathbb{R}^{n_3\\times n_2},\\ b_3\\in\\mathbb{R}^{n_3}$\n",
    "\n",
    "Det samlede funktionsudtryk bliver:\n",
    "\n",
    "\\begin{equation*}\n",
    "\\Phi(x)\n",
    "= W_3 \\, \\sigma \\bigl(W_2 \\, \\sigma(W_1 x + b_1) + b_2 \\bigr) + b_3.\n",
    "\\end{equation*}\n",
    "\n",
    "\n",
    "**Eksempel**: For et konkret netværk med to inputvariabler og ét output af formen $2 \\to n_1 \\to n_2 \\to 1$:\n",
    "\n",
    "\\begin{equation*}\n",
    "\\Phi(x_1,x_2)\n",
    "= W_3  \\,\\sigma \\Big(W_2 \\, \\sigma \\big(W_1\n",
    "\\begin{bmatrix}x_1 \\\\ x_2\\end{bmatrix} + b_1\\big) + b_2\\Big) + b_3,\n",
    "\\end{equation*}\n",
    "\n",
    "hvor dimensionerne er\n",
    "\n",
    "\\begin{equation*}\n",
    "W_1 \\in \\mathbb{R}^{n_1\\times2},\\quad\n",
    "W_2 \\in \\mathbb{R}^{n_2\\times n_1},\\quad\n",
    "W_3 \\in \\mathbb{R}^{1\\times n_2}.\n",
    "\\end{equation*}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b8e8f05",
   "metadata": {},
   "source": [
    "### Netværk og træning direkte i SKLearn"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2323cd17",
   "metadata": {},
   "source": [
    "Vi skal finde en \"AI-funktion\" \n",
    "\n",
    "\\begin{equation*}\n",
    "\\Phi : \\mathbb{R}^{784} \\to \\mathbb{R}^{10}\n",
    "\\end{equation*}\n",
    "\n",
    "der \"bedst\"-muligt kan klassificere et billede af et håndskrevet ciffer.\n",
    "\n",
    "I koden nedenfor opbygges denne som et ReLU-netværk med to skjulte lag, hvilket giver en samlet dybde på $L=3$. Formen af netværket er $784 \\to 256 \\to 128 \\to 10$. Altså er vægt-matricerne af størrelse\n",
    "\n",
    "\\begin{equation*}\n",
    "\\begin{aligned}\n",
    "&W_1 \\in \\mathbb{R}^{256 \\times 784}, \\quad b_1 \\in \\mathbb{R}^{256}, \\\\\n",
    "&W_2 \\in \\mathbb{R}^{128 \\times 256}, \\quad b_2 \\in \\mathbb{R}^{128}, \\\\\n",
    "&W_3 \\in \\mathbb{R}^{10 \\times 128}, \\quad b_3 \\in \\mathbb{R}^{10}.\n",
    "\\end{aligned}\n",
    "\\end{equation*}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "18483aa7",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.neural_network import MLPClassifier\n",
    "\n",
    "# Normaliser til [0,1]\n",
    "X = X / 255.0\n",
    "\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X, y, test_size=1/7, random_state=42\n",
    ")\n",
    "\n",
    "# DNN med samme “størrelse” som PyTorch-eksemplet\n",
    "clf = MLPClassifier(\n",
    "    hidden_layer_sizes=(256, 128),  # to skjulte lag\n",
    "    activation='relu',\n",
    "    solver='adam',\n",
    "    batch_size=64,\n",
    "    learning_rate_init=1e-3,\n",
    "    max_iter=6,\n",
    "    verbose=True\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e962ffda",
   "metadata": {},
   "source": [
    "#### Netværkets størrelse"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "579a1f51",
   "metadata": {},
   "source": [
    "> Hvor mange parametre er der?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a54d5c57",
   "metadata": {},
   "source": [
    "##### Svar"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "225ea351",
   "metadata": {},
   "source": [
    "Det samlede antal parametre for netværket er:\n",
    "\n",
    "* Lag 1: (784 input × 256 neuroner) + 256 bias = 200.704 + 256 = 200.960\n",
    "* Lag 2: (256 input × 128 neuroner) + 128 bias = 32.768 + 128 = 32.896\n",
    "* Lag 3: (128 input × 10 neuroner) + 10 bias = 1.280 + 10 = 1.290\n",
    "\n",
    "I alt: 200.960 + 32.896 + 1.290 = 235.146"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "12059d0a",
   "metadata": {},
   "source": [
    "#### Træning via SKLearn"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18c0ce30",
   "metadata": {},
   "source": [
    "Vi finder de optimale værdier for alle parametrene i $Phi-$funktionen ved at træne modellen med `fit`-metoden:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "30eb599b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iteration 1, loss = 0.22757620\n",
      "Iteration 2, loss = 0.08920455\n",
      "Iteration 3, loss = 0.05955793\n",
      "Iteration 4, loss = 0.04347159\n",
      "Iteration 5, loss = 0.03397271\n",
      "Iteration 6, loss = 0.02918372\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/jakle/Python/envs/intermat/lib/python3.10/site-packages/sklearn/neural_network/_multilayer_perceptron.py:781: ConvergenceWarning: Stochastic Optimizer: Maximum iterations (6) reached and the optimization hasn't converged yet.\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  display: none;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  overflow: visible;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".estimator-table summary {\n",
       "    padding: .5rem;\n",
       "    font-family: monospace;\n",
       "    cursor: pointer;\n",
       "}\n",
       "\n",
       ".estimator-table details[open] {\n",
       "    padding-left: 0.1rem;\n",
       "    padding-right: 0.1rem;\n",
       "    padding-bottom: 0.3rem;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table {\n",
       "    margin-left: auto !important;\n",
       "    margin-right: auto !important;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(odd) {\n",
       "    background-color: #fff;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(even) {\n",
       "    background-color: #f6f6f6;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:hover {\n",
       "    background-color: #e0e0e0;\n",
       "}\n",
       "\n",
       ".estimator-table table td {\n",
       "    border: 1px solid rgba(106, 105, 104, 0.232);\n",
       "}\n",
       "\n",
       ".user-set td {\n",
       "    color:rgb(255, 94, 0);\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td.value pre {\n",
       "    color:rgb(255, 94, 0) !important;\n",
       "    background-color: transparent !important;\n",
       "}\n",
       "\n",
       ".default td {\n",
       "    color: black;\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td i,\n",
       ".default td i {\n",
       "    color: black;\n",
       "}\n",
       "\n",
       ".copy-paste-icon {\n",
       "    background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNy4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTIwOCAwTDMzMi4xIDBjMTIuNyAwIDI0LjkgNS4xIDMzLjkgMTQuMWw2Ny45IDY3LjljOSA5IDE0LjEgMjEuMiAxNC4xIDMzLjlMNDQ4IDMzNmMwIDI2LjUtMjEuNSA0OC00OCA0OGwtMTkyIDBjLTI2LjUgMC00OC0yMS41LTQ4LTQ4bDAtMjg4YzAtMjYuNSAyMS41LTQ4IDQ4LTQ4ek00OCAxMjhsODAgMCAwIDY0LTY0IDAgMCAyNTYgMTkyIDAgMC0zMiA2NCAwIDAgNDhjMCAyNi41LTIxLjUgNDgtNDggNDhMNDggNTEyYy0yNi41IDAtNDgtMjEuNS00OC00OEwwIDE3NmMwLTI2LjUgMjEuNS00OCA0OC00OHoiLz48L3N2Zz4=);\n",
       "    background-repeat: no-repeat;\n",
       "    background-size: 14px 14px;\n",
       "    background-position: 0;\n",
       "    display: inline-block;\n",
       "    width: 14px;\n",
       "    height: 14px;\n",
       "    cursor: pointer;\n",
       "}\n",
       "</style><body><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>MLPClassifier(batch_size=64, hidden_layer_sizes=(256, 128), max_iter=6,\n",
       "              verbose=True)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>MLPClassifier</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.neural_network.MLPClassifier.html\">?<span>Documentation for MLPClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"\">\n",
       "        <div class=\"estimator-table\">\n",
       "            <details>\n",
       "                <summary>Parameters</summary>\n",
       "                <table class=\"parameters-table\">\n",
       "                  <tbody>\n",
       "                    \n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('hidden_layer_sizes',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">hidden_layer_sizes&nbsp;</td>\n",
       "            <td class=\"value\">(256, ...)</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('activation',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">activation&nbsp;</td>\n",
       "            <td class=\"value\">&#x27;relu&#x27;</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('solver',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">solver&nbsp;</td>\n",
       "            <td class=\"value\">&#x27;adam&#x27;</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('alpha',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">alpha&nbsp;</td>\n",
       "            <td class=\"value\">0.0001</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('batch_size',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">batch_size&nbsp;</td>\n",
       "            <td class=\"value\">64</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('learning_rate',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">learning_rate&nbsp;</td>\n",
       "            <td class=\"value\">&#x27;constant&#x27;</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('learning_rate_init',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">learning_rate_init&nbsp;</td>\n",
       "            <td class=\"value\">0.001</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('power_t',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">power_t&nbsp;</td>\n",
       "            <td class=\"value\">0.5</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_iter',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_iter&nbsp;</td>\n",
       "            <td class=\"value\">6</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('shuffle',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">shuffle&nbsp;</td>\n",
       "            <td class=\"value\">True</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('random_state',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">random_state&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('tol',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">tol&nbsp;</td>\n",
       "            <td class=\"value\">0.0001</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('verbose',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">verbose&nbsp;</td>\n",
       "            <td class=\"value\">True</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('warm_start',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">warm_start&nbsp;</td>\n",
       "            <td class=\"value\">False</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('momentum',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">momentum&nbsp;</td>\n",
       "            <td class=\"value\">0.9</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('nesterovs_momentum',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">nesterovs_momentum&nbsp;</td>\n",
       "            <td class=\"value\">True</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('early_stopping',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">early_stopping&nbsp;</td>\n",
       "            <td class=\"value\">False</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('validation_fraction',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">validation_fraction&nbsp;</td>\n",
       "            <td class=\"value\">0.1</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('beta_1',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">beta_1&nbsp;</td>\n",
       "            <td class=\"value\">0.9</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('beta_2',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">beta_2&nbsp;</td>\n",
       "            <td class=\"value\">0.999</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('epsilon',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">epsilon&nbsp;</td>\n",
       "            <td class=\"value\">1e-08</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('n_iter_no_change',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">n_iter_no_change&nbsp;</td>\n",
       "            <td class=\"value\">10</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_fun',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_fun&nbsp;</td>\n",
       "            <td class=\"value\">15000</td>\n",
       "        </tr>\n",
       "    \n",
       "                  </tbody>\n",
       "                </table>\n",
       "            </details>\n",
       "        </div>\n",
       "    </div></div></div></div></div><script>function copyToClipboard(text, element) {\n",
       "    // Get the parameter prefix from the closest toggleable content\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;\n",
       "\n",
       "    const originalStyle = element.style;\n",
       "    const computedStyle = window.getComputedStyle(element);\n",
       "    const originalWidth = computedStyle.width;\n",
       "    const originalHTML = element.innerHTML.replace('Copied!', '');\n",
       "\n",
       "    navigator.clipboard.writeText(fullParamName)\n",
       "        .then(() => {\n",
       "            element.style.width = originalWidth;\n",
       "            element.style.color = 'green';\n",
       "            element.innerHTML = \"Copied!\";\n",
       "\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        })\n",
       "        .catch(err => {\n",
       "            console.error('Failed to copy:', err);\n",
       "            element.style.color = 'red';\n",
       "            element.innerHTML = \"Failed!\";\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        });\n",
       "    return false;\n",
       "}\n",
       "\n",
       "document.querySelectorAll('.fa-regular.fa-copy').forEach(function(element) {\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const paramName = element.parentElement.nextElementSibling.textContent.trim();\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;\n",
       "\n",
       "    element.setAttribute('title', fullParamName);\n",
       "});\n",
       "</script></body>"
      ],
      "text/plain": [
       "MLPClassifier(batch_size=64, hidden_layer_sizes=(256, 128), max_iter=6,\n",
       "              verbose=True)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Træn\n",
    "clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92cc0d42",
   "metadata": {},
   "source": [
    "#### Forudsigelse på et enkelt billede"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "beda7585",
   "metadata": {},
   "source": [
    "Denne funktion kan vi nu bruge på et enkelt input-billede for at få en forudsigelse. Lad os tage et enkelt billede fra vores testsæt og se, hvad modellen forudsiger."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "540e552f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.61960784 0.90588235 0.14901961 0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.02745098 0.25490196 0.56862745\n",
      "  0.56862745 0.34509804 0.         0.05490196 0.83137255 0.99215686\n",
      "  0.28235294 0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.09019608 0.14509804\n",
      "  0.25882353 0.7254902  0.99215686 0.9372549  0.91372549 0.99215686\n",
      "  0.59607843 0.45490196 0.99215686 0.80784314 0.10980392 0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.06666667 0.87058824 0.99215686 0.99215686 0.9372549\n",
      "  0.80392157 0.27058824 0.14509804 0.64705882 0.99607843 0.99215686\n",
      "  0.89803922 0.10980392 0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.0745098\n",
      "  0.90196078 0.99215686 0.99215686 0.48235294 0.         0.\n",
      "  0.         0.58823529 0.99607843 0.81176471 0.24313725 0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.14901961 0.60392157\n",
      "  0.99215686 0.78823529 0.19215686 0.         0.46666667 0.98431373\n",
      "  0.98431373 0.30588235 0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.03921569 0.76470588 0.99215686\n",
      "  0.92941176 0.80784314 0.97647059 0.99215686 0.56470588 0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.10196078 0.50196078 0.92156863 0.99215686\n",
      "  0.99215686 0.99215686 0.90196078 0.38431373 0.14509804 0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.38039216 0.99215686 0.99215686 0.99215686\n",
      "  0.99607843 0.99215686 0.9372549  0.58431373 0.12156863 0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.56078431 0.99215686 0.78823529 0.06666667 0.29411765 0.51764706\n",
      "  0.81176471 0.99215686 0.84705882 0.11372549 0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.1372549  0.90196078 0.99607843\n",
      "  0.54509804 0.         0.         0.         0.07058824 0.56470588\n",
      "  0.98431373 0.8627451  0.12156863 0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.80784314 0.99215686 0.09411765 0.\n",
      "  0.         0.         0.         0.         0.66666667 0.99215686\n",
      "  0.69019608 0.01568627 0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.50980392 0.99215686 0.38823529 0.         0.         0.\n",
      "  0.         0.         0.09019608 0.78039216 0.99215686 0.14117647\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.27058824 0.96862745\n",
      "  0.64705882 0.64313725 0.         0.         0.         0.\n",
      "  0.         0.28627451 0.99215686 0.45882353 0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.85490196 0.99215686 0.99215686\n",
      "  0.11764706 0.         0.         0.         0.         0.28627451\n",
      "  0.99215686 0.61176471 0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.38431373 0.83137255 0.99215686 0.8745098  0.3254902\n",
      "  0.         0.         0.         0.07058824 0.85098039 0.90588235\n",
      "  0.07058824 0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.28627451 0.98039216 0.99607843 0.88627451 0.30980392 0.\n",
      "  0.         0.23529412 0.95686275 0.86666667 0.0627451  0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.13333333\n",
      "  0.99607843 0.99215686 0.83921569 0.30980392 0.         0.28627451\n",
      "  0.99215686 0.43529412 0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.36470588 0.99215686\n",
      "  0.99215686 0.97647059 0.78823529 0.81568627 0.99215686 0.14117647\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.00392157 0.31764706 0.81176471 0.99215686\n",
      "  0.99215686 0.85490196 0.36078431 0.00784314 0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.         0.         0.\n",
      "  0.         0.         0.         0.        ]]\n",
      "8\n",
      "[[7.08580512e-05 2.61484819e-04 1.44964793e-05 1.17057312e-03\n",
      "  1.67150883e-05 5.34671916e-02 4.29566890e-01 8.57747096e-06\n",
      "  5.14443444e-01 9.79769433e-04]]\n",
      "[8]\n"
     ]
    }
   ],
   "source": [
    "image_index = 2 # Vælg et billede (input)\n",
    "input_image = X_test[image_index:image_index+1] # Format (1, 784)\n",
    "true_label = y_test[image_index]\n",
    "\n",
    "probability_vector = clf.predict_proba(input_image) # Få sandsynlighedsvektoren\n",
    "predicted_label = clf.predict(input_image) # Lav forudsigelse \n",
    "\n",
    "print(input_image)\n",
    "print(true_label)\n",
    "print(probability_vector)\n",
    "print(predicted_label)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f58aa6ac",
   "metadata": {},
   "source": [
    "#### Total forudsigelse"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "212eca12",
   "metadata": {},
   "source": [
    "Den samlede procentandel af billeder i testsættet, som modellen klassificerede korrekt kan findes ved:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f45e90fb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test accuracy: 0.9778\n"
     ]
    }
   ],
   "source": [
    "# Samlet evaluering\n",
    "print(\"Test accuracy:\", clf.score(X_test, y_test))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d7850f35",
   "metadata": {},
   "source": [
    "#### Visualisering af forudsigelser"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5afb6a4",
   "metadata": {},
   "source": [
    "For at få en bedre fornemmelse af, hvordan modellen opfører sig, kan vi visualisere dens forudsigelser på enkelte billeder fra testsættet. Nedenstående funktion plotter billedet, den korrekte label, den forudsagte label og et søjlediagram over de forudsagte sandsynligheder for hver klasse. Dette er nyttigt for at se, hvornår modellen er sikker, og hvornår den er i tvivl."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "bcc8937e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 1200x600 with 10 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def show_images_with_mlp_probabilities(clf, X_test, y_test, X_test_orig, \n",
    "                                       num_images=5, only_incorrect=False,\n",
    "                                       image_shape=(8,8)):\n",
    "    # Predict full test set\n",
    "    pred_labels = clf.predict(X_test)\n",
    "    probas = clf.predict_proba(X_test)\n",
    "\n",
    "    # Select indices\n",
    "    all_indices = np.arange(len(X_test))\n",
    "    if only_incorrect:\n",
    "        indices = all_indices[pred_labels != y_test][:num_images]\n",
    "    else:\n",
    "        indices = all_indices[:num_images]\n",
    "\n",
    "    plt.figure(figsize=(12, 6))\n",
    "\n",
    "    for i, idx in enumerate(indices):\n",
    "        # --- Image plot ---\n",
    "        plt.subplot(2, num_images, i + 1)\n",
    "        img = X_test_orig[idx].reshape(image_shape)\n",
    "        plt.imshow(img, cmap='gray')\n",
    "        plt.title(f\"Idx {idx}\\nTrue {y_test[idx]}\\nPred {pred_labels[idx]}\")\n",
    "        plt.axis('off')\n",
    "\n",
    "        # --- Probability distribution ---\n",
    "        plt.subplot(2, num_images, num_images + i + 1)\n",
    "\n",
    "        p = probas[idx]\n",
    "\n",
    "        classes = np.arange(len(p))\n",
    "        colors = [\n",
    "            \"red\" if c == y_test[idx] else\n",
    "            (\"green\" if c == pred_labels[idx] else \"blue\")\n",
    "            for c in classes\n",
    "        ]\n",
    "\n",
    "        plt.bar(classes, p, color=colors)\n",
    "        plt.xticks(classes)\n",
    "        plt.ylim(0, 1)\n",
    "        plt.xlabel(\"Class\")\n",
    "        plt.ylabel(\"Probability\")\n",
    "\n",
    "    plt.tight_layout()\n",
    "    plt.show()\n",
    "\n",
    "show_images_with_mlp_probabilities(\n",
    "    clf, \n",
    "    X_test, \n",
    "    y_test, \n",
    "    X_test_orig=X_test, \n",
    "    only_incorrect=False,\n",
    "    num_images=5,\n",
    "    image_shape=(28,28)\n",
    ")    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "c05364ee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAJBCAYAAACXuAblAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAbNFJREFUeJzt3X18zfX/x/HnMba52sj1GBu5yHWIJEkWRaRSSK5KKhepVaJodLUupVBK0hVRiiShhK70lWslIpe5vtwYNrb374/9LGufw87Z2eecz/a432673fI6n/f5vM5xnra9+pzzdhljjAAAAAAAAAAbFfB3AwAAAAAAAMh/GEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbMZQCAAAAAACA7RhKIYs+ffooKirK320AsEA+AWchs4BzkFfAecit8zGUyifef/99uVwurVixwvZzX3vttXK5XFm+brjhhizHrly5UjfccIPCwsJUvHhxtW3bVmvWrLG9Z8BO/sznwoULdc8996hu3boKCgpy+0191KhRljk+9/Xzzz9brjtz5oxq164tl8ulV155JRcfCWAfJ2RWkvbu3av+/fsrOjpahQsXVrVq1RQbG6vDhw9nOm7SpElq1aqVypUrp5CQEEVHR6tv377avn177j4YwAb+yuvJkyc1YcIEtW3bVhUqVFDx4sV1+eWX66233lJqamqmYzdu3KihQ4eqYcOGKl68uCpUqKAOHTpY9jxr1iy1a9dOERERCgkJUaVKldSlSxf9/vvvdj00INc5Ibf/NXXqVLlcLhUrVizLbcuXL9eAAQPUuHFjFSpUSC6XK7cegiMV9HcDyB8qVaqk+Pj4TLWIiIhMf161apWuvvpqRUZGKi4uTmlpaXrzzTfVqlUrLV++XDVr1rSzZSBfmDZtmmbMmKFGjRplyeT5br31Vl166aVZ6k888YROnDihK664wnLduHHjtHPnTp/1C+R32c3siRMn1Lx5cyUlJWnAgAGKjIzU2rVrNX78eC1evFgrV65UgQLp/29y9erVio6OVqdOnVSyZElt27ZNkyZN0ty5c7V27doLngeAta1bt2rw4MFq06aNYmNjFRYWpgULFmjAgAH69ddf9cEHH2Qc++6772ry5Mm67bbbNGDAACUkJOjtt9/WlVdeqfnz5ysmJibj2PXr16tkyZIaMmSISpcurX379um9995T06ZNtWzZMjVo0MAfDxfIEzzJ7flOnDihoUOHqmjRopa3z5s3T++++67q16+vqlWr6q+//srNh+E8BvnClClTjCTz22+/XfTY3r17mypVqvjs3K1atTJ16tS56HHt27c3JUuWNIcOHcqo7dmzxxQrVszceuutPusHCDT+zOfu3btNSkqKMcaYDh06eHTfO3fuNC6Xy9x7772Wt+/fv9+Eh4ebp59+2kgyL7/8si9aBvzOCZmdOnWqkWTmzp2bqf7UU08ZSWbVqlUXPM+KFSuMJBMfH++TvgF/8VdeDx48aH7//fcs9b59+xpJZvPmzRm1FStWmOPHj2c67tChQ6ZMmTKmRYsWFz3Xvn37TMGCBc19992X88aBAOCE3J7v8ccfNzVr1jQ9evQwRYsWzXL7vn37zMmTJ40xxgwcONAwhsmMt+/lc7Nnz1bdunUVGhqqunXratasWVmOiYuLU4ECBbRo0aJM9f79+ys4OFhr167N1rnOnj2rEydOuL39xx9/VExMjEqVKpVRq1Chglq1aqW5c+decC2QF9mRz4iICBUqVMir/j755BMZY9SjRw/L24cNG6aaNWvqrrvu8ur+AacJpMwmJiZKksqVK5epXqFCBUlS4cKFL7j+3NsCjx07dtFzAU6U23ktXbq06tSpk6V+yy23SJL+/PPPjFrjxo2zvOWnVKlSatmyZabj3ClbtqyKFClCXpHnBVJuz9m8ebNee+01jRkzRgULWr8RrVy5chf9vpufMZTKxxYuXKjbbrtNLpdL8fHx6ty5s/r27ZvlvbsjRoxQw4YNdc899+j48eOSpAULFmjSpEl66qmnsnWZ8F9//aWiRYuqePHiKl++vEaOHKkzZ85kOiY5OdkyrEWKFFFKSgrvlUe+Ymc+vTV16lRFRkbqmmuuyXLb8uXL9cEHH2js2LG8bx75QqBl9pprrlGBAgU0ZMgQ/frrr/rnn380b948Pffcc+rcubNq1aqVZc3hw4d14MABrVixQn379pUktWnTxif9AIHEn3ndt2+fpPRffrNzrLvjjh07poMHD2r9+vXq16+fEhMTySvytEDN7UMPPaTWrVurffv2XjwqSOK6sfzC6hLIhg0bmgoVKphjx45l1BYuXGgkZbkEcv369SY4ONj069fPHD161FSsWNE0adLEnDlz5qLnvvvuu82oUaPM559/bj788EPTqVMnI8nccccdmY6rV6+eqVGjhjl79mxGLTk52VSuXNlIMjNnzvTy0QOBzZ/5PJ8nb9/7/fffjSQzdOjQLLelpaWZpk2bmu7duxtjjNm2bRtv30Oe4pTMvvvuu6ZEiRJGUsZX79693Z4nJCQk47hSpUqZN954w6N+gEAUKHk1Jv3n2tq1a5vo6OiLrv/hhx+My+UyI0eOtLy9Zs2aGXktVqyYGTFihElNTfW4JyAQOSW3c+fONQULFjR//PGHMSb9rYRWb987H2/fy4oPOs+n9u7dqzVr1mjYsGEKDw/PqF9//fWqXbu2kpKSMh1ft25djR49WsOHD9e6det06NAhLVy40O0liuebPHlypj/37NlT/fv316RJk/Twww/ryiuvlCQNGDBADzzwgO655x4NHTpUaWlpevbZZ7V3715J0qlTp3L6sAFHsDOf3po6daokWb517/3339f69es1c+bMXDs/EEgCNbMVK1ZU06ZN1b59e1WpUkU//vij3njjDZUuXdpyN8xvvvlGp0+f1p9//qmPP/44S99AXuDPvA4aNEgbNmzQ119/fcH1Bw4c0J133qno6GgNHTrU8pgpU6YoMTFRW7du1ZQpU3Tq1CmlpqZmbGAA5CWBmNuUlBQ9/PDDuv/++1W7dm3vHxx4+15+tWPHDklS9erVs9zmbpe7xx57TA0aNNDy5csVFxeXo/A98sgjkqTvvvsuo3b//ffriSee0LRp01SnTh3Vq1dPf//9d8Y3Y6vtNYG8yN/5vBhjjKZNm6a6deuqfv36mW5LTEzU8OHD9dhjjykyMjLXegACSSBm9ueff9ZNN92k5557TkOGDFHnzp316quvasSIERozZow2bNiQZU3r1q114403KjY2Vp999plGjx6t8ePH+7QvwN/8ldeXX35ZkyZN0jPPPHPBt/kkJSXppptu0vHjx/Xll1+6/fm3efPmateunR544AEtWLBAH3/8sYYPH+5xX4ATBGJuX3vtNR06dEijR4/2+H6RGUMpZNvWrVu1efNmSenb0ebEuV9Wjxw5kqn+3HPPaf/+/frxxx+1bt06/fbbb0pLS5Mk1ahRI0fnBPIyX+bzYn7++Wft2LHD8iqpV155RSkpKeratau2b9+u7du3659//pEkHT16VNu3b1dKSkqu9gc4QW5n9u2331a5cuXUpEmTTPVOnTrJGKNffvnlguurVaumyy+/POOqSCA/y2le33//fT3++OO6//77NWLECLfHpaSk6NZbb9W6dev05Zdfqm7dutm6/5IlS+q6664jr8B5cjO3CQkJevbZZ3XvvfcqMTEx42feEydOyBij7du368CBAz55HPkBQ6l8qkqVKpKUEdTzbdq0KUstLS1Nffr0UVhYmJ544gl98skn+uKLL7w+/9atWyVJZcqUyXJbyZIldfXVV6tevXqS0q+mqlSpkuWHsgJ5kb/zeTFTp06Vy+XSnXfemeW2nTt36ujRo6pTp46io6MVHR2tli1bSpKef/55RUdHW16hAThZIGZ2//79Sk1NzVI/t8nI2bNnL3ofp06dUkJCgk/7AvzN7rx++eWX6tevn2699VZNmDDB7XFpaWnq1auXFi1apGnTpqlVq1bZPodEXpG3BVpujx49qhMnTuill17K+Hk3Ojpan3/+uU6ePKno6Gj179/fg0eYz/n5M61gk5x+WNzLL79sJJk5c+aY1NRUc9VVV5myZcuagwcPXvC8CQkJ5vTp05lqaWlppmvXrkaSWbly5QXXT58+3Ugyr7zySjYfKeA8/srnf2Xng85TUlJMqVKlTMuWLS1vX7lypZk1a1amr7fffttIMn369DGzZs3K9JgAJ3JCZgcNGmQkmcWLF2eqP/TQQ0aS+fXXX40xxpw5c8YcOXIky/r//e9/JigoyPTs2dOjnoBA48+8Ll261ISGhprWrVtn+Xn4vwYMGGAkmbfffvuCx+3fvz9Lbdu2baZ48eJuvzcDThPouU1KSsry8+6sWbNM69atTWhoqJk1a1bG99n/4oPOs+KDzvOx+Ph4dejQQVdffbXuvvtuHTlyROPGjVOdOnV04sSJjOP+/PNPjRw5Un369FHHjh0lpV/O2LBhQw0YMECffvqp23OsWrVK3bt3V/fu3XXppZfq1KlTmjVrln7++Wf1799fjRo1yjj2hx9+0NNPP622bduqVKlS+vXXXzVlyhTdcMMNGjJkSO49EUAAsiOfkrRu3TrNmTNHkrRly5aMy5ElqUGDBhn3ec6CBQt0+PBhy7fuSVKjRo0y5VqStm/fLkmqU6eOOnfunO3nAHCSQMvsoEGDNGXKFHXs2FGDBw9WlSpVtHTpUn3yySe6/vrr1axZM0nSiRMnFBkZqa5du6pOnToqWrSo1q9frylTpig8PFwjR470+XMF+Jsded2xY4c6deokl8ulLl266LPPPst0e/369TM+l3Hs2LF688031bx5cxUpUkQff/xxpmNvueUWFS1aVJJUr149tWnTRg0bNlTJkiW1efNmTZ48WWfOnNELL7zgk+cHCESBlNsiRYpY/kw7e/ZsLV++PMttO3bs0EcffSRJWrFihSRlfO+uUqWKevbs6fHzkaf4eyoGe1hNm40x5vPPPzeXXXaZCQkJMbVr1zZffPGF6d27d8a0+ezZs+aKK64wlSpVynJ1w+uvv24kmRkzZrg979atW83tt99uoqKiTGhoqClSpIhp3LixmThxoklLS8t07JYtW0zbtm1N6dKlTUhIiKlVq5aJj483ycnJvnkSgADlr3yef26rr969e2c5vlu3bqZQoULm8OHD2X5827ZtM5LMyy+/nO01QCBzSmY3btxounTpYiIjI02hQoVMlSpVzKOPPmqSkpIyjklOTjZDhgwx9evXN2FhYRnH3XPPPWbbtm1eP0dAoPBXXhcvXuw2q5JMXFxcxrG9e/e+4LHnZzEuLs40adLElCxZ0hQsWNBERESYbt26mXXr1uX4uQIChRNya6V3796maNGiHt1vq1atsvWc5GUuY4zx9aALAAAAAAAAuBA+6BwAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANiOoVQ+4HK5svW1ZMkSf7eq8ePH67LLLlNISIgqVqyo2NhYJSUl+bstwFZOyeyFerv++uv92htgJ6dkdtKkSWrVqpXKlSunkJAQRUdHq2/fvtq+fbtf+wLs5pTM9unTx7KvWrVq+bUvwG5OyazE77PeKOjvBpD7Pvroo0x//vDDD/Xtt99mqV922WV2tpXF448/rpdeekldunTRkCFDtGHDBo0bN05//PGHFixY4NfeADs5JbP/7UeSVqxYoddff11t27b1Q0eAfzgls6tXr1Z0dLQ6deqkkiVLatu2bZo0aZLmzp2rtWvXKiIiwq/9AXZxSmYlKSQkRO+++26mWnh4uJ+6AfzDKZnl91kvGeQ7AwcONNn5q09KSrKhm3R79uwxBQsWND179sxUHzdunJFk5syZY1svQKAJxMy6c8899xiXy2V27drl71YAv3FSZlesWGEkmfj4eH+3AvhNoGa2d+/epmjRoraeE3CCQMwsv896j7fvQZJ07bXXqm7dulq5cqWuueYaFSlSRE888YSk9MslR40alWVNVFSU+vTpk6l27NgxPfTQQ4qMjFRISIguvfRSvfjii0pLS7vg+ZctW6azZ8+qW7dumern/jx9+nTvHxyQB/k7s1aSk5P1+eefq1WrVqpUqZI3DwvIswIxs+fOce5+AfwrkDKbmpqqxMTEnDwcIM/zd2b5fdZ7vH0PGQ4fPqwbb7xR3bp101133aVy5cp5tP7kyZNq1aqVdu/erfvuu0+VK1fWL7/8ouHDh2vv3r0aO3as27XJycmSpMKFC2eqFylSRJK0cuVKzx4MkA/4M7NW5s2bp2PHjqlHjx4erQPyi0DJ7OHDh5WamqqdO3fq6aefliS1adPG04cD5HmBkNmTJ08qLCxMJ0+eVMmSJdW9e3e9+OKLKlasmJePCsi7+H3WmRhKIcO+ffs0ceJE3XfffV6tHzNmjP7++2+tXr1a1atXlyTdd999ioiI0Msvv6xHHnlEkZGRlmtr1qwpSfr555/VunXrjPqPP/4oSdq9e7dXPQF5mT8za2Xq1KkKCQlRly5dvOoHyOsCJbMVK1bM+OG5VKlSeuONN9icALDg78xWqFBBQ4cOVaNGjZSWlqb58+frzTff1Nq1a7VkyRIVLMivcsD5+H3WmXj7HjKEhISob9++Xq//7LPP1LJlS5UsWVKHDh3K+IqJiVFqaqp++OEHt2sbNWqkZs2a6cUXX9SUKVO0fft2ffPNN7rvvvtUqFAhnTp1yuu+gLzKn5n9r8TERH399ddq3769SpQo4XVPQF4WKJn95ptvNG/ePL366quqXLkyuwIBbvg7s/Hx8XrhhRd0xx13qFu3bnr//ff13HPP6eeff9bMmTO97gvIq/h91pkYryNDxYoVFRwc7PX6zZs3a926dSpTpozl7QcOHLjg+s8//1xdu3bV3XffLUkKCgpSbGysli5dqk2bNnndF5BX+Tuz5/v88891+vRp3roHXECgZPbc/8G98cYbdfPNN6tu3boqVqyYBg0a5HVvQF4UKJk938MPP6yRI0fqu+++y/LZNUB+5+/M8vusdxhKIcN/3/96MampqZn+nJaWpuuvv15Dhw61PL5GjRoXvL+KFSvqp59+0ubNm7Vv3z5Vr15d5cuXV0RExEXXAvmRvzN7vqlTpyo8PFw33XSTRz0B+UkgZfacatWq6fLLL9fUqVMZSgH/EYiZLVy4sEqVKqUjR454vBbI6/ydWX6f9Q5DKVxUyZIls+zKk5KSor1792aqVatWTSdOnFBMTEyOzle9evWM9/Bu2LBBe/fuzbIrAgD37M7s3r17tXjxYvXp00chISE5ui8gP7I7s/916tSpjM+YAnBx/szs8ePHdejQIbdXcgDIit9nAxufKYWLqlatWpb3z77zzjtZJst33HGHli1bpgULFmS5j2PHjuns2bMenTctLU1Dhw5VkSJFdP/993veOJBP2Z3Z6dOnKy0tjbfuAV6yI7Nnz57V0aNHs9SXL1+u9evXq0mTJl52D+Q/dmT29OnTOn78eJb6M888I2OMbrjhBi+7B/Iffp8NbFwphYvq16+f7r//ft122226/vrrtXbtWi1YsEClS5fOdNxjjz2mOXPm6KabblKfPn3UuHFjJSUlaf369Zo5c6a2b9+eZc35hgwZotOnT6thw4Y6c+aMpk2bpuXLl+uDDz5Q5cqVc/thAnmGXZk9Z+rUqYqIiNC1116bS48IyNvsyOyJEycUGRmprl27qk6dOipatKjWr1+vKVOmKDw8XCNHjrTjoQJ5gh2Z3bdvny6//HJ1795dtWrVkiQtWLBA8+bN0w033KCbb7451x8nkFfw+2xgYyiFi7r33nu1bds2TZ48WfPnz1fLli317bffqk2bNpmOK1KkiJYuXarnn39en332mT788EOFhYWpRo0aGj16tMLDwy94nssvv1xjx47V1KlTVaBAATVt2lSLFi3KtKUmgIuzK7OStGnTJq1cuVKxsbEqUICLbwFv2JHZIkWKqF+/flq8eLFmzpypU6dOKSIiQt27d9eIESMUFRWVy48SyDvsyGyJEiV000036dtvv9UHH3yg1NRUXXrppXr++ef16KOP8j0X8AC/zwY2lzHG+LsJAAAAAAAA5C+M2AEAAAAAAGA7hlIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2zGUgi2ioqLUp08ff7cBIJvILOAsZBZwFjILOAuZzT0MpfKB999/Xy6XK+MrNDRUNWrU0KBBg7R//35/t5fJ6dOnFR8fr9q1a6tIkSKqWLGibr/9dv3xxx/+bg2wjZMye+LECT300EOqVKmSQkJCdNlll+mtt97yd1uArZyU2aioqEy9nvu6//77/d0aYBsnZVaSjh8/rqFDhyo6OlohISGqWLGiunTpopMnT/q7NcAWTsvsnDlz1KhRI4WGhqpy5cqKi4vT2bNn/d1WwCro7wZgn6efflrR0dE6ffq0fvrpJ7311luaN2+efv/9dxUpUsTf7UmSevTooTlz5ujee+9Vo0aNtGfPHk2YMEHNmzfX+vXrVaVKFX+3CNgm0DObmpqqdu3aacWKFRo4cKCqV6+uBQsWaMCAATp69KieeOIJf7cI2CrQM3tOw4YN9cgjj2Sq1ahRw0/dAP7jhMwmJCSoVatW+ueff9S/f39deumlOnjwoH788UclJycHTJ+AHZyQ2W+++UadO3fWtddeq3Hjxmn9+vV69tlndeDAAf7HrTsGed6UKVOMJPPbb79lqsfGxhpJZtq0aW7Xnjhxwic9VKlSxfTu3fuCx/zzzz9Gknn00Ucz1b///nsjyYwZM8YnvQCBzimZ/fTTT40kM3ny5Ez12267zYSGhpr9+/f7pBcg0Dkls+eO69Chg0/OCTiVkzL7wAMPmBIlSpitW7f65LyAEzkps7Vr1zYNGjQwZ86cyag9+eSTxuVymT///NMnveQ1vH0vH7vuuuskSdu2bZMk9enTR8WKFdPff/+t9u3bq3jx4urRo4ckKS0tTWPHjlWdOnUUGhqqcuXK6b777tPRo0cz3acxRs8++6wqVaqkIkWKqHXr1tl+693x48clSeXKlctUr1ChgiSpcOHC3j9YIA8ItMz++OOPkqRu3bplqnfr1k2nT5/Wl19+maPHCzhdoGX2fCkpKUpKSsrhIwTylkDL7LFjxzRlyhT1799f0dHRSklJUXJysg8fMeBsgZbZDRs2aMOGDerfv78KFvz3TWkDBgyQMUYzZ870xcPOcxhK5WN///23JKlUqVIZtbNnz6pdu3YqW7asXnnlFd12222SpPvuu0+PPfaYWrRooddff119+/bV1KlT1a5dO505cyZj/VNPPaWRI0eqQYMGevnll1W1alW1bds2Wz/4VqtWTZUqVdKrr76qr776Sv/884+WL1+u+++/X9HR0Vl+8QXym0DLbHJysoKCghQcHJypfu7y6ZUrV+b4MQNOFmiZPef7779XkSJFVKxYMUVFRen111/30SMGnC3QMvvTTz/p9OnTuvTSS9WlSxcVKVJEhQsXVosWLbRmzRrfPnjAgQIts6tXr5YkNWnSJFM9IiJClSpVyrgd/+HPy7Rgj3OXO3733Xfm4MGDZteuXWb69OmmVKlSpnDhwuaff/4xxhjTu3dvI8kMGzYs0/off/zRSDJTp07NVJ8/f36m+oEDB0xwcLDp0KGDSUtLyzjuiSeeMJKydbnj//73P1OtWjUjKeOrcePGZu/evTl8FgDncEpmX331VSPJ/Pjjj5nqw4YNM5LMTTfd5O1TADiKUzJrjDEdO3Y0L774opk9e7aZPHmyadmypZFkhg4dmsNnAXAOp2R2zJgxRpIpVaqUadq0qZk6dap58803Tbly5UzJkiXNnj17fPBsAIHPKZl9+eWXjSSzc+fOLLddccUV5sorr/Tm4ed5XCmVj8TExKhMmTKKjIxUt27dVKxYMc2aNUsVK1bMdNwDDzyQ6c+fffaZwsPDdf311+vQoUMZX40bN1axYsW0ePFiSdJ3332nlJQUDR48WC6XK2P9Qw89lO0eS5YsqYYNG2rYsGGaPXu2XnnlFW3fvl233367Tp8+7f2DBxwo0DN75513Kjw8XHfffbe+/fZbbd++Xe+8847efPNNSdKpU6dy8OgB5wn0zErpOwINHTpUN998s+6++24tXbpU7dq105gxY/TPP/94/+ABBwr0zJ44cUKS5HK5tGjRIt1555164IEHNHv2bB09elQTJkzIwaMHnCfQM3vuZ9+QkJAst4WGhvKzsRvsvpePTJgwQTVq1FDBggVVrlw51axZUwUKZJ5LFixYUJUqVcpU27x5sxISElS2bFnL+z1w4IAkaceOHZKk6tWrZ7q9TJkyKlmy5EX7S0hIUMuWLfXYY49l2hWoSZMmuvbaazVlypQs/8AAeVmgZ7Z8+fKaM2eOevbsqbZt20qSwsLCNG7cOPXu3VvFihXL3gMF8ohAz6wVl8ulhx9+WAsWLNCSJUt01113eXU/gBMFembPfZ5qx44dM31PvfLKKxUdHa1ffvnlovcB5CVOyazVZ7+dPn2az0h2g6FUPtK0adMs72/9r5CQkCzBTktLU9myZTV16lTLNWXKlPFJf59//rn279+vTp06Zaq3atVKYWFh+vnnnxlKIV8J9MxK0jXXXKOtW7dq/fr1SkpKUoMGDbRnzx5JbDGP/McJmbUSGRkpSTpy5EiungcINIGe2YiICElZNwGSpLJly2b5gGYgrwv0zJ7boGvv3r0Z31vP2bt3r5o2beqT8+Q1DKVwUdWqVdN3332nFi1aXHC6W6VKFUnpk+iqVatm1A8ePJitb5r79++XJKWmpmaqG2OUmpqqs2fPetM+kO/YldlzgoKC1LBhw4w/f/fdd5LSL7EGcHF2Z/a/tm7dKin3h19AXmFXZhs3bixJ2r17d5bb9uzZo1q1annaOpAv2ZXZcz8Pr1ixItMAas+ePfrnn3/Uv39/Lx9B3sZnSuGi7rjjDqWmpuqZZ57JctvZs2d17NgxSem/gBYqVEjjxo2TMSbjmLFjx2brPOeuqpg+fXqm+pw5c5SUlKTLL7/cuwcA5DN2ZdbKwYMH9eKLL6p+/foMpYBssiuzR44cyfI/fs6cOaMXXnhBwcHBat26tdePAchP7MpszZo11aBBA3355Zc6dOhQRn3hwoXatWuXrr/++hw9DiC/sCuzderUUa1atfTOO+9k+n771ltvyeVyqUuXLjl6HHkVV0rholq1aqX77rtP8fHxWrNmjdq2batChQpp8+bN+uyzz/T666+rS5cuKlOmjB599FHFx8frpptuUvv27bV69Wp98803Kl269EXP07FjR9WpU0dPP/20duzYoSuvvFJbtmzR+PHjVaFCBd1zzz02PFrA+ezK7LlzNW/eXJdeeqn27dund955RydOnNDcuXOzXDoNwJpdmZ0zZ46effZZdenSRdHR0Tpy5IimTZum33//Xc8//7zKly9vw6MFnM/O77Ovvfaarr/+el199dW67777lJCQoDFjxqhGjRp8rAWQTXZm9uWXX1anTp3Utm1bdevWTb///rvGjx+vfv366bLLLsvlR+pMDKWQLRMnTlTjxo319ttv64knnlDBggUVFRWlu+66Sy1atMg47tlnn1VoaKgmTpyoxYsXq1mzZlq4cKE6dOhw0XMEBwfrxx9/1DPPPKOvv/5an3zyiYoXL67OnTvr+eefz/Y/BADsyayU/taCzz77TLt371ZYWJiuv/56PfPMM5kueQZwcXZktl69eqpdu7Y+/vhjHTx4UMHBwWrYsKE+/fRT3X777bn58IA8x67vs61bt9b8+fM1cuRIPfHEEypSpIg6d+6sl156iQ1FAA/YldmbbrpJX3zxhUaPHq3BgwerTJkyeuKJJ/TUU0/l1kNzPJc5/7o0AAAAAAAAwAa8twIAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANiuoL8b8AeXy+XvFoBsMcb4u4WAQGbhFGQ2HZmFU5DZdGQWTkFm05FZOEV2MsuVUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbMZQCAAAAAACA7RhKAQAAAAAAwHYMpQAAAAAAAGA7hlIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsx1AKAAAAAAAAtmMoBQAAAAAAANsxlAIAAAAAAIDtGEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbFfR3AwhMtWrVsqw/99xzlvXOnTu7va8uXbpY1mfNmuVxXwAAAEB2BQcHW9aLFStmWU9OTrasJyUl+awnAM5SrVo1y/qECRMs6+3atbOsL1682LJ+3XXXeddYHsGVUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbsftePnfNNddY1j/44APL+sqVKy3rzz//vM96AgAAuad27dqW9Ztvvtmyfvvtt1vWL7/8csu6u12HFi5cmI3uAN+Kjo62rP/www+W9QMHDljWly1b5tF5ly9f7va2pk2benRfkydPtqwfPnzYsn7kyBGP6gCkRo0aub3tzTfftKxfccUVlvW0tDTLeosWLSzrrVu3tqy7260vr+FKKQAAAAAAANiOoRQAAAAAAABsx1AKAAAAAAAAtmMoBQAAAAAAANsxlAIAAAAAAIDtXMYY4+8m7OZyufzdgu1uueUWy/rnn39uWf/iiy8s6yNGjLCsb9y40bvGcEH5MJ6W8mNmneTqq6+2rP/zzz+W9e3bt+diN/5FZtORWe+527muS5cubte428mrevXqlvWCBa03X05OTrasu9v5a+bMmZZ1d7uUpaamWtb9icymy8uZveGGGyzr8+bNs7kT+/zxxx+W9U2bNvnk/j/66CO3t+3du9eyvmrVKsv62bNnPTo3mU2XlzOb24oXL25ZX7Fihds17r6fevp6dPf39tNPP1nW27RpY1k/c+aMR+f1p+w8R1wpBQAAAAAAANsxlAIAAAAAAIDtGEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALAdu+/lMbVq1bKs//bbb5b1BQsWWNZ79eplWT958qR3jfmAux0E3Zk1a1YudWKffBhPS3k5s56qWrWqZb1AAev/xxASEmJZv/32292e46qrrrKsR0VFWdYvueQSy/q6dess69ddd53bczsdmU0XiJmdOHGiZd1dFtztXrV+/XqPzhsUFOTReUuWLOnR/V/I8ePHLesffPCBZf3TTz+1rLvbFSgvILPpAjGzvlKqVCnL+pgxYyzr7r6fVqlSxbJeunRpy/pbb73ltqdixYpZ1qtVq2ZZr1ixotv7suLu352YmBiP7seXnn76acv6qFGjPLofMpsuL2fWV0JDQy3rL7zwgmX9wQcf9Pgcp0+f9ujcnipbtqxl/dChQz65fzuw+x4AAAAAAAACEkMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2xX0dwPwrYcfftiyXqRIEct6ly5dcrMdr2zYsMGyXrNmTcv6rl27LOs//vijZd1JuxXA/9ztUuXu9fjVV19Z1pOTky3r7jLobleVyy+/3LJesKBn/5y725VLks6cOWNZd7eLp7udh+rVq+dRT0Bu2rFjh2V99+7dlvUSJUpY1m+66SbLurudLt2dd8qUKZb12NhYy3pCQoJlXZKmTZtmWX/xxRct6zt37nR7X0Bec/jwYct67969LesrVqywrDdq1Miy/sgjj1jWx40bl43ucoe73ffq1q1rcyf/crejKZBbHnvsMcv64MGDLesX2iXu6NGjlvURI0ZY1idMmGBZd/fzfX7fVZIrpQAAAAAAAGA7hlIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2Y/e9PMbdJ/e7q9eqVcuyvnHjRp/1VKZMGcv6hx9+aFl3t6uZu8fgbsdBdtmDL/zwww+W9Z49e1rWmzZt6tH9b9u2zbIeHBxsWZ8xY4ZH979gwQKP6pJ08OBBj87x119/WdYrV65sWW/SpIll3d2OR4AvxMfHW9ZfffVVj+7H3W62hQoVsqy7y9Pw4cMt6+52xuzYsaPbnn766Se3twH5nbufE93VK1SoYFnv06ePZX3WrFle9ZWbUlNTLetr1661uRMg9/Xr18+y/uSTT/rsHIsWLbKsv/DCCz47R37GlVIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA27H7Xh4zcuRIy3rjxo0t6xs2bLCsf/HFF5b12rVre3Q/kvTnn39a1tu2bWtZX7VqlWX9xhtvtKyzyx5y0549ezw6/umnn7asjxo1ygfdBKZp06ZZ1ocNG2ZZP3PmTG62A3gkJSUlV493Z+fOnR4df/LkSZ+cF3AKl8tlWS9btqxlPS4uzrLubmeuyZMnW9bd7U775ZdfWtbd7Q4NwLciIyMt66+99ppl3d1O1u4y+9BDD7k99+uvv+7RfXnK3e8bycnJPrn/QMeVUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbsfteHnPw4EHLurud6yZOnGhZr1mzpmV96dKllvVZs2a57ally5aWdXe7FbDLHpwsP+7CU6pUKct6gQLW/9+jcOHCudkO4AhTp061rI8YMcKy/tlnn7m9r+eff96yPmPGDMv6iRMnLtId4H+lS5e2rLvbHa9y5cqW9ccee8yy7m43LQD+FRUVZVl3l/0iRYp4dP8vvfSSZb1hw4Ye3Y8vudtVtFChQjZ34h9cKQUAAAAAAADbMZQCAAAAAACA7RhKAQAAAAAAwHYMpQAAAAAAAGA7hlIAAAAAAACwHbvv5RPudq7r0qVLrp/7vvvus6y7XC7LOrvsAYEpLCzMsl6jRg3LekJCgmX9119/taxfeumllnV3/yacPHnSsu5uByZJ2rt3r2U9KSnJ7RrATrfccotl/emnn3a7Zty4cZZ1d99/H3zwQcu6u2wC/vDoo49a1uvXr29Zf/jhhy3rf//9t2X9/fff96qv7Prf//7n9rbdu3db1rds2eKTc//555+W9fy4QzCc5+6777asV69e3Sf3//HHH1vWly1b5vF9uft91tOsFSxoPZZxt5N1XpM/HiUAAAAAAAACCkMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA27H7HnzC3W5BktS5c2fL+hdffJFL3QC+c+bMGct6WlqaZT04ODg323ErKCjIst6rVy/LurtduST3O4lccskllvWKFSta1t3tJOJuh6+mTZta1nfs2GFZd7e7n7udmSRp06ZNlvXLLrvM7RrAThs3brSs33HHHW7X1KpVy7I+efJky/r8+fMt6+52O3vvvfcs6+7+HQR8oVmzZh4d/9prr+VSJ95x9/1X8nzHLk+Pnz17tmV94MCBlnV3O9MCuSk8PNyy7u5nVHev9+TkZMt6y5YtLesjR460rBctWtSyfiHsaOkbXCkFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANjOZfLhPobutlWF95588km3t917772W9SZNmljWDx065JOe8oJ8GE9LgZhZd6/Tw4cPW9Zr1qyZm+243cZ2xYoVlvUL9ePp1tOe+v777y3rnm5Jfe2111rWlyxZ4vG5p0yZ4tG53SGz6QIxs/jXe++9Z1nv06ePZf2RRx6xrL/22mu+aslvyGy6QMxsVFSUZb1ixYr2NhIA6tata1lv3769Zb1gwYKW9QoVKljWR40aZVn/9ddfLesHDhywrNuBzKYLxMx6atKkSZb1u+++26P72bBhg2W9Xr16lvXk5GTLurvcSL772djd/SxatMiyfuONN1rWz54969F5/Sk7zxFXSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsx+578EiZMmUs68uXL3e7xt0uZVdccYVPesrL8mE8LQViZrt162ZZnzZtmmV9zpw5lnV3u1MePHjQu8Zy0Q033GBZ/+yzzyzr7nb4GjJkiM96CjRkNl0gZhYX9/bbb1vW77rrLst648aNLesbN270WU+5jcymI7N5S2hoqGV99erVlnV3O/K62/lrwYIF3jXmA2Q2nZMyW6hQIcv6d999Z1lv2bKlZd3dz8bt2rWzrK9Zs8aynpKSYlm/0O57nnL3Ok1ISLCs169f37L+zz//+Kwnf2H3PQAAAAAAAAQkhlIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2891HzCNfeOaZZyzrlStXdrsmNjY2t9oB/GbJkiWW9Z9++smy3qlTJ8t6cnKyZb1r165e9ZWb3O2odebMGcs6O+QAzrJr1y7LeuHChS3rpUuXzs12AEvXX3+9Zb1u3bqW9e3bt1vWZ82a5auWAs7p06ct6zExMZb1hQsXWtabNWtmWffn7ntwnhIlSljWr776asu6u58fFy9ebFlfv369Zb1JkyaWdXc7F17o51ZP15w9e9ay/sgjj1jW88IueznBlVIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA27H7HnziQrsV5OXdTZB/7du3z7LubmcbdztU7t2712c95bZy5cpZ1t3tqgIgbzh27Jhl/e+//7a3EeQrRYoUsay/+OKLlvWGDRta1t39jDpp0iTL+ty5cz2qO0nr1q0t6zVr1rSs//LLL7nZDuCR5s2bW9bdZbNt27Y+O7enO0p/9NFHlvUpU6b4op08hyulAAAAAAAAYDuGUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZj9z145JprrrGsu9vBBMhvUlJSLOtbtmyxuRPfO3v2rGU9NTXV5k4A5MSNN95oWe/fv79lferUqZZ1J+0eCucJDg62rFevXt2j+3G5XJZ1d6/3q666yrIeHh5uWf/xxx8t64cPH3bbU1JSktvbfCEkJMSyPnToUMv6+vXrLevfffedz3oC/stdNt2JjIz0qG6HsWPHWtZHjBhhbyMOx5VSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsx1AKAAAAAAAAtmMoBQAAAAAAANux+x48UrNmTcv60qVLbe4EgN127NhhWT906JBl/brrrsvNdgD8v4iICMt6mzZtLOvPPvusZd3d7qGvv/66d40BOZCcnGxZ37Bhg2X9iiuu8Ml569ata1n/6KOPPLqf//3vf25v27Ztm0f39ccff1jWv/76a8t669atLesVKlSwrPfs2dOjfgBPJCQkWNZ//fVXy3qzZs1ysx2vzJs3z7L+1FNPWdZPnjyZm+3kOVwpBQAAAAAAANsxlAIAAAAAAIDtGEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALCdyxhj/N2E3Vwul79bcCx3u+yVLl3a7Zprr73Wsn7w4EFftJSn5cN4WiKzgc3dvwvXXHONZb1fv36W9cmTJ/usJ38hs+nIrO91797d7W2vvvqqZb18+fKW9Y8//tiy/thjj1nW9+/ff5HunIvMpnNSZuvUqWNZr1SpkmW9W7dulvXKlSt7dN6oqCjLenR0tEf3Y4fU1FTL+syZMy3rF/r3JdCQ2XROyqw77rIcFxdnWQ8PD7esh4aGWtZbtmzpUT8Xem116dLFsj5r1iyPzpEfZSezXCkFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsB2778EjEydOtKy7201Lkt544w3LemxsrE96ysvyYTwtkdnANmrUKMv6U089ZVmfOnWqZb1nz56+aslvyGw6Mvsvd89F165dLevuvje626VIkr799lvLurudttzVT58+7fYceRWZTUdmLy4iIsKy3r9/f8u6u++Bdli1apVlvUmTJjZ34ntkNh2Z/Ze7HfBuvvlmj+5n9uzZbm+79dZbPbov/Ivd9wAAAAAAABCQGEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALAdQykAAAAAAADYjt334JFbbrnFsj5mzBi3a6Kioizrn3/+uWV9xIgRlvWNGzdeuLk8KB/G0xKZDWxVqlSxrM+dO9ey/vbbb1vWx48f77Oe/IXMpnNSZkuUKGFZr1u3rmW9Xr16lvU2bdpY1suWLWtZr127tmX91Vdftax/9dVXlnVJ+v33393ehgsjs+mclNlAU7BgQcu6u++NklSpUiXL+p133umTnubMmWNZ//rrr31y//5EZtPlx8y6+z3U3Y6ynj5HTZs2dXvbihUrPLov/Ivd9wAAAAAAABCQGEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbOcy+XBfzfy4hWZuK126tNvbli5dalmvWbOmZX3hwoWW9V69elnWDx06dJHunCsfxtMSmXUmd/8ukNm8L7czGxQU5Pa2bt26Wda7dOliWY+JibGsBwcHW9aPHz9uWX/11Vct67/99ptl/bvvvrOsw15kNh3fZ+EUZDZdfszsRx99ZFm/8847PbqfOXPmWNbvuusut2uSkpI8Ogf+lZ3McqUUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbMZQCAAAAAACA7RhKAQAAAAAAwHbsvgcEsHwYT0tkFk5BZtPldmYbNGjg9rbx48db1tesWWNZd7cL3qZNmyzrGzduvHBzcBQym47vs3AKMpuOzMIp2H0PAAAAAAAAAYmhFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO3YfQ8IYPkwnpbILJyCzKYjs3AKMpuOzMIpyGw6MgunYPc9AAAAAAAABCSGUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbMZQCAAAAAACA7RhKAQAAAAAAwHYMpQAAAAAAAGA7hlIAAAAAAACwHUMpAAAAAAAA2M5ljDH+bgIAAAAAAAD5C1dKAQAAAAAAwHYMpQAAAAAAAGA7hlIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsx1AKAAAAAAAAtmMoBQAAAAAAANsxlAIAAAAAAIDtGEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbMZQCAAAAAACA7RhKAQAAAAAAwHYMpQAAAAAAAGA7hlIAAAAAAACwHUMpAAAAAAAA2M6vQ6kffvhBHTt2VEREhFwul2bPnn3RNUuWLFGjRo0UEhKiSy+9VO+//36u9wkgHZkFnIXMAs5CZgFnIbNAzvl1KJWUlKQGDRpowoQJ2Tp+27Zt6tChg1q3bq01a9booYceUr9+/bRgwYJc7hSARGYBpyGzgLOQWcBZyCyQcy5jjPF3E5Lkcrk0a9Ysde7c2e0xjz/+uL7++mv9/vvvGbVu3brp2LFjmj9/vg1dAjiHzALOQmYBZyGzgLOQWcA7jvpMqWXLlikmJiZTrV27dlq2bJmfOgJwIWQWcBYyCzgLmQWchcwCWRX0dwOe2Ldvn8qVK5epVq5cOSUmJurUqVMqXLhwljXJyclKTk7O+HNaWpqOHDmiUqVKyeVy5XrPgLeMMTp+/LgiIiJUoICj5scZyCzyEzKbjszCKchsOjILpyCz6cgsnCK7mXXUUMob8fHxGj16tL/bALy2a9cuVapUyd9t2IbMwunILOAsZBZwFjILOMvFMuuooVT58uW1f//+TLX9+/crLCzMcqosScOHD1dsbGzGnxMSElS5cmXt2rVLYWFhudovkBOJiYmKjIxU8eLF/d2K18gs8hMym47MwinIbDoyC6cgs+nILJwiu5l11FCqefPmmjdvXqbat99+q+bNm7tdExISopCQkCz1sLAwQgxHcPJluWQW+RGZTUdm4RRkNh2ZhVOQ2XRkFk5xscz69c24J06c0Jo1a7RmzRpJ6VtkrlmzRjt37pSUPhXu1atXxvH333+/tm7dqqFDh2rjxo1688039emnn+rhhx/2R/tAvkNmAWchs4CzkFnAWcgs4APGjxYvXmwkZfnq3bu3McaY3r17m1atWmVZ07BhQxMcHGyqVq1qpkyZ4tE5ExISjCSTkJDgmwcB5JJAfK2SWcC9QHytklnAvUB8rZJZwL1AfK2SWcC97L5WXcYYk8tzr4CSmJio8PBwJSQkcLkjAhqv1XQ8D3AKXqvpeB7gFLxW0/E8wCl4rabjeYBTZPe16sy9NAEAAAAAAOBoDKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsV9DfDQAAAAAAAN9wjXZ5vMbEmVzoBLg4rpQCAAAAAACA7RhKAQAAAAAAwHYMpQAAAAAAAGA7hlIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgu4L+bgAIJK7RLo+ON3EmlzoBAAAAACBv40opAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsx1AKAAAAAAAAtmMoBQAAAAAAANsxlAIAAAAAAIDtGEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALBdQX83AACAv7hGuzw63sSZXOoEAAAAyH+4UgoAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2fh9KTZgwQVFRUQoNDVWzZs20fPnyCx4/duxY1axZU4ULF1ZkZKQefvhhnT592qZuAZBZwFnILOAsZBZwFjIL5Ixfh1IzZsxQbGys4uLitGrVKjVo0EDt2rXTgQMHLI+fNm2ahg0bpri4OP3555+aPHmyZsyYoSeeeMLmzoH8icwCzkJmAWchs4CzkFkg5/w6lBozZozuvfde9e3bV7Vr19bEiRNVpEgRvffee5bH//LLL2rRooXuvPNORUVFqW3bturevftFp9EAfIPMAs5CZgFnIbOAs5BZIOf8NpRKSUnRypUrFRMT828zBQooJiZGy5Yts1xz1VVXaeXKlRmh3bp1q+bNm6f27du7PU9ycrISExMzfQHwHJkFnIXMAs5CZgFnIbOAbxT014kPHTqk1NRUlStXLlO9XLly2rhxo+WaO++8U4cOHdLVV18tY4zOnj2r+++//4KXO8bHx2v06NE+7R3Ij8gs4CxkFnAWMgs4C5kFfMPvH3TuiSVLluj555/Xm2++qVWrVumLL77Q119/rWeeecbtmuHDhyshISHja9euXTZ2DORvZBZwFjILOAuZzftco10efyFwkVkgK79dKVW6dGkFBQVp//79mer79+9X+fLlLdeMHDlSPXv2VL9+/SRJ9erVU1JSkvr3768nn3xSBQpknbGFhIQoJCTE9w8AyGfILOAsZBZwFjILOAuZBXzDb1dKBQcHq3Hjxlq0aFFGLS0tTYsWLVLz5s0t15w8eTJLUIOCgiRJxpjcaxYAmQUchswCzkJmAWchs4Bv+O1KKUmKjY1V79691aRJEzVt2lRjx45VUlKS+vbtK0nq1auXKlasqPj4eElSx44dNWbMGF1++eVq1qyZtmzZopEjR6pjx44ZYQaQe8gs4CxkFnAWMgs4C5kFcs6vQ6muXbvq4MGDeuqpp7Rv3z41bNhQ8+fPz/iwuJ07d2aaJI8YMUIul0sjRozQ7t27VaZMGXXs2FHPPfecvx4CkK+QWcBZyCzgLGQWcBYyC+Scy+Sz6wQTExMVHh6uhIQEhYWF+bsdBBhPPxzSxOVefHitpuN5QG7yZeZ5rabjeYBT8FpNx/MQ2Lz54PLc/PnUn3itpsvO88DrBoEgu5l11O57AAAAAAAAyBsYSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsx1AKAAAAAAAAtmMoBQAAAAAAANsxlAIAAAAAAIDtGEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbMZQCAAAAAACA7RhKAQAAAAAAwHYMpQAAAAAAAGA7hlIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgu4L+bgAAAADZ4xrt8niNiTO50AkAAEDOcaUUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbMZQCAAAAAACA7RhKAQAAAAAAwHZeDaUWL17s6z4A5CIyCzgLmQWchcwCzkJmgcDh1VDqhhtuULVq1fTss89q165dvu4JgI+RWcBZyCzgLGQWcBYyCwQOr4ZSu3fv1qBBgzRz5kxVrVpV7dq106effqqUlBRf9wfAB8gs4CxkFnAWMgs4C5kFAodXQ6nSpUvr4Ycf1po1a/S///1PNWrU0IABAxQREaEHH3xQa9eu9XWfAHKAzALOQmYBZyGzgLOQWSBw5PiDzhs1aqThw4dr0KBBOnHihN577z01btxYLVu21B9//OGLHgH4EJkFnIXMAs5CZgFnIbOAf3k9lDpz5oxmzpyp9u3bq0qVKlqwYIHGjx+v/fv3a8uWLapSpYpuv/32i97PhAkTFBUVpdDQUDVr1kzLly+/4PHHjh3TwIEDVaFCBYWEhKhGjRqaN2+etw8DyDfILOAsZBZwFjILOAuZBQJDQW8WDR48WJ988omMMerZs6deeukl1a1bN+P2okWL6pVXXlFERMQF72fGjBmKjY3VxIkT1axZM40dO1bt2rXTpk2bVLZs2SzHp6Sk6Prrr1fZsmU1c+ZMVaxYUTt27FCJEiW8eRhAvkFmAWchs4CzkFnAWcgsEDi8Gkpt2LBB48aN06233qqQkBDLY0qXLn3RrTbHjBmje++9V3379pUkTZw4UV9//bXee+89DRs2LMvx7733no4cOaJffvlFhQoVkiRFRUV58xCAfIXMAs5CZgFnIbOAs5BZIHB49fa9uLg43X777VkCfPbsWf3www+SpIIFC6pVq1Zu7yMlJUUrV65UTEzMv80UKKCYmBgtW7bMcs2cOXPUvHlzDRw4UOXKlVPdunX1/PPPKzU11e15kpOTlZiYmOkLyG/ILOAsZBZwFjILOAuZBQKHV0Op1q1b68iRI1nqCQkJat26dbbu49ChQ0pNTVW5cuUy1cuVK6d9+/ZZrtm6datmzpyp1NRUzZs3TyNHjtSrr76qZ5991u154uPjFR4envEVGRmZrf6AvITMAs5CZgFnIbOAs5BZIHB4NZQyxsjlcmWpHz58WEWLFs1xU+6kpaWpbNmyeuedd9S4cWN17dpVTz75pCZOnOh2zfDhw5WQkJDxtWvXrlzrDwhUZBZwFjILOAuZBZyFzAKBw6PPlLr11lslSS6XS3369Ml0uWNqaqrWrVunq666Klv3Vbp0aQUFBWn//v2Z6vv371f58uUt11SoUEGFChVSUFBQRu2yyy7Tvn37lJKSouDg4CxrQkJC3L5PGMjryCzgLGQWcBYyCzgLmQUCj0dXSp27ZNAYo+LFi2e6jLB8+fLq37+/Pv7442zdV3BwsBo3bqxFixZl1NLS0rRo0SI1b97cck2LFi20ZcsWpaWlZdT++usvVahQwTLAQH5HZgFnIbOAs5BZwFnILBB4PLpSasqUKZLSdwh49NFHc3xpY2xsrHr37q0mTZqoadOmGjt2rJKSkjJ2L+jVq5cqVqyo+Ph4SdIDDzyg8ePHa8iQIRo8eLA2b96s559/Xg8++GCO+gDyKjILOAuZBZyFzALOQmaBwOPRUOqcuLg4n5y8a9euOnjwoJ566int27dPDRs21Pz58zM+LG7nzp0qUODfi7kiIyO1YMECPfzww6pfv74qVqyoIUOG6PHHH/dJP0BeRWYBZyGzgLOQWcBZyCwQOFzGGJOdAxs1aqRFixapZMmSuvzyyy0/GO6cVatW+axBX0tMTFR4eLgSEhIUFhbm73YQYFyj3b+urZi4bMXHKzl9rZJZ4OJ8mXkym47M5i5PX7NS7n6vcjIym47MBjYy/y8ymy47zwOvGwSC7GY221dK3XzzzRkfsNa5c+ccNwggd5FZwFnILOAsZBZwFjILBKZsXymVV/B/g3AheelKqbyC5wG5KZCulMoreB5yF//323d4rabjeQhsZP5fvFbTcaUUnCK7mfVo9z0AAAAAAADAF7L99r2SJUte8H235zty5IjXDQHwDTILOAuZBZyFzALOQmaBwJTtodTYsWNzsQ0AvkZmAWchs4CzkFnAWcgsEJiyPZTq3bt3bvYBwMfILOAsZBZwFjILOAuZBQJTtodSiYmJGR9OlZiYeMFj8/MHzwGBgswCzkJmAWchs4CzkFkgMHn0mVJ79+5V2bJlVaJECcv34xpj5HK5lJqa6tMmAXiOzALOQmYBZyGzgLOQWSAwZXso9f333+uSSy6RJC1evDjXGgLgG2QWcBYyCzgLmQWchcwCgSnbQ6lWrVpZ/jeAwERmAWchs4CzkFnAWcgsEJiyPZT6r6NHj2ry5Mn6888/JUm1a9dW3759M6bPAAILmQWchcwCzkJmAWchs0BgKODNoh9++EFRUVF64403dPToUR09elRvvPGGoqOj9cMPP/i6RwA5RGYBZyGzgLOQWcBZyCwQOLy6UmrgwIHq2rWr3nrrLQUFBUmSUlNTNWDAAA0cOFDr16/3aZMAcobMAs5CZgFnIbOAs5BZIHB4daXUli1b9Mgjj2QEWJKCgoIUGxurLVu2+Kw5AL5BZgFnIbOAs5BZwFnILBA4vBpKNWrUKOO9t+f7888/1aBBgxw3BcC3yCzgLGQWcBYyCzgLmQUCR7bfvrdu3bqM/37wwQc1ZMgQbdmyRVdeeaUk6ddff9WECRP0wgsv+L5LAB4js4CzkFnAWcgs4CxkFghMLmOMyc6BBQoUkMvl0sUOd7lcSk1N9UlzuSExMVHh4eFKSEhQWFiYv9tBgHGNdnl0vInLVny8ktPXKpkFLs6XmSez6chs7vL0NSvl7vcqJyOz6chsYCPz/yKz6bLzPPC6QSDIbmazfaXUtm3bfNIYAHuQWcBZyCzgLGQWcBYyCwSmbA+lqlSpkpt9APAxMgs4C5kFnIXMAs5CZoHAlO2hlJUNGzZo586dSklJyVTv1KlTjpoCkDvILOAsZBZwFjILOAuZBfzPq6HU1q1bdcstt2j9+vWZ3pfrcqW/dzWQ34ML5EdkFnAWMgs4C5kFnIXMAoGjgDeLhgwZoujoaB04cEBFihTRH3/8oR9++EFNmjTRkiVLfNwigJwis4CzkFnAWcgs4CxkFggcXl0ptWzZMn3//fcqXbq0ChQooAIFCujqq69WfHy8HnzwQa1evdrXfQLIATILOAuZBZyFzALOQmaBwOHVlVKpqakqXry4JKl06dLas2ePpPQPj9u0aZPvugPgE2QWcBYyCzgLmQWchcwCgcOrK6Xq1q2rtWvXKjo6Ws2aNdNLL72k4OBgvfPOO6pataqvewSQQ2QWcBYyCzgLmQWchcwCgcOrodSIESOUlJQkSXr66ad10003qWXLlipVqpRmzJjh0wYB5ByZBZyFzALOQmYBZyGzQODwaijVrl27jP++9NJLtXHjRh05ckQlS5bM2LEAQOAgs4CzkFnAWcgs4CxkFggcXg2lzrdr1y5JUmRkZI6bAZD7yCzgLGQWcBYyCzgLmQX8y6sPOj979qxGjhyp8PBwRUVFKSoqSuHh4RoxYoTOnDnj6x4B5BCZBZyFzALOQmYBZyGzQODw6kqpwYMH64svvtBLL72k5s2bS0rfVnPUqFE6fPiw3nrrLZ82CSBnyCzgLGQWcBYyCzgLmQUCh1dDqWnTpmn69Om68cYbM2r169dXZGSkunfvToiBAENmAWchs4CzkFnAWcgsEDi8evteSEiIoqKistSjo6MVHByc054A+BiZBZyFzALOQmYBZyGzQODwaig1aNAgPfPMM0pOTs6oJScn67nnntOgQYN81hwA3yCzgLOQWcBZyCzgLGQWCBzZfvverbfemunP3333nSpVqqQGDRpIktauXauUlBS1adPGtx0C8AqZBZyFzALOQmYBZyGzQGDK9lAqPDw8059vu+22TH9mC00gsJBZwFnILOAsZBZwFjILBKZsD6WmTJmSm30A8DEyCzgLmQWchcwCzkJmgcDk1e575xw8eFCbNm2SJNWsWVNlypTxSVMAcgeZBZyFzALOQmYBZyGzgP959UHnSUlJuvvuu1WhQgVdc801uuaaaxQREaF77rlHJ0+e9HWPAHKIzALOQmYBZyGzgLOQWSBweDWUio2N1dKlS/XVV1/p2LFjOnbsmL788kstXbpUjzzyiMf3N2HCBEVFRSk0NFTNmjXT8uXLs7Vu+vTpcrlc6ty5s8fnBPITMgs4C5kFnIXMAs5CZoHA4dVQ6vPPP9fkyZN14403KiwsTGFhYWrfvr0mTZqkmTNnenRfM2bMUGxsrOLi4rRq1So1aNBA7dq104EDBy64bvv27Xr00UfVsmVLbx4CkK+QWcBZyCzgLGQWcBYyCwQOr4ZSJ0+eVLly5bLUy5Yt6/HljmPGjNG9996rvn37qnbt2po4caKKFCmi9957z+2a1NRU9ejRQ6NHj1bVqlU97h/Ib8gs4CxkFnAWMgs4C5kFAodXQ6nmzZsrLi5Op0+fzqidOnVKo0ePVvPmzbN9PykpKVq5cqViYmL+bahAAcXExGjZsmVu1z399NMqW7as7rnnnoueIzk5WYmJiZm+gPyGzALOQmYBZyGzgLOQWSBweLX73tixY3XDDTeoUqVKatCggSRp7dq1Cg0N1YIFC7J9P4cOHVJqamqWKXW5cuW0ceNGyzU//fSTJk+erDVr1mTrHPHx8Ro9enS2ewLyIjILOAuZBZyFzALOQmaBwOHVUKpevXravHmzpk6dmhG27t27q0ePHipcuLBPGzzf8ePH1bNnT02aNEmlS5fO1prhw4crNjY248+JiYmKjIzMrRaBgERmAWchs4CzkFnAWcgsEDg8HkqdOXNGtWrV0ty5c3Xvvffm6OSlS5dWUFCQ9u/fn6m+f/9+lS9fPsvxf//9t7Zv366OHTtm1NLS0iRJBQsW1KZNm1StWrVMa0JCQhQSEpKjPgEnI7OAs5BZwFnILOAsZBYILB5/plShQoUyvfc2J4KDg9W4cWMtWrQoo5aWlqZFixZZvpe3Vq1aWr9+vdasWZPx1alTJ7Vu3Vpr1qxhYgxYILOAs5BZwFnILOAsZBYILF69fW/gwIF68cUX9e6776pgQa/uIkNsbKx69+6tJk2aqGnTpho7dqySkpLUt29fSVKvXr1UsWJFxcfHKzQ0VHXr1s20vkSJEpKUpQ7gX2QWcBYyCzgLmQWchcwCgcOrBP72229atGiRFi5cqHr16qlo0aKZbv/iiy+yfV9du3bVwYMH9dRTT2nfvn1q2LCh5s+fn/FhcTt37lSBAl5tEgjg/5FZwFnILOAsZBZwFjILBA6XMcZ4uujc1NedKVOmeN1QbktMTFR4eLgSEhIUFhbm73YQYFyjXR4db+I8jk+2+fK1SmYBa77MPJlNR2Zzl6evWSl3v1c5GZlNR2YDG5n/F5lNl53ngdcNAkF2M+vRlVJpaWl6+eWX9ddffyklJUXXXXedRo0alas7FADwHpkFnIXMAs5CZgFnIbNA4PHoOsLnnntOTzzxhIoVK6aKFSvqjTfe0MCBA3OrNwA5RGYBZyGzgLOQWcBZyCwQeDwaSn344Yd68803tWDBAs2ePVtfffWVpk6dmrGNJYDAQmYBZyGzgLOQWcBZyCwQeDwaSu3cuVPt27fP+HNMTIxcLpf27Nnj88YA5ByZBZyFzALOQmYBZyGzQODxaCh19uxZhYaGZqoVKlRIZ86c8WlTAHyDzALOQmYBZyGzgLOQWSDwePRB58YY9enTRyEhIRm106dP6/7778+0jaYnW2gCyD1kFnAWMgs4C5kFnIXMAoHHo6FU7969s9TuuusunzUDwLfILOAsZBZwFjILOAuZBQKPR0OpKVOm5FYfAHIBmQWchcwCzkJmAWchs0Dg8WgoBQAAkO+5XJ4db0zu9AEAAOBwHn3QOQAAAAAAAOALDKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsx1AKAAAAAAAAtmMoBQAAAAAAANsxlAIAAAAAAIDtGEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbMZQCAAAAAACA7RhKAQAAAAAAwHYMpQAAAAAAAGA7hlIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsFxBDqQkTJigqKkqhoaFq1qyZli9f7vbYSZMmqWXLlipZsqRKliypmJiYCx4PwPfILOAsZBZwFjILOAuZBbzn96HUjBkzFBsbq7i4OK1atUoNGjRQu3btdODAAcvjlyxZou7du2vx4sVatmyZIiMj1bZtW+3evdvmzoH8icwCzkJmAWchs4CzkFkgZ1zGGOPPBpo1a6YrrrhC48ePlySlpaUpMjJSgwcP1rBhwy66PjU1VSVLltT48ePVq1evix6fmJio8PBwJSQkKCwsLMf9I29xjXZ5dLyJy734BOprlcwiL/Fl5gP1tUpmc4HLs9eNfPijlqevWSl3v1c5WaC+Vskszkfm/xWor9VAzCyvGwSC7GbWr1dKpaSkaOXKlYqJicmoFShQQDExMVq2bFm27uPkyZM6c+aMLrnkktxqE8D/I7OAs5BZwFnILOAsZBbIuYL+PPmhQ4eUmpqqcuXKZaqXK1dOGzduzNZ9PP7444qIiMj0D8H5kpOTlZycnPHnxMRE7xsG8jkyCzgLmQWchcwCzkJmgZzz+2dK5cQLL7yg6dOna9asWQoNDbU8Jj4+XuHh4RlfkZGRNncJ4BwyCzgLmQWchcwGIJfL8y/kG2QW8PNQqnTp0goKCtL+/fsz1ffv36/y5ctfcO0rr7yiF154QQsXLlT9+vXdHjd8+HAlJCRkfO3atcsnvQP5EZkFnIXMAs5CZgFnIbNAzvl1KBUcHKzGjRtr0aJFGbW0tDQtWrRIzZs3d7vupZde0jPPPKP58+erSZMmFzxHSEiIwsLCMn0B8A6ZBZyFzALOQmYBZyGzQM759TOlJCk2Nla9e/dWkyZN1LRpU40dO1ZJSUnq27evJKlXr16qWLGi4uPjJUkvvviinnrqKU2bNk1RUVHat2+fJKlYsWIqVqyY3x4HkF+QWcBZyCzgLGQWcBYyC+SM34dSXbt21cGDB/XUU09p3759atiwoebPn5/xYXE7d+5UgQL/XtD11ltvKSUlRV26dMl0P3FxcRo1apSdrQP5EpkFnIXMAs5CZgFnIbNAzriMMcbfTdgpMTFR4eHhSkhI4NJHZOEa7dmHS5q43IsPr9V0PA/ITb7MPK/VdPniefD0g4h9+KOWp69ZKXe/VzlZvnitZgPPQy7z5oPLz/s3g8z/i9dquuw8D7xuEAiym1lH774HAAAAAAAAZ2IoBQAAAAAAANsxlAIAAAAAAIDtGEoBAAAAAADAdgylAAAAAAAAYLuC/m4AAJCP5XBXIgAAAADOxZVSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsx1AKAAAAAAAAtmMoBQAAAAAAANsxlAIAAAAAAIDtGEoBAAAAAADAdgylAAAAAAAAYDuGUgAAAAAAALAdQykAAAAAAADYjqEUAAAAAAAAbMdQCgAAAAAAALZjKAUAAAAAAADbMZQCAAAAAACA7RhKAQAAAAAAwHYMpQAAAAAAAGA7hlIAAAAAAACwHUMpAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2Bf3dAJCnuFyeHW9M7vQBAAAAAECA40opAAAAAAAA2I6hFAAAAAAAAGzHUAoAAAAAAAC2YygFAAAAAAAA2zGUAgAAAAAAgO0YSgEAAAAAAMB2DKUAAAAAAABgO4ZSAAAAAAAAsF1ADKUmTJigqKgohYaGqlmzZlq+fPkFj//ss89Uq1YthYaGql69epo3b55NnQKQyCzgNGQWcBYyCzgLmUWgcLk8+woEfh9KzZgxQ7GxsYqLi9OqVavUoEEDtWvXTgcOHLA8/pdfflH37t11zz33aPXq1ercubM6d+6s33//3ebOA5cTX4hwDjILOAuZBZyFzALOQmaRp/hhmOAyxhif3JOXmjVrpiuuuELjx4+XJKWlpSkyMlKDBw/WsGHDshzftWtXJSUlae7cuRm1K6+8Ug0bNtTEiRMver7ExESFh4crISFBYWFhvnsgAcTT14Z/XwGBxTXasyfPxP3nyfPhkx+or1UyC5/y5puZD//RynHmzxOor1Uymwv8+I3W09esdOHXbX4WqK9VMpvH5PD7HJn/V6C+VgMxs7xu/MfPP9rm/EcUP/w+69crpVJSUrRy5UrFxMRk1AoUKKCYmBgtW7bMcs2yZcsyHS9J7dq1c3u8P3g6XPzv3ztXOnkvp889LiyvZtbJeM3jQsgs4CxkFnAWMgvkXEF/nvzQoUNKTU1VuXLlMtXLlSunjRs3Wq7Zt2+f5fH79u2zPD45OVnJyckZf05ISJCUPrULJDlpJ6cP5fz14eGer///p9SxMj1/pz1d68Mn3819+/lixkwCNbP+ft16en5/ZybA/vnznC8fgA8zT2bTBer3Wb/y42s2/fT8XVghs+mc8H023zn/74LMZyCz6bL1fTaHrxt/Zz4nP1v7u3dv+DOyOT63D3429utQyg7x8fEaPXp0lnpkZKQfunHPm/D4Ym0grPe3HD33L+T+k3f8+HGFO/1J9oBdmfXnU+rvv05/nz/H/PgAspN5Mpsu0L7P+pWfXw85/l6Vx5HZdHnp+6zj5fDJy+uZJ7PpfJ7ZHL5unPyztb9fTk5+7nzx+6xfh1KlS5dWUFCQ9u/fn6m+f/9+lS9f3nJN+fLlPTp++PDhio2NzfhzWlqajhw5olKlSsnlwftYEhMTFRkZqV27dnn1HmbWe7/eyb3nZL0xRsePH1dERITH58wtZJb1gX5uf64ns+nIrPPWO7n3nKwns+nIrPPWO7n3nKwns+nIrPPWO7n3nKzPbmb9OpQKDg5W48aNtWjRInXu3FlSesgWLVqkQYMGWa5p3ry5Fi1apIceeiij9u2336p58+aWx4eEhCgkJCRTrUSJEl73HBYWlqMP1mO99+ud3Lu36wPt/wKRWdY75dz+Wk9m05FZZ653cu/eriez6cisM9c7uXdv15PZdGTWmeud3Lu367OTWb+/fS82Nla9e/dWkyZN1LRpU40dO1ZJSUnq27evJKlXr16qWLGi4uPjJUlDhgxRq1at9Oqrr6pDhw6aPn26VqxYoXfeecefDwPIN8gs4CxkFnAWMgs4C5kFcsbvQ6muXbvq4MGDeuqpp7Rv3z41bNhQ8+fPz/jwt507d6pAgX83Cbzqqqs0bdo0jRgxQk888YSqV6+u2bNnq27duv56CEC+QmYBZyGzgLOQWcBZyCyQQwbZcvr0aRMXF2dOnz7NepvXO7l3X6yHd/z995af1zu5d1+sh3f8/feWn9c7uXdfrId3/P33lp/XO7l3X6yHd/z995af1zu5d1+svxiXMQG0pyYAAAAAAADyhQIXPwQAAAAAAADwLYZSAAAAAAAAsB1DKQAAAAAAANiOoRQAAAAAAABsx1AqmyZMmKCoqCiFhoaqWbNmWr58ebbW/fDDD+rYsaMiIiLkcrk0e/Zsj84bHx+vK664QsWLF1fZsmXVuXNnbdq0Kdvr33rrLdWvX19hYWEKCwtT8+bN9c0333jUwzkvvPCCXC6XHnrooWwdP2rUKLlcrkxftWrV8uicu3fv1l133aVSpUqpcOHCqlevnlasWJGttVFRUVnO73K5NHDgwGytT01N1ciRIxUdHa3ChQurWrVqeuaZZ5TdvQGOHz+uhx56SFWqVFHhwoV11VVX6bfffsvWWuQcmSWzZNZZyCyZJbPOQmbJLJl1FjJLZgM1swylsmHGjBmKjY1VXFycVq1apQYNGqhdu3Y6cODARdcmJSWpQYMGmjBhglfnXrp0qQYOHKhff/1V3377rc6cOaO2bdsqKSkpW+srVaqkF154QStXrtSKFSt03XXX6eabb9Yff/zhUR+//fab3n77bdWvX9+jdXXq1NHevXszvn766adsrz169KhatGihQoUK6ZtvvtGGDRv06quvqmTJktnu+fxzf/vtt5Kk22+/PVvrX3zxRb311lsaP368/vzzT7344ot66aWXNG7cuGyt79evn7799lt99NFHWr9+vdq2bauYmBjt3r07W+vhPTJLZsmss5BZMktmnYXMklky6yxklswGdGYNLqpp06Zm4MCBGX9OTU01ERERJj4+3qP7kWRmzZqVo14OHDhgJJmlS5d6fR8lS5Y07777braPP378uKlevbr59ttvTatWrcyQIUOytS4uLs40aNDAuyaNMY8//ri5+uqrvV7/X0OGDDHVqlUzaWlp2Tq+Q4cO5u67785Uu/XWW02PHj0uuvbkyZMmKCjIzJ07N1O9UaNG5sknn8x+0/AKmSWz55BZZyCzZPYcMusMZJbMnkNmnYHMktlzAjGzXCl1ESkpKVq5cqViYmIyagUKFFBMTIyWLVtmez8JCQmSpEsuucTjtampqZo+fbqSkpLUvHnzbK8bOHCgOnTokOk5yK7NmzcrIiJCVatWVY8ePbRz585sr50zZ46aNGmi22+/XWXLltXll1+uSZMmedyDlP73+PHHH+vuu++Wy+XK1pqrrrpKixYt0l9//SVJWrt2rX766SfdeOONF1179uxZpaamKjQ0NFO9cOHCHk3X4TkyS2bJrLOQWTJLZp2FzJJZMussZJbMBnxmfTriyoN2795tJJlffvklU/2xxx4zTZs29ei+lMPJcmpqqunQoYNp0aKFR+vWrVtnihYtaoKCgkx4eLj5+uuvs732k08+MXXr1jWnTp0yxhiPJsvz5s0zn376qVm7dq2ZP3++ad68ualcubJJTEzM1vqQkBATEhJihg8fblatWmXefvttExoaat5///1s93/OjBkzTFBQkNm9e3e216SmpprHH3/cuFwuU7BgQeNyuczzzz+f7fXNmzc3rVq1Mrt37zZnz541H330kSlQoICpUaOGx/0j+8gsmSWzzkJmySyZdRYyS2bJrLOQWTIb6JllKHURgRTi+++/31SpUsXs2rXLo3XJyclm8+bNZsWKFWbYsGGmdOnS5o8//rjoup07d5qyZcuatWvXZtQ8CfF/HT161ISFhWX7UstChQqZ5s2bZ6oNHjzYXHnllR6fu23btuamm27yaM0nn3xiKlWqZD755BOzbt068+GHH5pLLrkk2/+IbNmyxVxzzTVGkgkKCjJXXHGF6dGjh6lVq5bH/SP7yCyZJbPOQmbJLJl1FjJLZsmss5BZMhvomWUodRHJyckmKCgoS/h69eplOnXq5NF95STEAwcONJUqVTJbt271av352rRpY/r373/R42bNmpXxAjz3Jcm4XC4TFBRkzp496/G5mzRpYoYNG5atYytXrmzuueeeTLU333zTREREeHTO7du3mwIFCpjZs2d7tK5SpUpm/PjxmWrPPPOMqVmzpkf3c+LECbNnzx5jjDF33HGHad++vUfr4RkyS2bPR2YDH5kls+cjs4GPzJLZ85HZwEdmyez5AjGzfKbURQQHB6tx48ZatGhRRi0tLU2LFi3y6H2s3jLGaNCgQZo1a5a+//57RUdH5/g+09LSlJycfNHj2rRpo/Xr12vNmjUZX02a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",
      "text/plain": [
       "<Figure size 1200x600 with 10 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_images_with_mlp_probabilities(\n",
    "    clf, \n",
    "    X_test, \n",
    "    y_test, \n",
    "    X_test_orig=X_test, \n",
    "    only_incorrect=True,\n",
    "    num_images=5,\n",
    "    image_shape=(28,28)\n",
    ")    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "875bcfdc",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "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.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
