diff --git a/seminar3/.ipynb_checkpoints/mri_3DCNN-checkpoint.ipynb b/seminar3/.ipynb_checkpoints/mri_3DCNN-checkpoint.ipynb new file mode 100644 index 0000000..83c3384 --- /dev/null +++ b/seminar3/.ipynb_checkpoints/mri_3DCNN-checkpoint.ipynb @@ -0,0 +1,1002 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "accelerator": "GPU", + "colab": { + "name": "mri_3DCNN.ipynb", + "provenance": [], + "collapsed_sections": [], + "toc_visible": true, + "machine_shape": "hm" + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "URuxAJkkEjV0", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bHS8qClIqSdl", + "colab_type": "text" + }, + "source": [ + "## **MRI classification with 3D CNN**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gYI4bcYpptdM", + "colab_type": "text" + }, + "source": [ + "#### 1. Introduction\n", + "In this notebook we will explore simple 3D CNN classificationl model on `pytorch` from the Frontiers in Neuroscience paper: https://www.frontiersin.org/articles/10.3389/fnins.2019.00185/full. In the current notebook we follow [the paper](https://arxiv.org/pdf/2006.15969.pdf) on `3T` `T1w` MRI images from https://www.humanconnectome.org/. \n", + "\n", + "**Our goal will be to build a network for MEN and WOMEN brain classification, to explore gender influence on brain structure and find gender-specific biomarkers.**\n", + "\n", + "\n", + "*Proceeding with this Notebook you confirm your personal acess [to the data](https://www.humanconnectome.org/study/hcp-young-adult/document/1200-subjects-data-release). \n", + " And your agreement on data [terms and conditions](https://www.humanconnectome.org/study/hcp-young-adult/data-use-terms).*\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YqAayt8wtZ-m", + "colab_type": "text" + }, + "source": [ + "1. Importing needed libs\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "TbVC-fIYcwoA", + "colab": {} + }, + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import pandas as pd\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.utils.data as torch_data\n", + "import torch.nn.functional as F\n", + "from torchsummary import summary\n", + "import os\n", + "from sklearn.model_selection import train_test_split, StratifiedKFold\n", + "\n", + "\n", + "%matplotlib inline" + ], + "execution_count": 1, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tb4Hu77AuRte", + "colab_type": "text" + }, + "source": [ + "2. Mounting Google Drive to Collab Notebook. You should go with the link and enter your personal authorization code:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZXYXRCCIB2Ue", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "10b09fe9-7442-42d7-cdd9-e52b66dd7596" + }, + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/drive')" + ], + "execution_count": 2, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Mounted at /content/drive\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1IlGfuWsuot2", + "colab_type": "text" + }, + "source": [ + "3. Get the data. Add a shortcut to your Google Drive for `labels.npy` and `tensors.npy`. \n", + "\n", + "Shared link: https://drive.google.com/drive/folders/1Cq35zfhqJHlmhQjNlsDIeQ71ZsT2aghv?usp=sharing" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WBxqm43mKUCl", + "colab_type": "code", + "colab": {} + }, + "source": [ + "data_dir = '/content/drive/My Drive/Skoltech Neuroimaging/NeuroML2020/data/seminars/anat/'" + ], + "execution_count": 6, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5tJhdbkMKte1", + "colab_type": "text" + }, + "source": [ + "Let's watch the data. We will use `nilearn` package for the visualisation: \n", + "https://nilearn.github.io/modules/generated/nilearn.plotting.plot_anat.html#nilearn.plotting.plot_anat " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CRiEcgFIK5gZ", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "94cb16b6-fcd6-4d6a-fba1-a9e8b5131570" + }, + "source": [ + "!pip install --quiet --upgrade nilearn\n", + "import nilearn\n", + "from nilearn import plotting" + ], + "execution_count": 8, + "outputs": [ + { + "output_type": "stream", + "text": [ + "\u001b[K |████████████████████████████████| 2.5MB 2.5MB/s \n", + "\u001b[?25h" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jsQ_-1WsMd0C", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 235 + }, + "outputId": "9a272066-ac8e-44a3-f9d3-7d57e0788a84" + }, + "source": [ + "img = nilearn.image.load_img(data_dir +'100408.nii')\n", + "plotting.plot_anat(img)" + ], + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iR-yP8c-NanX", + "colab_type": "text" + }, + "source": [ + "Questions:\n", + "1. What is the size of image (file)?\n", + "2. That is the intensity distribution of voxels?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oHD0cZv9NmWg", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "a14bea50-ce47-4c51-b2ac-0703aa73a7d0" + }, + "source": [ + "img_array = nilearn.image.get_data(img)\n", + "img_array.shape" + ], + "execution_count": 10, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(260, 311, 260)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 10 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EMokM8qhKq_4", + "colab_type": "text" + }, + "source": [ + "#### 2. Defining training and target samples" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "Ng1IcCer9NSG", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "3b27c863-34b9-44b3-c775-3f37416e7f9f" + }, + "source": [ + "X, y = np.load(data_dir + 'tensors.npy'), \\\n", + "np.load(data_dir + 'labels.npy')\n", + "X = X[:, np.newaxis, :, :, :]\n", + "print(X.shape, y.shape)" + ], + "execution_count": 11, + "outputs": [ + { + "output_type": "stream", + "text": [ + "(1113, 1, 58, 70, 58) (1113,)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "G-in4TXqOuzY", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "cc475860-ba6f-43d5-f34a-c327fda09234" + }, + "source": [ + "sample_data = X[1,0,:,:,:]\n", + "X[1,0,:,:,:].shape" + ], + "execution_count": 12, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(58, 70, 58)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aVv2Rd0GY5YZ", + "colab_type": "text" + }, + "source": [ + "**From the sourse article:**\n", + "\n", + "[The original data were too large](https://www.frontiersin.org/articles/10.3389/fnins.2019.00185/full) to train the model and it would cause RESOURCE EXAUSTED problem while training due to the insufficient of GPU memory. The GPU we used in the experiment is NVIDIAN TITAN_XP with 12G memory each. To solve the problem, we scaled the size of FA image to [58 × 70 × 58]. This procedure may lead to a better classification result, since a smaller size of the input image can provide a larger receptive field to the CNN model. In order to perform the image scaling, “dipy” (http://nipy.org/dipy/) was used to read the .nii data of FA. Then “ndimage” in the SciPy (http://www.scipy.org) was used to reduce the size of the data. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "be_2ekP6PG2t", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 235 + }, + "outputId": "cf54fb05-5d9a-4105-8d9a-cddb15c6c5c1" + }, + "source": [ + "sample_img = nilearn.image.new_img_like(img, sample_data)\n", + "plotting.plot_anat(sample_img)" + ], + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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9vLLL6dtmqQ1lSidukaOHJna6GymTmcsaMFjPPLII8l0DZRSHC9atCi1MUWuprhl6mVt03hsrS3dXamJuXvIkCGYM2cO1q9fjyzLcjcc2Bugfs8992Dr1q3YuHEjrr322vRd79698fDDD2P16tXIsgznnHNOtbtvasxbb72Fbdu2pc+uXbvwz3/+M31/6qmnYvHixfj888+xePHilLfYGGPqjZpo0nv27MHjjz+OW2+9Ff/73/9afX/zzTdjzJgxGDlyJIYMGYL58+fj7bffxhNPPAFgbwL5WbNm4eGHH652100BGDt2bO7/q1atSnOhd+/emDNnDmbNmoU77rgDV111FebMmYMxY8Z0Wn3vjqBOYAxRGTx4cGpjUQJNBaoOMc8++yyA7ucEY4qHzlUt4sNt1YCJhlMx65cWmmH4Fuuab9iwIbc/HSMfe+yx1MZnQfvjJZ4OaNI/+9nP8Mgjj+TabrvtNsyaNWu/T7p582b86U9/yuUbVmbMmIFf//rX+OSTT7Bs2TLcdddduPLKKwHsXbe77bbb8N///tc/YHXI6NGj8eGHH2LChAkAgKFDh2Lz5s37bRH5v//7Pxx++OF49NFHAQDnnnsuDjjgAMyaNQs7d+7E7bffjoaGBpx33nmddg3GGFMt2tWk77//ftx888049NBDsXXrVjQ2NuJHP/oRLrjgAvzxj3/E5ZdfHu733nvv7ZeZccCAARg2bBhef/311Pb666/j4osv3udjmeKxatUqXH/99bj//vtxxhln4N5778V9992HZ599dr/m04wZM/Doo48myf2UU07BG2+8kfubN954A6ecckqyxFQbagPz589PbcxtrNr1vHnz0na9FKQ3xnQt7b6k33//fSxYsAA/+MEPcPfdd+P888/Hli1b8Morr+CVV17B1Vdf3akdYsydZsbZunVrckAoImr6Me1z991348ILL8SiRYuQZRkuuugiAMDVV1+9T/PpoIMOwiWXXJL2B/bOH507QPHnT1fgOWm6El06+jrLSDZnt0+HHMfuu+8+XHHFFQCAK664An//+987fIKzzz47OfhoOEklGMiuHoX9+/fPefQVjZkzZ2LmzJm17kZdcdddd2HcuHG4/fbb99tD83vf+x4++uijtH4L7J0/OneA4s+frsBz0pjuQ9bep6mpKfvoo4+yU045Jdu2bVs2YsSIDED2pz/9Kdu2bVv4eeutt9o9bmNjY5ZlWTZy5Mhc+/r167Np06al/99yyy3ZAw880Gr/lpaW7Jxzzmn3PP4U69O3b9/s3Xffze66665s3bp12cCBA/drPs2bNy+75ZZbcm3Tp0/PWlpacm1r1qzJvv3tb9f8uvXTq1evrFevXlljY2P61LpP/vjT2Z8777wzu/POO2vejzr/dOwP//znP2evv/569tRTT3XKiZuamrKDDz44y7IsO/7447Ompqb03a233po988wz2YABA7ITTjgh27BhQ+5Htk+fPllTU1PW0tKSTZ8+PbevP8X/3H333dns2bMzYO9D/OCDD+7zMYYPH57t2rUrGz16dK69d+/e2Zo1a7Jrrrkm69OnT3b11Vdna9asyXr37l3z69aPX9L+9ISPX9Kd8unYH5511llZlmXZlVde2SknjuB3ffr0ye65555s69at2fvvv59de+21uX1Xr17dat9ybdyfYn4uuuiinPbct2/fbMWKFdnll1++T8e54YYbsgULFoTfNTc3Z4sXL862b9+evfzyy1lzc3PNr9sff3rixy/pr/9p+P8b7TJixAgsW7YMQ4YM6XHre8YYY/adO++8EwBw1VVX1bgn9UuHHMcaGhpw3XXXYfbs2X5BG2OMMVWi3RCsgw8+GJs2bcLatWtx/vnnV6NPxhhjjEEHXtLbt2/vcTGmxhhjTBFwPWljjDGmoPglbYwxxhQUv6SNMaYAjBw5ElmW5cqw3nTTTa3+buDAgdi8eTOee+65GvTSVJualKo0xhgTM2DAgDYr/P3ud7/D0qVL0auXdayegO+yMcbsB5deemlO692xY0eu0llXMGXKFIwdOxb33ntvl57HFAe/pI0xZj946KGH0K9fP/Tr1w/Dhg3DqlWr8MADD+D666/Hxx9/XPHTHmvXrkVLSwv+8pe/4LDDDkvtvXr1wh/+8Af85Cc/wd4EjcVn+fLlrsjWCdQ87Zk//vjjT71+Ghoasn/961/ZHXfc8bWO07dv3+z000/PGhsbsyOPPDJ7+OGHs8cffzx9/9Of/jSdY8aMGdlzzz1X82v3pyqfmnfAH3/88aduP7/97W+zZ555JjvggAM6vM+IESNyVd6ivxk8eHCWZVl2yCGHZEOHDs1WrVqVct77Jd1zPnYcM8aY/eSHP/whLrvsMkycOBG7d+8GANx44434+c9/XnGffv36oaWlpd0kUTRp9+rVC5MmTcLQoUPx9ttvAwAOOuggHHTQQdi4cSOGDx+OPXv2dNIVmSJSc0nBH3/88afePs3NzdnmzZuzU089tVOON2nSpOz444/PGhoaskGDBmWzZ8/Onn766QzYWxlw8ODB6XPNNddkCxcuzAYPHlzzcfCnaz92HDPGmP3gO9/5DgYOHIjnn38+eXg/9thj+3280aNH4/HHH8e2bdvw1ltv4csvv8Rll10GANi5cyc2bdqUPlu3bsWuXbuwadOmzrocU1A6XKrSGGOMMdXFmrQxxhhTUPySNsYYYwqKX9LGGGNMQfFL2hhjjCkofkkbY4wxBcUvaWOMMaag+CVtjDHGFBS/pI0xxpiC4pe0McYYU1D8kjbGGGMKil/SxhhjTEHxS9oYY4wpKH5JG2OMMQXl/wECvy9cAjCijAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R9ObKK2YQW2s", + "colab_type": "text" + }, + "source": [ + "#### 3. Defining Data Set" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "hjalzY4ZylGC", + "colab": {} + }, + "source": [ + "class MriData(torch.utils.data.Dataset):\n", + " def __init__(self, X, y):\n", + " super(MriData, self).__init__()\n", + " self.X = torch.tensor(X, dtype=torch.float32)\n", + " self.y = torch.tensor(y).long()\n", + " \n", + " def __len__(self):\n", + " return self.X.shape[0]\n", + " \n", + " def __getitem__(self, idx):\n", + " return self.X[idx], self.y[idx]" + ], + "execution_count": 14, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8lv4i-TSQvcX", + "colab_type": "text" + }, + "source": [ + "#### 4. Defining the CNN model architecture\n", + "\n", + "[3D PCNN architecture](https://www.frontiersin.org/articles/10.3389/fnins.2019.00185/full)\n", + "![model](https://www.frontiersin.org/files/Articles/442577/fnins-13-00185-HTML/image_m/fnins-13-00185-g001.jpg)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cqFwgNpJHdDN", + "colab_type": "text" + }, + "source": [ + "At first check if we have GPU onborad:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mvbAGRRAHS63", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "371a6856-9f5c-4688-f210-6066f488abb4" + }, + "source": [ + " torch.cuda.is_available()" + ], + "execution_count": 18, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "True" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jX-W0Nv_HaLG", + "colab_type": "code", + "colab": {} + }, + "source": [ + "if torch.cuda.is_available():\n", + " device = torch.device(\"cuda\")\n", + "else:\n", + " device = torch.device(\"cpu\")" + ], + "execution_count": 19, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vvoEO3-oQxfV", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 485 + }, + "outputId": "30a6b67d-2c69-4db9-a725-1a518841f82d" + }, + "source": [ + "## Hidden layers 1, 2 and 3\n", + "hidden = lambda c_in, c_out: nn.Sequential(\n", + " nn.Conv3d(c_in, c_out, (3,3,3)), # Convolutional layer\n", + " nn.BatchNorm3d(c_out), # Batch Normalization layer\n", + " nn.ReLU(), # Activational layer\n", + " nn.MaxPool3d(2) # Pooling layer\n", + ")\n", + "\n", + "class MriNet(nn.Module):\n", + " def __init__(self, c):\n", + " super(MriNet, self).__init__()\n", + " self.hidden1 = hidden(1, c)\n", + " self.hidden2 = hidden(c, 2*c)\n", + " self.hidden3 = hidden(2*c, 4*c)\n", + " self.linear = nn.Linear(128*5*7*5, 2)\n", + " self.flatten = nn.Flatten()\n", + "\n", + " def forward(self, x):\n", + " x = self.hidden1(x)\n", + " x = self.hidden2(x)\n", + " x = self.hidden3(x)\n", + " x = self.flatten(x)\n", + " x = self.linear(x)\n", + " x = F.log_softmax(x, dim=1)\n", + " return x\n", + "\n", + "torch.manual_seed(1)\n", + "np.random.seed(1)\n", + "\n", + "c = 32\n", + "model = MriNet(c).to(device)\n", + "summary(model, (1, 58, 70, 58))" + ], + "execution_count": 20, + "outputs": [ + { + "output_type": "stream", + "text": [ + "----------------------------------------------------------------\n", + " Layer (type) Output Shape Param #\n", + "================================================================\n", + " Conv3d-1 [-1, 32, 56, 68, 56] 896\n", + " BatchNorm3d-2 [-1, 32, 56, 68, 56] 64\n", + " ReLU-3 [-1, 32, 56, 68, 56] 0\n", + " MaxPool3d-4 [-1, 32, 28, 34, 28] 0\n", + " Conv3d-5 [-1, 64, 26, 32, 26] 55,360\n", + " BatchNorm3d-6 [-1, 64, 26, 32, 26] 128\n", + " ReLU-7 [-1, 64, 26, 32, 26] 0\n", + " MaxPool3d-8 [-1, 64, 13, 16, 13] 0\n", + " Conv3d-9 [-1, 128, 11, 14, 11] 221,312\n", + " BatchNorm3d-10 [-1, 128, 11, 14, 11] 256\n", + " ReLU-11 [-1, 128, 11, 14, 11] 0\n", + " MaxPool3d-12 [-1, 128, 5, 7, 5] 0\n", + " Flatten-13 [-1, 22400] 0\n", + " Linear-14 [-1, 2] 44,802\n", + "================================================================\n", + "Total params: 322,818\n", + "Trainable params: 322,818\n", + "Non-trainable params: 0\n", + "----------------------------------------------------------------\n", + "Input size (MB): 0.90\n", + "Forward/backward pass size (MB): 201.01\n", + "Params size (MB): 1.23\n", + "Estimated Total Size (MB): 203.14\n", + "----------------------------------------------------------------\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "wUtTLI4ZwhDi" + }, + "source": [ + "#### 5. Training the model" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "yUZGw-ETwKA5", + "colab": {} + }, + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42) \n", + "#del X, y #deleting for freeing space on disc\n", + "\n", + "train_dataset = MriData(X_train, y_train)\n", + "test_dataset = MriData(X_test, y_test)\n", + "#del X_train, X_test, y_train, y_test #deleting for freeing space on disc" + ], + "execution_count": 16, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "BttsN8kG3YyG", + "colab": {} + }, + "source": [ + "train_dataset = MriData(X_train, y_train)\n", + "test_dataset = MriData(X_test, y_test)\n", + "train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=45, shuffle=True) #45 - recommended value for batchsize\n", + "val_loader = torch.utils.data.DataLoader(test_dataset, batch_size=28, shuffle=False) " + ], + "execution_count": 17, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "Ry5Deo3uYufS", + "colab": {} + }, + "source": [ + "CHECKPOINTS_DIR = data_dir +'/checkpoints'\n", + "\n", + "criterion = nn.NLLLoss().to(device)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)\n", + "scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[5, 15], gamma=0.1)" + ], + "execution_count": 22, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "InIC1EMOZRHs", + "colab": {} + }, + "source": [ + "# timing\n", + "from tqdm import tqdm\n", + "\n", + "def get_accuracy(net, data_loader):\n", + " net.eval()\n", + " correct = 0\n", + " for data, target in data_loader:\n", + " data = data.to(device)\n", + " target = target.to(device)\n", + "\n", + " out = net(data)\n", + " pred = out.data.max(1)[1] # get the index of the max log-probability\n", + " correct += pred.eq(target.data).cpu().sum()\n", + " del data, target\n", + " accuracy = 100. * correct / len(data_loader.dataset)\n", + " return accuracy.item()\n", + "\n", + "def get_loss(net, data_loader):\n", + " net.eval()\n", + " loss = 0 \n", + " for data, target in data_loader:\n", + " data = data.to(device)\n", + " target = target.to(device)\n", + "\n", + " out = net(data)\n", + " loss += criterion(out, target).item()*len(data)\n", + "\n", + " del data, target, out \n", + "\n", + " return loss / len(data_loader.dataset)\n", + "\n", + "\n", + "def train(epochs, net, criterion, optimizer, train_loader, val_loader, scheduler=None, verbose=True, save=False):\n", + " best_val_loss = 100_000\n", + " best_model = None\n", + " train_loss_list = []\n", + " val_loss_list = []\n", + " train_acc_list = []\n", + " val_acc_list = []\n", + "\n", + " train_loss_list.append(get_loss(net, train_loader))\n", + " val_loss_list.append(get_loss(net, val_loader))\n", + " train_acc_list.append(get_accuracy(net, train_loader))\n", + " val_acc_list.append(get_accuracy(net, val_loader))\n", + " if verbose:\n", + " print('Epoch {:02d}/{} || Loss: Train {:.4f} | Validation {:.4f}'.format(0, epochs, train_loss_list[-1], val_loss_list[-1]))\n", + "\n", + " net.to(device)\n", + " for epoch in tqdm(range(1, epochs+1)):\n", + " net.train()\n", + " for X, y in train_loader:\n", + " # Perform one step of minibatch stochastic gradient descent\n", + " X, y = X.to(device), y.to(device)\n", + " optimizer.zero_grad()\n", + " out = net(X)\n", + " loss = criterion(out, y)\n", + " loss.backward()\n", + " optimizer.step()\n", + " del X, y, out, loss #freeing gpu space\n", + " \n", + " \n", + " # define NN evaluation, i.e. turn off dropouts, batchnorms, etc.\n", + " net.eval()\n", + " for X, y in val_loader:\n", + " # Compute the validation loss\n", + " X, y = X.to(device), y.to(device)\n", + " out = net(X)\n", + " del X, y, out #freeing gpu space\n", + " \n", + " if scheduler is not None:\n", + " scheduler.step()\n", + " \n", + " \n", + " train_loss_list.append(get_loss(net, train_loader))\n", + " val_loss_list.append(get_loss(net, val_loader))\n", + " train_acc_list.append(get_accuracy(net, train_loader))\n", + " val_acc_list.append(get_accuracy(net, val_loader))\n", + "\n", + " if save and val_loss_list[-1] < best_val_loss:\n", + " torch.save(net.state_dict(), CHECKPOINTS_DIR+'best_model')\n", + " freq = 1\n", + " if verbose and epoch%freq==0:\n", + " print('Epoch {:02d}/{} || Loss: Train {:.4f} | Validation {:.4f}'.format(epoch, epochs, train_loss_list[-1], val_loss_list[-1]))\n", + " \n", + " return train_loss_list, val_loss_list, train_acc_list, val_acc_list " + ], + "execution_count": 23, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2UznBfFtRtQS", + "colab_type": "text" + }, + "source": [ + "##### Training first **20 epochs**:\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "ETQqxi4CeFgm", + "colab": {} + }, + "source": [ + "# training will take ~3 min\n", + "torch.manual_seed(1)\n", + "np.random.seed(1)\n", + "EPOCHS = 20\n", + "\n", + "train_loss_list, val_loss_list, train_acc_list, val_acc_list = train(EPOCHS, model, criterion, optimizer, train_loader, val_loader, scheduler=scheduler, save=False) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "AgbxRc1RsPEl", + "colab": {} + }, + "source": [ + "plt.figure(figsize=(20,8))\n", + "\n", + "plt.subplot(1, 2, 1)\n", + "plt.title('Loss history', fontsize=18)\n", + "plt.plot(train_loss_list[1:], label='Train')\n", + "plt.plot(val_loss_list[1:], label='Validation')\n", + "plt.xlabel('# of epoch', fontsize=16)\n", + "plt.ylabel('Loss', fontsize=16)\n", + "plt.legend(fontsize=16)\n", + "plt.grid()\n", + "\n", + "plt.subplot(1, 2, 2)\n", + "plt.title('Accuracy history', fontsize=18)\n", + "plt.plot(train_acc_list, label='Train')\n", + "plt.plot(val_acc_list, label='Validation')\n", + "plt.xlabel('# of epoch', fontsize=16)\n", + "plt.ylabel('Accuracy', fontsize=16)\n", + "plt.legend(fontsize=16)\n", + "plt.grid()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "OT1c6OQmwvRV" + }, + "source": [ + "##### K-Fold model validation:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Sody3ciZTAcy", + "colab_type": "text" + }, + "source": [ + "Questions:\n", + "1. What is the purpose of K-Fold in that experiment setting?\n", + "2. Can we afford cross-validation in regular DL?" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "kwwuFwsH2Ifa", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 121 + }, + "outputId": "c0bc9da8-5ea6-4ef8-fdcd-8a4ca7735109" + }, + "source": [ + "# execute for ~ 5 min\n", + "skf = StratifiedKFold(n_splits=3, shuffle=True, random_state=42)\n", + "cross_vall_acc_list = []\n", + "j = 0\n", + "\n", + "for train_index, test_index in skf.split(X, y):\n", + " print('Doing {} split'.format(j))\n", + " j += 1\n", + "\n", + " X_train, X_test = X[train_index], X[test_index]\n", + " y_train, y_test = y[train_index], y[test_index]\n", + " train_dataset = MriData(X_train, y_train)\n", + " test_dataset = MriData(X_test, y_test)\n", + " train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=45, shuffle=True) #45 - recommended value for batchsize\n", + " val_loader = torch.utils.data.DataLoader(test_dataset, batch_size=28, shuffle=False) \n", + " \n", + " torch.manual_seed(1)\n", + " np.random.seed(1)\n", + "\n", + " c = 32\n", + " model = MriNet(c).to(device)\n", + " criterion = nn.NLLLoss().to(device)\n", + " optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)\n", + " scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[5, 15], gamma=0.1)\n", + "\n", + " train(EPOCHS, model, criterion, optimizer, train_loader, val_loader, scheduler=scheduler, save=False, verbose=False) \n", + " cross_vall_acc_list.append(get_accuracy(model, val_loader))\n" + ], + "execution_count": 26, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Doing 0 split\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "100%|██████████| 20/20 [03:20<00:00, 10.04s/it]\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "Doing 1 split\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "100%|██████████| 20/20 [03:20<00:00, 10.03s/it]\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "Doing 2 split\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "100%|██████████| 20/20 [03:20<00:00, 10.03s/it]\n" + ], + "name": "stderr" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "RKbs0w6HwynW", + "colab": {} + }, + "source": [ + "print('Average cross-validation accuracy (3-folds):', sum(cross_vall_acc_list)/len(cross_vall_acc_list))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "QLX_sxmGsgI2" + }, + "source": [ + "#### Model save\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "bSiiJhZZsf3u", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "26b6ea06-13c7-436b-b4cb-a8243e34cef8" + }, + "source": [ + "# Training model on whole data and saving it\n", + "dataset = MriData(X, y)\n", + "loader = torch.utils.data.DataLoader(dataset, batch_size=45, shuffle=True) #45 - recommended value for batchsize\n", + "\n", + "torch.manual_seed(1)\n", + "np.random.seed(1)\n", + "\n", + "model = MriNet(c).to(device)\n", + "criterion = nn.NLLLoss().to(device)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)\n", + "scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[5, 15], gamma=0.1)\n", + "\n", + "train(EPOCHS, model, criterion, optimizer, loader, loader, scheduler=scheduler, save=True, verbose=False) \n", + "pass" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " 25%|██▌ | 5/20 [01:31<04:33, 18.23s/it]" + ], + "name": "stderr" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xmw3OAG7Z9p4", + "colab_type": "text" + }, + "source": [ + "## What else?\n", + "\n", + "MRI classifcation model interpretation \n", + "\n", + "Visit: https://github.com/kondratevakate/InterpretableNeuroDL\n", + "\n", + "Meaningfull perturbations on MEN brains prediction:\n", + "![img](https://github.com/kondratevakate/InterpretableNeuroDL/raw/master/image/man.png)" + ] + } + ] +} \ No newline at end of file diff --git a/seminar3/mri_3DCNN.ipynb b/seminar3/mri_3DCNN.ipynb index 83c3384..9ce6672 100644 --- a/seminar3/mri_3DCNN.ipynb +++ b/seminar3/mri_3DCNN.ipynb @@ -1,1002 +1,1002 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "accelerator": "GPU", + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "URuxAJkkEjV0" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "bHS8qClIqSdl" + }, + "source": [ + "## **MRI classification with 3D CNN**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "gYI4bcYpptdM" + }, + "source": [ + "#### 1. Introduction\n", + "In this notebook we will explore simple 3D CNN classificationl model on `pytorch` from the Frontiers in Neuroscience paper: https://www.frontiersin.org/articles/10.3389/fnins.2019.00185/full. In the current notebook we follow [the paper](https://arxiv.org/pdf/2006.15969.pdf) on `3T` `T1w` MRI images from https://www.humanconnectome.org/. \n", + "\n", + "**Our goal will be to build a network for MEN and WOMEN brain classification, to explore gender influence on brain structure and find gender-specific biomarkers.**\n", + "\n", + "\n", + "*Proceeding with this Notebook you confirm your personal acess [to the data](https://www.humanconnectome.org/study/hcp-young-adult/document/1200-subjects-data-release). \n", + " And your agreement on data [terms and conditions](https://www.humanconnectome.org/study/hcp-young-adult/data-use-terms).*\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "YqAayt8wtZ-m" + }, + "source": [ + "1. Importing needed libs\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "TbVC-fIYcwoA" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import pandas as pd\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.utils.data as torch_data\n", + "import torch.nn.functional as F\n", + "from torchsummary import summary\n", + "import os\n", + "from sklearn.model_selection import train_test_split, StratifiedKFold\n", + "\n", + "\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Tb4Hu77AuRte" + }, + "source": [ + "2. Mounting Google Drive to Collab Notebook. You should go with the link and enter your personal authorization code:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { "colab": { - "name": "mri_3DCNN.ipynb", - "provenance": [], - "collapsed_sections": [], - "toc_visible": true, - "machine_shape": "hm" - }, - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.4" + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "colab_type": "code", + "id": "ZXYXRCCIB2Ue", + "outputId": "10b09fe9-7442-42d7-cdd9-e52b66dd7596" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Mounted at /content/drive\n" + ] } + ], + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/drive')" + ] }, - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "URuxAJkkEjV0", - "colab_type": "text" - }, - "source": [ - "\"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "bHS8qClIqSdl", - "colab_type": "text" - }, - "source": [ - "## **MRI classification with 3D CNN**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "gYI4bcYpptdM", - "colab_type": "text" - }, - "source": [ - "#### 1. Introduction\n", - "In this notebook we will explore simple 3D CNN classificationl model on `pytorch` from the Frontiers in Neuroscience paper: https://www.frontiersin.org/articles/10.3389/fnins.2019.00185/full. In the current notebook we follow [the paper](https://arxiv.org/pdf/2006.15969.pdf) on `3T` `T1w` MRI images from https://www.humanconnectome.org/. \n", - "\n", - "**Our goal will be to build a network for MEN and WOMEN brain classification, to explore gender influence on brain structure and find gender-specific biomarkers.**\n", - "\n", - "\n", - "*Proceeding with this Notebook you confirm your personal acess [to the data](https://www.humanconnectome.org/study/hcp-young-adult/document/1200-subjects-data-release). \n", - " And your agreement on data [terms and conditions](https://www.humanconnectome.org/study/hcp-young-adult/data-use-terms).*\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "YqAayt8wtZ-m", - "colab_type": "text" - }, - "source": [ - "1. Importing needed libs\n" - ] - }, - { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "TbVC-fIYcwoA", - "colab": {} - }, - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import torch\n", - "import torch.nn as nn\n", - "import torch.utils.data as torch_data\n", - "import torch.nn.functional as F\n", - "from torchsummary import summary\n", - "import os\n", - "from sklearn.model_selection import train_test_split, StratifiedKFold\n", - "\n", - "\n", - "%matplotlib inline" - ], - "execution_count": 1, - "outputs": [] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "Tb4Hu77AuRte", - "colab_type": "text" - }, - "source": [ - "2. Mounting Google Drive to Collab Notebook. You should go with the link and enter your personal authorization code:" - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "ZXYXRCCIB2Ue", - "colab_type": "code", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "outputId": "10b09fe9-7442-42d7-cdd9-e52b66dd7596" - }, - "source": [ - "from google.colab import drive\n", - "drive.mount('/content/drive')" - ], - "execution_count": 2, - "outputs": [ - { - "output_type": "stream", - "text": [ - "Mounted at /content/drive\n" - ], - "name": "stdout" - } - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "1IlGfuWsuot2", - "colab_type": "text" - }, - "source": [ - "3. Get the data. Add a shortcut to your Google Drive for `labels.npy` and `tensors.npy`. \n", - "\n", - "Shared link: https://drive.google.com/drive/folders/1Cq35zfhqJHlmhQjNlsDIeQ71ZsT2aghv?usp=sharing" - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "WBxqm43mKUCl", - "colab_type": "code", - "colab": {} - }, - "source": [ - "data_dir = '/content/drive/My Drive/Skoltech Neuroimaging/NeuroML2020/data/seminars/anat/'" - ], - "execution_count": 6, - "outputs": [] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "5tJhdbkMKte1", - "colab_type": "text" - }, - "source": [ - "Let's watch the data. We will use `nilearn` package for the visualisation: \n", - "https://nilearn.github.io/modules/generated/nilearn.plotting.plot_anat.html#nilearn.plotting.plot_anat " - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "CRiEcgFIK5gZ", - "colab_type": "code", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "outputId": "94cb16b6-fcd6-4d6a-fba1-a9e8b5131570" - }, - "source": [ - "!pip install --quiet --upgrade nilearn\n", - "import nilearn\n", - "from nilearn import plotting" - ], - "execution_count": 8, - "outputs": [ - { - "output_type": "stream", - "text": [ - "\u001b[K |████████████████████████████████| 2.5MB 2.5MB/s \n", - "\u001b[?25h" - ], - "name": "stdout" - } - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "jsQ_-1WsMd0C", - "colab_type": "code", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 235 - }, - "outputId": "9a272066-ac8e-44a3-f9d3-7d57e0788a84" - }, - "source": [ - "img = nilearn.image.load_img(data_dir +'100408.nii')\n", - "plotting.plot_anat(img)" - ], - "execution_count": 9, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ] - }, - "metadata": { - "tags": [] - }, - "execution_count": 9 - }, - { - "output_type": "display_data", - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "tags": [] - } - } - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "iR-yP8c-NanX", - "colab_type": "text" - }, - "source": [ - "Questions:\n", - "1. What is the size of image (file)?\n", - "2. That is the intensity distribution of voxels?" - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "oHD0cZv9NmWg", - "colab_type": "code", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "outputId": "a14bea50-ce47-4c51-b2ac-0703aa73a7d0" - }, - "source": [ - "img_array = nilearn.image.get_data(img)\n", - "img_array.shape" - ], - "execution_count": 10, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "(260, 311, 260)" - ] - }, - "metadata": { - "tags": [] - }, - "execution_count": 10 - } - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "EMokM8qhKq_4", - "colab_type": "text" - }, - "source": [ - "#### 2. Defining training and target samples" - ] - }, - { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "Ng1IcCer9NSG", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "outputId": "3b27c863-34b9-44b3-c775-3f37416e7f9f" - }, - "source": [ - "X, y = np.load(data_dir + 'tensors.npy'), \\\n", - "np.load(data_dir + 'labels.npy')\n", - "X = X[:, np.newaxis, :, :, :]\n", - "print(X.shape, y.shape)" - ], - "execution_count": 11, - "outputs": [ - { - "output_type": "stream", - "text": [ - "(1113, 1, 58, 70, 58) (1113,)\n" - ], - "name": "stdout" - } - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "G-in4TXqOuzY", - "colab_type": "code", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "outputId": "cc475860-ba6f-43d5-f34a-c327fda09234" - }, - "source": [ - "sample_data = X[1,0,:,:,:]\n", - "X[1,0,:,:,:].shape" - ], - "execution_count": 12, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "(58, 70, 58)" - ] - }, - "metadata": { - "tags": [] - }, - "execution_count": 12 - } - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "aVv2Rd0GY5YZ", - "colab_type": "text" - }, - "source": [ - "**From the sourse article:**\n", - "\n", - "[The original data were too large](https://www.frontiersin.org/articles/10.3389/fnins.2019.00185/full) to train the model and it would cause RESOURCE EXAUSTED problem while training due to the insufficient of GPU memory. The GPU we used in the experiment is NVIDIAN TITAN_XP with 12G memory each. To solve the problem, we scaled the size of FA image to [58 × 70 × 58]. This procedure may lead to a better classification result, since a smaller size of the input image can provide a larger receptive field to the CNN model. In order to perform the image scaling, “dipy” (http://nipy.org/dipy/) was used to read the .nii data of FA. Then “ndimage” in the SciPy (http://www.scipy.org) was used to reduce the size of the data. " - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "be_2ekP6PG2t", - "colab_type": "code", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 235 - }, - "outputId": "cf54fb05-5d9a-4105-8d9a-cddb15c6c5c1" - }, - "source": [ - "sample_img = nilearn.image.new_img_like(img, sample_data)\n", - "plotting.plot_anat(sample_img)" - ], - "execution_count": 13, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ] - }, - "metadata": { - "tags": [] - }, - "execution_count": 13 - }, - { - "output_type": "display_data", - "data": { - "image/png": "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9vLLL6dtmqQ1lSidukaOHJna6GymTmcsaMFjPPLII8l0DZRSHC9atCi1MUWuprhl6mVt03hsrS3dXamJuXvIkCGYM2cO1q9fjyzLcjcc2Bugfs8992Dr1q3YuHEjrr322vRd79698fDDD2P16tXIsgznnHNOtbtvasxbb72Fbdu2pc+uXbvwz3/+M31/6qmnYvHixfj888+xePHilLfYGGPqjZpo0nv27MHjjz+OW2+9Ff/73/9afX/zzTdjzJgxGDlyJIYMGYL58+fj7bffxhNPPAFgbwL5WbNm4eGHH652100BGDt2bO7/q1atSnOhd+/emDNnDmbNmoU77rgDV111FebMmYMxY8Z0Wn3vjqBOYAxRGTx4cGpjUQJNBaoOMc8++yyA7ucEY4qHzlUt4sNt1YCJhlMx65cWmmH4Fuuab9iwIbc/HSMfe+yx1MZnQfvjJZ4OaNI/+9nP8Mgjj+TabrvtNsyaNWu/T7p582b86U9/yuUbVmbMmIFf//rX+OSTT7Bs2TLcdddduPLKKwHsXbe77bbb8N///tc/YHXI6NGj8eGHH2LChAkAgKFDh2Lz5s37bRH5v//7Pxx++OF49NFHAQDnnnsuDjjgAMyaNQs7d+7E7bffjoaGBpx33nmddg3GGFMt2tWk77//ftx888049NBDsXXrVjQ2NuJHP/oRLrjgAvzxj3/E5ZdfHu733nvv7ZeZccCAARg2bBhef/311Pb666/j4osv3udjmeKxatUqXH/99bj//vtxxhln4N5778V9992HZ599dr/m04wZM/Doo48myf2UU07BG2+8kfubN954A6ecckqyxFQbagPz589PbcxtrNr1vHnz0na9FKQ3xnQt7b6k33//fSxYsAA/+MEPcPfdd+P888/Hli1b8Morr+CVV17B1Vdf3akdYsydZsbZunVrckAoImr6Me1z991348ILL8SiRYuQZRkuuugiAMDVV1+9T/PpoIMOwiWXXJL2B/bOH507QPHnT1fgOWm6El06+jrLSDZnt0+HHMfuu+8+XHHFFQCAK664An//+987fIKzzz47OfhoOEklGMiuHoX9+/fPefQVjZkzZ2LmzJm17kZdcdddd2HcuHG4/fbb99tD83vf+x4++uijtH4L7J0/OneA4s+frsBz0pjuQ9bep6mpKfvoo4+yU045Jdu2bVs2YsSIDED2pz/9Kdu2bVv4eeutt9o9bmNjY5ZlWTZy5Mhc+/r167Np06al/99yyy3ZAw880Gr/lpaW7Jxzzmn3PP4U69O3b9/s3Xffze66665s3bp12cCBA/drPs2bNy+75ZZbcm3Tp0/PWlpacm1r1qzJvv3tb9f8uvXTq1evrFevXlljY2P61LpP/vjT2Z8777wzu/POO2vejzr/dOwP//znP2evv/569tRTT3XKiZuamrKDDz44y7IsO/7447Ompqb03a233po988wz2YABA7ITTjgh27BhQ+5Htk+fPllTU1PW0tKSTZ8+PbevP8X/3H333dns2bMzYO9D/OCDD+7zMYYPH57t2rUrGz16dK69d+/e2Zo1a7Jrrrkm69OnT3b11Vdna9asyXr37l3z69aPX9L+9ISPX9Kd8unYH5511llZlmXZlVde2SknjuB3ffr0ye65555s69at2fvvv59de+21uX1Xr17dat9ybdyfYn4uuuiinPbct2/fbMWKFdnll1++T8e54YYbsgULFoTfNTc3Z4sXL862b9+evfzyy1lzc3PNr9sff3rixy/pr/9p+P8b7TJixAgsW7YMQ4YM6XHre8YYY/adO++8EwBw1VVX1bgn9UuHHMcaGhpw3XXXYfbs2X5BG2OMMVWi3RCsgw8+GJs2bcLatWtx/vnnV6NPxhhjjEEHXtLbt2/vcTGmxhhjTBFwPWljjDGmoPglbYwxxhQUv6SNMaYAjBw5ElmW5cqw3nTTTa3+buDAgdi8eTOee+65GvTSVJualKo0xhgTM2DAgDYr/P3ud7/D0qVL0auXdayegO+yMcbsB5deemlO692xY0eu0llXMGXKFIwdOxb33ntvl57HFAe/pI0xZj946KGH0K9fP/Tr1w/Dhg3DqlWr8MADD+D666/Hxx9/XPHTHmvXrkVLSwv+8pe/4LDDDkvtvXr1wh/+8Af85Cc/wd4EjcVn+fLlrsjWCdQ87Zk//vjjT71+Ghoasn/961/ZHXfc8bWO07dv3+z000/PGhsbsyOPPDJ7+OGHs8cffzx9/9Of/jSdY8aMGdlzzz1X82v3pyqfmnfAH3/88aduP7/97W+zZ555JjvggAM6vM+IESNyVd6ivxk8eHCWZVl2yCGHZEOHDs1WrVqVct77Jd1zPnYcM8aY/eSHP/whLrvsMkycOBG7d+8GANx44434+c9/XnGffv36oaWlpd0kUTRp9+rVC5MmTcLQoUPx9ttvAwAOOuggHHTQQdi4cSOGDx+OPXv2dNIVmSJSc0nBH3/88afePs3NzdnmzZuzU089tVOON2nSpOz444/PGhoaskGDBmWzZ8/Onn766QzYWxlw8ODB6XPNNddkCxcuzAYPHlzzcfCnaz92HDPGmP3gO9/5DgYOHIjnn38+eXg/9thj+3280aNH4/HHH8e2bdvw1ltv4csvv8Rll10GANi5cyc2bdqUPlu3bsWuXbuwadOmzrocU1A6XKrSGGOMMdXFmrQxxhhTUPySNsYYYwqKX9LGGGNMQfFL2hhjjCkofkkbY4wxBcUvaWOMMaag+CVtjDHGFBS/pI0xxpiC4pe0McYYU1D8kjbGGGMKil/SxhhjTEHxS9oYY4wpKH5JG2OMMQXl/wECvy9cAjCijAAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "tags": [] - } - } - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "R9ObKK2YQW2s", - "colab_type": "text" - }, - "source": [ - "#### 3. Defining Data Set" - ] - }, - { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "hjalzY4ZylGC", - "colab": {} - }, - "source": [ - "class MriData(torch.utils.data.Dataset):\n", - " def __init__(self, X, y):\n", - " super(MriData, self).__init__()\n", - " self.X = torch.tensor(X, dtype=torch.float32)\n", - " self.y = torch.tensor(y).long()\n", - " \n", - " def __len__(self):\n", - " return self.X.shape[0]\n", - " \n", - " def __getitem__(self, idx):\n", - " return self.X[idx], self.y[idx]" - ], - "execution_count": 14, - "outputs": [] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "8lv4i-TSQvcX", - "colab_type": "text" - }, - "source": [ - "#### 4. Defining the CNN model architecture\n", - "\n", - "[3D PCNN architecture](https://www.frontiersin.org/articles/10.3389/fnins.2019.00185/full)\n", - "![model](https://www.frontiersin.org/files/Articles/442577/fnins-13-00185-HTML/image_m/fnins-13-00185-g001.jpg)" + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "1IlGfuWsuot2" + }, + "source": [ + "3. Get the data. Add a shortcut to your Google Drive for `labels.npy` and `tensors.npy`. \n", + "\n", + "Shared link: https://drive.google.com/drive/folders/1Cq35zfhqJHlmhQjNlsDIeQ71ZsT2aghv?usp=sharing" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "WBxqm43mKUCl" + }, + "outputs": [], + "source": [ + "data_dir = '/content/drive/My Drive/Skoltech Neuroimaging/NeuroML2020/data/seminars/anat/'" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "5tJhdbkMKte1" + }, + "source": [ + "Let's watch the data. We will use `nilearn` package for the visualisation: \n", + "https://nilearn.github.io/modules/generated/nilearn.plotting.plot_anat.html#nilearn.plotting.plot_anat " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "colab_type": "code", + "id": "CRiEcgFIK5gZ", + "outputId": "94cb16b6-fcd6-4d6a-fba1-a9e8b5131570" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[K |████████████████████████████████| 2.5MB 2.5MB/s \n", + "\u001b[?25h" + ] + } + ], + "source": [ + "!pip install --quiet --upgrade nilearn\n", + "import nilearn\n", + "from nilearn import plotting" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 235 + }, + "colab_type": "code", + "id": "jsQ_-1WsMd0C", + "outputId": "9a272066-ac8e-44a3-f9d3-7d57e0788a84" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "cqFwgNpJHdDN", - "colab_type": "text" - }, - "source": [ - "At first check if we have GPU onborad:" + }, + "execution_count": 9, + "metadata": { + "tags": [] + }, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" ] - }, - { - "cell_type": "code", - "metadata": { - "id": "mvbAGRRAHS63", - "colab_type": "code", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "outputId": "371a6856-9f5c-4688-f210-6066f488abb4" - }, - "source": [ - " torch.cuda.is_available()" - ], - "execution_count": 18, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "True" - ] - }, - "metadata": { - "tags": [] - }, - "execution_count": 18 - } + }, + "metadata": { + "tags": [] + }, + "output_type": "display_data" + } + ], + "source": [ + "img = nilearn.image.load_img(data_dir +'100408.nii')\n", + "plotting.plot_anat(img)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "iR-yP8c-NanX" + }, + "source": [ + "Questions:\n", + "1. What is the size of image (file)?\n", + "2. That is the intensity distribution of voxels?" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "colab_type": "code", + "id": "oHD0cZv9NmWg", + "outputId": "a14bea50-ce47-4c51-b2ac-0703aa73a7d0" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(260, 311, 260)" ] - }, - { - "cell_type": "code", - "metadata": { - "id": "jX-W0Nv_HaLG", - "colab_type": "code", - "colab": {} - }, - "source": [ - "if torch.cuda.is_available():\n", - " device = torch.device(\"cuda\")\n", - "else:\n", - " device = torch.device(\"cpu\")" - ], - "execution_count": 19, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "id": "vvoEO3-oQxfV", - "colab_type": "code", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 485 - }, - "outputId": "30a6b67d-2c69-4db9-a725-1a518841f82d" - }, - "source": [ - "## Hidden layers 1, 2 and 3\n", - "hidden = lambda c_in, c_out: nn.Sequential(\n", - " nn.Conv3d(c_in, c_out, (3,3,3)), # Convolutional layer\n", - " nn.BatchNorm3d(c_out), # Batch Normalization layer\n", - " nn.ReLU(), # Activational layer\n", - " nn.MaxPool3d(2) # Pooling layer\n", - ")\n", - "\n", - "class MriNet(nn.Module):\n", - " def __init__(self, c):\n", - " super(MriNet, self).__init__()\n", - " self.hidden1 = hidden(1, c)\n", - " self.hidden2 = hidden(c, 2*c)\n", - " self.hidden3 = hidden(2*c, 4*c)\n", - " self.linear = nn.Linear(128*5*7*5, 2)\n", - " self.flatten = nn.Flatten()\n", - "\n", - " def forward(self, x):\n", - " x = self.hidden1(x)\n", - " x = self.hidden2(x)\n", - " x = self.hidden3(x)\n", - " x = self.flatten(x)\n", - " x = self.linear(x)\n", - " x = F.log_softmax(x, dim=1)\n", - " return x\n", - "\n", - "torch.manual_seed(1)\n", - "np.random.seed(1)\n", - "\n", - "c = 32\n", - "model = MriNet(c).to(device)\n", - "summary(model, (1, 58, 70, 58))" - ], - "execution_count": 20, - "outputs": [ - { - "output_type": "stream", - "text": [ - "----------------------------------------------------------------\n", - " Layer (type) Output Shape Param #\n", - "================================================================\n", - " Conv3d-1 [-1, 32, 56, 68, 56] 896\n", - " BatchNorm3d-2 [-1, 32, 56, 68, 56] 64\n", - " ReLU-3 [-1, 32, 56, 68, 56] 0\n", - " MaxPool3d-4 [-1, 32, 28, 34, 28] 0\n", - " Conv3d-5 [-1, 64, 26, 32, 26] 55,360\n", - " BatchNorm3d-6 [-1, 64, 26, 32, 26] 128\n", - " ReLU-7 [-1, 64, 26, 32, 26] 0\n", - " MaxPool3d-8 [-1, 64, 13, 16, 13] 0\n", - " Conv3d-9 [-1, 128, 11, 14, 11] 221,312\n", - " BatchNorm3d-10 [-1, 128, 11, 14, 11] 256\n", - " ReLU-11 [-1, 128, 11, 14, 11] 0\n", - " MaxPool3d-12 [-1, 128, 5, 7, 5] 0\n", - " Flatten-13 [-1, 22400] 0\n", - " Linear-14 [-1, 2] 44,802\n", - "================================================================\n", - "Total params: 322,818\n", - "Trainable params: 322,818\n", - "Non-trainable params: 0\n", - "----------------------------------------------------------------\n", - "Input size (MB): 0.90\n", - "Forward/backward pass size (MB): 201.01\n", - "Params size (MB): 1.23\n", - "Estimated Total Size (MB): 203.14\n", - "----------------------------------------------------------------\n" - ], - "name": "stdout" - } + }, + "execution_count": 10, + "metadata": { + "tags": [] + }, + "output_type": "execute_result" + } + ], + "source": [ + "img_array = nilearn.image.get_data(img)\n", + "img_array.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "EMokM8qhKq_4" + }, + "source": [ + "#### 2. Defining training and target samples" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "colab_type": "code", + "id": "Ng1IcCer9NSG", + "outputId": "3b27c863-34b9-44b3-c775-3f37416e7f9f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1113, 1, 58, 70, 58) (1113,)\n" + ] + } + ], + "source": [ + "X, y = np.load(data_dir + 'tensors.npy'), \\\n", + "np.load(data_dir + 'labels.npy')\n", + "X = X[:, np.newaxis, :, :, :]\n", + "print(X.shape, y.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "colab_type": "code", + "id": "G-in4TXqOuzY", + "outputId": "cc475860-ba6f-43d5-f34a-c327fda09234" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(58, 70, 58)" ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "wUtTLI4ZwhDi" - }, - "source": [ - "#### 5. Training the model" + }, + "execution_count": 12, + "metadata": { + "tags": [] + }, + "output_type": "execute_result" + } + ], + "source": [ + "sample_data = X[1,0,:,:,:]\n", + "X[1,0,:,:,:].shape" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "aVv2Rd0GY5YZ" + }, + "source": [ + "**From the sourse article:**\n", + "\n", + "[The original data were too large](https://www.frontiersin.org/articles/10.3389/fnins.2019.00185/full) to train the model and it would cause RESOURCE EXAUSTED problem while training due to the insufficient of GPU memory. The GPU we used in the experiment is NVIDIAN TITAN_XP with 12G memory each. To solve the problem, we scaled the size of FA image to [58 × 70 × 58]. This procedure may lead to a better classification result, since a smaller size of the input image can provide a larger receptive field to the CNN model. In order to perform the image scaling, “dipy” (http://nipy.org/dipy/) was used to read the .nii data of FA. Then “ndimage” in the SciPy (http://www.scipy.org) was used to reduce the size of the data. " + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 235 + }, + "colab_type": "code", + "id": "be_2ekP6PG2t", + "outputId": "cf54fb05-5d9a-4105-8d9a-cddb15c6c5c1" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" ] - }, - { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "yUZGw-ETwKA5", - "colab": {} - }, - "source": [ - "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42) \n", - "#del X, y #deleting for freeing space on disc\n", - "\n", - "train_dataset = MriData(X_train, y_train)\n", - "test_dataset = MriData(X_test, y_test)\n", - "#del X_train, X_test, y_train, y_test #deleting for freeing space on disc" - ], - "execution_count": 16, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "BttsN8kG3YyG", - "colab": {} - }, - "source": [ - "train_dataset = MriData(X_train, y_train)\n", - "test_dataset = MriData(X_test, y_test)\n", - "train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=45, shuffle=True) #45 - recommended value for batchsize\n", - "val_loader = torch.utils.data.DataLoader(test_dataset, batch_size=28, shuffle=False) " - ], - "execution_count": 17, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "Ry5Deo3uYufS", - "colab": {} - }, - "source": [ - "CHECKPOINTS_DIR = data_dir +'/checkpoints'\n", - "\n", - "criterion = nn.NLLLoss().to(device)\n", - "optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)\n", - "scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[5, 15], gamma=0.1)" - ], - "execution_count": 22, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "InIC1EMOZRHs", - "colab": {} - }, - "source": [ - "# timing\n", - "from tqdm import tqdm\n", - "\n", - "def get_accuracy(net, data_loader):\n", - " net.eval()\n", - " correct = 0\n", - " for data, target in data_loader:\n", - " data = data.to(device)\n", - " target = target.to(device)\n", - "\n", - " out = net(data)\n", - " pred = out.data.max(1)[1] # get the index of the max log-probability\n", - " correct += pred.eq(target.data).cpu().sum()\n", - " del data, target\n", - " accuracy = 100. * correct / len(data_loader.dataset)\n", - " return accuracy.item()\n", - "\n", - "def get_loss(net, data_loader):\n", - " net.eval()\n", - " loss = 0 \n", - " for data, target in data_loader:\n", - " data = data.to(device)\n", - " target = target.to(device)\n", - "\n", - " out = net(data)\n", - " loss += criterion(out, target).item()*len(data)\n", - "\n", - " del data, target, out \n", - "\n", - " return loss / len(data_loader.dataset)\n", - "\n", - "\n", - "def train(epochs, net, criterion, optimizer, train_loader, val_loader, scheduler=None, verbose=True, save=False):\n", - " best_val_loss = 100_000\n", - " best_model = None\n", - " train_loss_list = []\n", - " val_loss_list = []\n", - " train_acc_list = []\n", - " val_acc_list = []\n", - "\n", - " train_loss_list.append(get_loss(net, train_loader))\n", - " val_loss_list.append(get_loss(net, val_loader))\n", - " train_acc_list.append(get_accuracy(net, train_loader))\n", - " val_acc_list.append(get_accuracy(net, val_loader))\n", - " if verbose:\n", - " print('Epoch {:02d}/{} || Loss: Train {:.4f} | Validation {:.4f}'.format(0, epochs, train_loss_list[-1], val_loss_list[-1]))\n", - "\n", - " net.to(device)\n", - " for epoch in tqdm(range(1, epochs+1)):\n", - " net.train()\n", - " for X, y in train_loader:\n", - " # Perform one step of minibatch stochastic gradient descent\n", - " X, y = X.to(device), y.to(device)\n", - " optimizer.zero_grad()\n", - " out = net(X)\n", - " loss = criterion(out, y)\n", - " loss.backward()\n", - " optimizer.step()\n", - " del X, y, out, loss #freeing gpu space\n", - " \n", - " \n", - " # define NN evaluation, i.e. turn off dropouts, batchnorms, etc.\n", - " net.eval()\n", - " for X, y in val_loader:\n", - " # Compute the validation loss\n", - " X, y = X.to(device), y.to(device)\n", - " out = net(X)\n", - " del X, y, out #freeing gpu space\n", - " \n", - " if scheduler is not None:\n", - " scheduler.step()\n", - " \n", - " \n", - " train_loss_list.append(get_loss(net, train_loader))\n", - " val_loss_list.append(get_loss(net, val_loader))\n", - " train_acc_list.append(get_accuracy(net, train_loader))\n", - " val_acc_list.append(get_accuracy(net, val_loader))\n", - "\n", - " if save and val_loss_list[-1] < best_val_loss:\n", - " torch.save(net.state_dict(), CHECKPOINTS_DIR+'best_model')\n", - " freq = 1\n", - " if verbose and epoch%freq==0:\n", - " print('Epoch {:02d}/{} || Loss: Train {:.4f} | Validation {:.4f}'.format(epoch, epochs, train_loss_list[-1], val_loss_list[-1]))\n", - " \n", - " return train_loss_list, val_loss_list, train_acc_list, val_acc_list " - ], - "execution_count": 23, - "outputs": [] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "2UznBfFtRtQS", - "colab_type": "text" - }, - "source": [ - "##### Training first **20 epochs**:\n" + }, + "execution_count": 13, + "metadata": { + "tags": [] + }, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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9vLLL6dtmqQ1lSidukaOHJna6GymTmcsaMFjPPLII8l0DZRSHC9atCi1MUWuprhl6mVt03hsrS3dXamJuXvIkCGYM2cO1q9fjyzLcjcc2Bugfs8992Dr1q3YuHEjrr322vRd79698fDDD2P16tXIsgznnHNOtbtvasxbb72Fbdu2pc+uXbvwz3/+M31/6qmnYvHixfj888+xePHilLfYGGPqjZpo0nv27MHjjz+OW2+9Ff/73/9afX/zzTdjzJgxGDlyJIYMGYL58+fj7bffxhNPPAFgbwL5WbNm4eGHH652100BGDt2bO7/q1atSnOhd+/emDNnDmbNmoU77rgDV111FebMmYMxY8Z0Wn3vjqBOYAxRGTx4cGpjUQJNBaoOMc8++yyA7ucEY4qHzlUt4sNt1YCJhlMx65cWmmH4Fuuab9iwIbc/HSMfe+yx1MZnQfvjJZ4OaNI/+9nP8Mgjj+TabrvtNsyaNWu/T7p582b86U9/yuUbVmbMmIFf//rX+OSTT7Bs2TLcdddduPLKKwHsXbe77bbb8N///tc/YHXI6NGj8eGHH2LChAkAgKFDh2Lz5s37bRH5v//7Pxx++OF49NFHAQDnnnsuDjjgAMyaNQs7d+7E7bffjoaGBpx33nmddg3GGFMt2tWk77//ftx888049NBDsXXrVjQ2NuJHP/oRLrjgAvzxj3/E5ZdfHu733nvv7ZeZccCAARg2bBhef/311Pb666/j4osv3udjmeKxatUqXH/99bj//vtxxhln4N5778V9992HZ599dr/m04wZM/Doo48myf2UU07BG2+8kfubN954A6ecckqyxFQbagPz589PbcxtrNr1vHnz0na9FKQ3xnQt7b6k33//fSxYsAA/+MEPcPfdd+P888/Hli1b8Morr+CVV17B1Vdf3akdYsydZsbZunVrckAoImr6Me1z991348ILL8SiRYuQZRkuuugiAMDVV1+9T/PpoIMOwiWXXJL2B/bOH507QPHnT1fgOWm6El06+jrLSDZnt0+HHMfuu+8+XHHFFQCAK664An//+987fIKzzz47OfhoOEklGMiuHoX9+/fPefQVjZkzZ2LmzJm17kZdcdddd2HcuHG4/fbb99tD83vf+x4++uijtH4L7J0/OneA4s+frsBz0pjuQ9bep6mpKfvoo4+yU045Jdu2bVs2YsSIDED2pz/9Kdu2bVv4eeutt9o9bmNjY5ZlWTZy5Mhc+/r167Np06al/99yyy3ZAw880Gr/lpaW7Jxzzmn3PP4U69O3b9/s3Xffze66665s3bp12cCBA/drPs2bNy+75ZZbcm3Tp0/PWlpacm1r1qzJvv3tb9f8uvXTq1evrFevXlljY2P61LpP/vjT2Z8777wzu/POO2vejzr/dOwP//znP2evv/569tRTT3XKiZuamrKDDz44y7IsO/7447Ompqb03a233po988wz2YABA7ITTjgh27BhQ+5Htk+fPllTU1PW0tKSTZ8+PbevP8X/3H333dns2bMzYO9D/OCDD+7zMYYPH57t2rUrGz16dK69d+/e2Zo1a7Jrrrkm69OnT3b11Vdna9asyXr37l3z69aPX9L+9ISPX9Kd8unYH5511llZlmXZlVde2SknjuB3ffr0ye65555s69at2fvvv59de+21uX1Xr17dat9ybdyfYn4uuuiinPbct2/fbMWKFdnll1++T8e54YYbsgULFoTfNTc3Z4sXL862b9+evfzyy1lzc3PNr9sff3rixy/pr/9p+P8b7TJixAgsW7YMQ4YM6XHre8YYY/adO++8EwBw1VVX1bgn9UuHHMcaGhpw3XXXYfbs2X5BG2OMMVWi3RCsgw8+GJs2bcLatWtx/vnnV6NPxhhjjEEHXtLbt2/vcTGmxhhjTBFwPWljjDGmoPglbYwxxhQUv6SNMaYAjBw5ElmW5cqw3nTTTa3+buDAgdi8eTOee+65GvTSVJualKo0xhgTM2DAgDYr/P3ud7/D0qVL0auXdayegO+yMcbsB5deemlO692xY0eu0llXMGXKFIwdOxb33ntvl57HFAe/pI0xZj946KGH0K9fP/Tr1w/Dhg3DqlWr8MADD+D666/Hxx9/XPHTHmvXrkVLSwv+8pe/4LDDDkvtvXr1wh/+8Af85Cc/wd4EjcVn+fLlrsjWCdQ87Zk//vjjT71+Ghoasn/961/ZHXfc8bWO07dv3+z000/PGhsbsyOPPDJ7+OGHs8cffzx9/9Of/jSdY8aMGdlzzz1X82v3pyqfmnfAH3/88aduP7/97W+zZ555JjvggAM6vM+IESNyVd6ivxk8eHCWZVl2yCGHZEOHDs1WrVqVct77Jd1zPnYcM8aY/eSHP/whLrvsMkycOBG7d+8GANx44434+c9/XnGffv36oaWlpd0kUTRp9+rVC5MmTcLQoUPx9ttvAwAOOuggHHTQQdi4cSOGDx+OPXv2dNIVmSJSc0nBH3/88afePs3NzdnmzZuzU089tVOON2nSpOz444/PGhoaskGDBmWzZ8/Onn766QzYWxlw8ODB6XPNNddkCxcuzAYPHlzzcfCnaz92HDPGmP3gO9/5DgYOHIjnn38+eXg/9thj+3280aNH4/HHH8e2bdvw1ltv4csvv8Rll10GANi5cyc2bdqUPlu3bsWuXbuwadOmzrocU1A6XKrSGGOMMdXFmrQxxhhTUPySNsYYYwqKX9LGGGNMQfFL2hhjjCkofkkbY4wxBcUvaWOMMaag+CVtjDHGFBS/pI0xxpiC4pe0McYYU1D8kjbGGGMKil/SxhhjTEHxS9oYY4wpKH5JG2OMMQXl/wECvy9cAjCijAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" ] - }, - { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "ETQqxi4CeFgm", - "colab": {} - }, - "source": [ - "# training will take ~3 min\n", - "torch.manual_seed(1)\n", - "np.random.seed(1)\n", - "EPOCHS = 20\n", - "\n", - "train_loss_list, val_loss_list, train_acc_list, val_acc_list = train(EPOCHS, model, criterion, optimizer, train_loader, val_loader, scheduler=scheduler, save=False) " - ], - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "AgbxRc1RsPEl", - "colab": {} - }, - "source": [ - "plt.figure(figsize=(20,8))\n", - "\n", - "plt.subplot(1, 2, 1)\n", - "plt.title('Loss history', fontsize=18)\n", - "plt.plot(train_loss_list[1:], label='Train')\n", - "plt.plot(val_loss_list[1:], label='Validation')\n", - "plt.xlabel('# of epoch', fontsize=16)\n", - "plt.ylabel('Loss', fontsize=16)\n", - "plt.legend(fontsize=16)\n", - "plt.grid()\n", - "\n", - "plt.subplot(1, 2, 2)\n", - "plt.title('Accuracy history', fontsize=18)\n", - "plt.plot(train_acc_list, label='Train')\n", - "plt.plot(val_acc_list, label='Validation')\n", - "plt.xlabel('# of epoch', fontsize=16)\n", - "plt.ylabel('Accuracy', fontsize=16)\n", - "plt.legend(fontsize=16)\n", - "plt.grid()" - ], - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "OT1c6OQmwvRV" - }, - "source": [ - "##### K-Fold model validation:" + }, + "metadata": { + "tags": [] + }, + "output_type": "display_data" + } + ], + "source": [ + "sample_img = nilearn.image.new_img_like(img, sample_data)\n", + "plotting.plot_anat(sample_img)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "R9ObKK2YQW2s" + }, + "source": [ + "#### 3. Defining Data Set" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "hjalzY4ZylGC" + }, + "outputs": [], + "source": [ + "class MriData(torch.utils.data.Dataset):\n", + " def __init__(self, X, y):\n", + " super(MriData, self).__init__()\n", + " self.X = torch.tensor(X, dtype=torch.float32)\n", + " self.y = torch.tensor(y).long()\n", + " \n", + " def __len__(self):\n", + " return self.X.shape[0]\n", + " \n", + " def __getitem__(self, idx):\n", + " return self.X[idx], self.y[idx]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "8lv4i-TSQvcX" + }, + "source": [ + "#### 4. Defining the CNN model architecture\n", + "\n", + "[3D PCNN architecture](https://www.frontiersin.org/articles/10.3389/fnins.2019.00185/full)\n", + "![model](https://www.frontiersin.org/files/Articles/442577/fnins-13-00185-HTML/image_m/fnins-13-00185-g001.jpg)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "cqFwgNpJHdDN" + }, + "source": [ + "At first check if we have GPU onborad:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "colab_type": "code", + "id": "mvbAGRRAHS63", + "outputId": "371a6856-9f5c-4688-f210-6066f488abb4" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" ] + }, + "execution_count": 18, + "metadata": { + "tags": [] + }, + "output_type": "execute_result" + } + ], + "source": [ + " torch.cuda.is_available()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "jX-W0Nv_HaLG" + }, + "outputs": [], + "source": [ + "if torch.cuda.is_available():\n", + " device = torch.device(\"cuda\")\n", + "else:\n", + " device = torch.device(\"cpu\")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 485 + }, + "colab_type": "code", + "id": "vvoEO3-oQxfV", + "outputId": "30a6b67d-2c69-4db9-a725-1a518841f82d" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "----------------------------------------------------------------\n", + " Layer (type) Output Shape Param #\n", + "================================================================\n", + " Conv3d-1 [-1, 32, 56, 68, 56] 896\n", + " BatchNorm3d-2 [-1, 32, 56, 68, 56] 64\n", + " ReLU-3 [-1, 32, 56, 68, 56] 0\n", + " MaxPool3d-4 [-1, 32, 28, 34, 28] 0\n", + " Conv3d-5 [-1, 64, 26, 32, 26] 55,360\n", + " BatchNorm3d-6 [-1, 64, 26, 32, 26] 128\n", + " ReLU-7 [-1, 64, 26, 32, 26] 0\n", + " MaxPool3d-8 [-1, 64, 13, 16, 13] 0\n", + " Conv3d-9 [-1, 128, 11, 14, 11] 221,312\n", + " BatchNorm3d-10 [-1, 128, 11, 14, 11] 256\n", + " ReLU-11 [-1, 128, 11, 14, 11] 0\n", + " MaxPool3d-12 [-1, 128, 5, 7, 5] 0\n", + " Flatten-13 [-1, 22400] 0\n", + " Linear-14 [-1, 2] 44,802\n", + "================================================================\n", + "Total params: 322,818\n", + "Trainable params: 322,818\n", + "Non-trainable params: 0\n", + "----------------------------------------------------------------\n", + "Input size (MB): 0.90\n", + "Forward/backward pass size (MB): 201.01\n", + "Params size (MB): 1.23\n", + "Estimated Total Size (MB): 203.14\n", + "----------------------------------------------------------------\n" + ] + } + ], + "source": [ + "## Hidden layers 1, 2 and 3\n", + "hidden = lambda c_in, c_out: nn.Sequential(\n", + " nn.Conv3d(c_in, c_out, (3,3,3)), # Convolutional layer\n", + " nn.BatchNorm3d(c_out), # Batch Normalization layer\n", + " nn.ReLU(), # Activational layer\n", + " nn.MaxPool3d(2) # Pooling layer\n", + ")\n", + "\n", + "class MriNet(nn.Module):\n", + " def __init__(self, c):\n", + " super(MriNet, self).__init__()\n", + " self.hidden1 = hidden(1, c)\n", + " self.hidden2 = hidden(c, 2*c)\n", + " self.hidden3 = hidden(2*c, 4*c)\n", + " self.linear = nn.Linear(128*5*7*5, 2)\n", + " self.flatten = nn.Flatten()\n", + "\n", + " def forward(self, x):\n", + " x = self.hidden1(x)\n", + " x = self.hidden2(x)\n", + " x = self.hidden3(x)\n", + " x = self.flatten(x)\n", + " x = self.linear(x)\n", + " x = F.log_softmax(x, dim=1)\n", + " return x\n", + "\n", + "torch.manual_seed(1)\n", + "np.random.seed(1)\n", + "\n", + "c = 32\n", + "model = MriNet(c).to(device)\n", + "summary(model, (1, 58, 70, 58))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "wUtTLI4ZwhDi" + }, + "source": [ + "#### 5. Training the model" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "yUZGw-ETwKA5" + }, + "outputs": [], + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42) \n", + "#del X, y #deleting for freeing space on disc\n", + "\n", + "train_dataset = MriData(X_train, y_train)\n", + "test_dataset = MriData(X_test, y_test)\n", + "#del X_train, X_test, y_train, y_test #deleting for freeing space on disc" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "BttsN8kG3YyG" + }, + "outputs": [], + "source": [ + "train_dataset = MriData(X_train, y_train)\n", + "test_dataset = MriData(X_test, y_test)\n", + "train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=45, shuffle=True) #45 - recommended value for batchsize\n", + "val_loader = torch.utils.data.DataLoader(test_dataset, batch_size=28, shuffle=False) " + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "Ry5Deo3uYufS" + }, + "outputs": [], + "source": [ + "CHECKPOINTS_DIR = data_dir +'/checkpoints'\n", + "\n", + "criterion = nn.NLLLoss().to(device)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)\n", + "scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[5, 15], gamma=0.1)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "InIC1EMOZRHs" + }, + "outputs": [], + "source": [ + "# timing\n", + "from tqdm import tqdm\n", + "\n", + "def get_accuracy(net, data_loader):\n", + " net.eval()\n", + " correct = 0\n", + " for data, target in data_loader:\n", + " data = data.to(device)\n", + " target = target.to(device)\n", + "\n", + " out = net(data)\n", + " pred = out.data.max(1)[1] # get the index of the max log-probability\n", + " correct += pred.eq(target.data).cpu().sum()\n", + " del data, target\n", + " accuracy = 100. * correct / len(data_loader.dataset)\n", + " return accuracy.item()\n", + "\n", + "def get_loss(net, data_loader):\n", + " net.eval()\n", + " loss = 0 \n", + " for data, target in data_loader:\n", + " data = data.to(device)\n", + " target = target.to(device)\n", + "\n", + " out = net(data)\n", + " loss += criterion(out, target).item()*len(data)\n", + "\n", + " del data, target, out \n", + "\n", + " return loss / len(data_loader.dataset)\n", + "\n", + "\n", + "def train(epochs, net, criterion, optimizer, train_loader, val_loader, scheduler=None, verbose=True, save=False):\n", + " best_val_loss = 100_000\n", + " best_model = None\n", + " train_loss_list = []\n", + " val_loss_list = []\n", + " train_acc_list = []\n", + " val_acc_list = []\n", + "\n", + " train_loss_list.append(get_loss(net, train_loader))\n", + " val_loss_list.append(get_loss(net, val_loader))\n", + " train_acc_list.append(get_accuracy(net, train_loader))\n", + " val_acc_list.append(get_accuracy(net, val_loader))\n", + " if verbose:\n", + " print('Epoch {:02d}/{} || Loss: Train {:.4f} | Validation {:.4f}'.format(0, epochs, train_loss_list[-1], val_loss_list[-1]))\n", + "\n", + " net.to(device)\n", + " for epoch in tqdm(range(1, epochs+1)):\n", + " net.train()\n", + " for X, y in train_loader:\n", + " # Perform one step of minibatch stochastic gradient descent\n", + " X, y = X.to(device), y.to(device)\n", + " optimizer.zero_grad()\n", + " out = net(X)\n", + " loss = criterion(out, y)\n", + " loss.backward()\n", + " optimizer.step()\n", + " del X, y, out, loss #freeing gpu space\n", + " \n", + " \n", + " # define NN evaluation, i.e. turn off dropouts, batchnorms, etc.\n", + " net.eval()\n", + " for X, y in val_loader:\n", + " # Compute the validation loss\n", + " X, y = X.to(device), y.to(device)\n", + " out = net(X)\n", + " del X, y, out #freeing gpu space\n", + " \n", + " if scheduler is not None:\n", + " scheduler.step()\n", + " \n", + " \n", + " train_loss_list.append(get_loss(net, train_loader))\n", + " val_loss_list.append(get_loss(net, val_loader))\n", + " train_acc_list.append(get_accuracy(net, train_loader))\n", + " val_acc_list.append(get_accuracy(net, val_loader))\n", + "\n", + " if save and val_loss_list[-1] < best_val_loss:\n", + " torch.save(net.state_dict(), CHECKPOINTS_DIR+'best_model')\n", + " freq = 1\n", + " if verbose and epoch%freq==0:\n", + " print('Epoch {:02d}/{} || Loss: Train {:.4f} | Validation {:.4f}'.format(epoch, epochs, train_loss_list[-1], val_loss_list[-1]))\n", + " \n", + " return train_loss_list, val_loss_list, train_acc_list, val_acc_list " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "2UznBfFtRtQS" + }, + "source": [ + "##### Training first **20 epochs**:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "ETQqxi4CeFgm" + }, + "outputs": [], + "source": [ + "# training will take ~3 min\n", + "torch.manual_seed(1)\n", + "np.random.seed(1)\n", + "EPOCHS = 20\n", + "\n", + "train_loss_list, val_loss_list, train_acc_list, val_acc_list = train(EPOCHS, model, criterion, optimizer, train_loader, val_loader, scheduler=scheduler, save=False) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "AgbxRc1RsPEl" + }, + "outputs": [], + "source": [ + "plt.figure(figsize=(20,8))\n", + "\n", + "plt.subplot(1, 2, 1)\n", + "plt.title('Loss history', fontsize=18)\n", + "plt.plot(train_loss_list[1:], label='Train')\n", + "plt.plot(val_loss_list[1:], label='Validation')\n", + "plt.xlabel('# of epoch', fontsize=16)\n", + "plt.ylabel('Loss', fontsize=16)\n", + "plt.legend(fontsize=16)\n", + "plt.grid()\n", + "\n", + "plt.subplot(1, 2, 2)\n", + "plt.title('Accuracy history', fontsize=18)\n", + "plt.plot(train_acc_list, label='Train')\n", + "plt.plot(val_acc_list, label='Validation')\n", + "plt.xlabel('# of epoch', fontsize=16)\n", + "plt.ylabel('Accuracy', fontsize=16)\n", + "plt.legend(fontsize=16)\n", + "plt.grid()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "OT1c6OQmwvRV" + }, + "source": [ + "##### K-Fold model validation:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Sody3ciZTAcy" + }, + "source": [ + "Questions:\n", + "1. What is the purpose of K-Fold in that experiment setting?\n", + "2. Can we afford cross-validation in regular DL?" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 121 }, + "colab_type": "code", + "id": "kwwuFwsH2Ifa", + "outputId": "c0bc9da8-5ea6-4ef8-fdcd-8a4ca7735109" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "Sody3ciZTAcy", - "colab_type": "text" - }, - "source": [ - "Questions:\n", - "1. What is the purpose of K-Fold in that experiment setting?\n", - "2. Can we afford cross-validation in regular DL?" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Doing 0 split\n" + ] }, { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "kwwuFwsH2Ifa", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 121 - }, - "outputId": "c0bc9da8-5ea6-4ef8-fdcd-8a4ca7735109" - }, - "source": [ - "# execute for ~ 5 min\n", - "skf = StratifiedKFold(n_splits=3, shuffle=True, random_state=42)\n", - "cross_vall_acc_list = []\n", - "j = 0\n", - "\n", - "for train_index, test_index in skf.split(X, y):\n", - " print('Doing {} split'.format(j))\n", - " j += 1\n", - "\n", - " X_train, X_test = X[train_index], X[test_index]\n", - " y_train, y_test = y[train_index], y[test_index]\n", - " train_dataset = MriData(X_train, y_train)\n", - " test_dataset = MriData(X_test, y_test)\n", - " train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=45, shuffle=True) #45 - recommended value for batchsize\n", - " val_loader = torch.utils.data.DataLoader(test_dataset, batch_size=28, shuffle=False) \n", - " \n", - " torch.manual_seed(1)\n", - " np.random.seed(1)\n", - "\n", - " c = 32\n", - " model = MriNet(c).to(device)\n", - " criterion = nn.NLLLoss().to(device)\n", - " optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)\n", - " scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[5, 15], gamma=0.1)\n", - "\n", - " train(EPOCHS, model, criterion, optimizer, train_loader, val_loader, scheduler=scheduler, save=False, verbose=False) \n", - " cross_vall_acc_list.append(get_accuracy(model, val_loader))\n" - ], - "execution_count": 26, - "outputs": [ - { - "output_type": "stream", - "text": [ - "Doing 0 split\n" - ], - "name": "stdout" - }, - { - "output_type": "stream", - "text": [ - "100%|██████████| 20/20 [03:20<00:00, 10.04s/it]\n" - ], - "name": "stderr" - }, - { - "output_type": "stream", - "text": [ - "Doing 1 split\n" - ], - "name": "stdout" - }, - { - "output_type": "stream", - "text": [ - "100%|██████████| 20/20 [03:20<00:00, 10.03s/it]\n" - ], - "name": "stderr" - }, - { - "output_type": "stream", - "text": [ - "Doing 2 split\n" - ], - "name": "stdout" - }, - { - "output_type": "stream", - "text": [ - "100%|██████████| 20/20 [03:20<00:00, 10.03s/it]\n" - ], - "name": "stderr" - } - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 20/20 [03:20<00:00, 10.04s/it]\n" + ] }, { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "RKbs0w6HwynW", - "colab": {} - }, - "source": [ - "print('Average cross-validation accuracy (3-folds):', sum(cross_vall_acc_list)/len(cross_vall_acc_list))" - ], - "execution_count": null, - "outputs": [] + "name": "stdout", + "output_type": "stream", + "text": [ + "Doing 1 split\n" + ] }, { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "QLX_sxmGsgI2" - }, - "source": [ - "#### Model save\n" - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 20/20 [03:20<00:00, 10.03s/it]\n" + ] }, { - "cell_type": "code", - "metadata": { - "colab_type": "code", - "id": "bSiiJhZZsf3u", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "outputId": "26b6ea06-13c7-436b-b4cb-a8243e34cef8" - }, - "source": [ - "# Training model on whole data and saving it\n", - "dataset = MriData(X, y)\n", - "loader = torch.utils.data.DataLoader(dataset, batch_size=45, shuffle=True) #45 - recommended value for batchsize\n", - "\n", - "torch.manual_seed(1)\n", - "np.random.seed(1)\n", - "\n", - "model = MriNet(c).to(device)\n", - "criterion = nn.NLLLoss().to(device)\n", - "optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)\n", - "scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[5, 15], gamma=0.1)\n", - "\n", - "train(EPOCHS, model, criterion, optimizer, loader, loader, scheduler=scheduler, save=True, verbose=False) \n", - "pass" - ], - "execution_count": null, - "outputs": [ - { - "output_type": "stream", - "text": [ - " 25%|██▌ | 5/20 [01:31<04:33, 18.23s/it]" - ], - "name": "stderr" - } - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Doing 2 split\n" + ] }, { - "cell_type": "markdown", - "metadata": { - "id": "Xmw3OAG7Z9p4", - "colab_type": "text" - }, - "source": [ - "## What else?\n", - "\n", - "MRI classifcation model interpretation \n", - "\n", - "Visit: https://github.com/kondratevakate/InterpretableNeuroDL\n", - "\n", - "Meaningfull perturbations on MEN brains prediction:\n", - "![img](https://github.com/kondratevakate/InterpretableNeuroDL/raw/master/image/man.png)" - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 20/20 [03:20<00:00, 10.03s/it]\n" + ] } - ] -} \ No newline at end of file + ], + "source": [ + "# execute for ~ 5 min\n", + "skf = StratifiedKFold(n_splits=3, shuffle=True, random_state=42)\n", + "cross_vall_acc_list = []\n", + "j = 0\n", + "\n", + "for train_index, test_index in skf.split(X, y):\n", + " print('Doing {} split'.format(j))\n", + " j += 1\n", + "\n", + " X_train, X_test = X[train_index], X[test_index]\n", + " y_train, y_test = y[train_index], y[test_index]\n", + " train_dataset = MriData(X_train, y_train)\n", + " test_dataset = MriData(X_test, y_test)\n", + " train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=45, shuffle=True) #45 - recommended value for batchsize\n", + " val_loader = torch.utils.data.DataLoader(test_dataset, batch_size=28, shuffle=False) \n", + " \n", + " torch.manual_seed(1)\n", + " np.random.seed(1)\n", + "\n", + " c = 32\n", + " model = MriNet(c).to(device)\n", + " criterion = nn.NLLLoss().to(device)\n", + " optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)\n", + " scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[5, 15], gamma=0.1)\n", + "\n", + " train(EPOCHS, model, criterion, optimizer, train_loader, val_loader, scheduler=scheduler, save=False, verbose=False) \n", + " cross_vall_acc_list.append(get_accuracy(model, val_loader))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "RKbs0w6HwynW" + }, + "outputs": [], + "source": [ + "print('Average cross-validation accuracy (3-folds):', sum(cross_vall_acc_list)/len(cross_vall_acc_list))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "QLX_sxmGsgI2" + }, + "source": [ + "#### Model save\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "colab_type": "code", + "id": "bSiiJhZZsf3u", + "outputId": "26b6ea06-13c7-436b-b4cb-a8243e34cef8" + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + " 25%|██▌ | 5/20 [01:31<04:33, 18.23s/it]" + ] + } + ], + "source": [ + "# Training model on whole data and saving it\n", + "dataset = MriData(X, y)\n", + "loader = torch.utils.data.DataLoader(dataset, batch_size=45, shuffle=True) #45 - recommended value for batchsize\n", + "\n", + "torch.manual_seed(1)\n", + "np.random.seed(1)\n", + "\n", + "model = MriNet(c).to(device)\n", + "criterion = nn.NLLLoss().to(device)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)\n", + "scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[5, 15], gamma=0.1)\n", + "\n", + "train(EPOCHS, model, criterion, optimizer, loader, loader, scheduler=scheduler, save=True, verbose=False) \n", + "pass" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Xmw3OAG7Z9p4" + }, + "source": [ + "## What else?\n", + "\n", + "MRI classifcation model interpretation \n", + "\n", + "Visit: https://github.com/kondratevakate/InterpretableNeuroDL\n", + "\n", + "Meaningfull perturbations on MEN brains prediction:\n", + "![img](https://github.com/kondratevakate/InterpretableNeuroDL/raw/master/image/man.png)" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "machine_shape": "hm", + "name": "mri_3DCNN.ipynb", + "provenance": [], + "toc_visible": true + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/seminar6/seminar6_part1_ROI_time_series.ipynb b/seminar6/seminar6_part1_ROI_time_series.ipynb new file mode 100644 index 0000000..32cebe4 --- /dev/null +++ b/seminar6/seminar6_part1_ROI_time_series.ipynb @@ -0,0 +1,1401 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + }, + "colab": { + "name": "seminar6_part1_ROI_time_series.ipynb", + "provenance": [], + "collapsed_sections": [ + "hqZksnfwt34o" + ] + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "TZIZlv5Hs2e-" + }, + "source": [ + "\"Open\n", + "\n", + "# **Seminar 6: Deep Learning for fMRI**\n", + "\n", + "## **Classification of ROI time series**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t6ojrwUYmCXH" + }, + "source": [ + "#### Introduction\n", + "In this notebook we will work with time series for brain region of interest (ROIs) obtained from fMRI.\n", + "\n", + "**We will train a network for detection of Autistm Spectrum Disorder (ASD) based on the ROI time series data of the patient.**\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PPx5Ba3ks2fA" + }, + "source": [ + "import os\n", + "import time\n", + "from tqdm import tqdm\n", + "import nibabel as nib\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from IPython.display import clear_output\n", + "\n", + "from sklearn.preprocessing import LabelEncoder\n", + "from sklearn.model_selection import StratifiedKFold, train_test_split\n", + "from sklearn.metrics import roc_auc_score\n", + "\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "import torch.utils.data as data\n", + "import torchvision\n", + "import torchvision.transforms as transforms" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7MjR5PKZJpsm", + "outputId": "a0270cbd-acb6-4d95-d057-80e6ede3744c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 373 + } + }, + "source": [ + "# check if gpu is available\n", + "!nvidia-smi" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fri Oct 2 09:38:32 2020 \n", + "+-----------------------------------------------------------------------------+\n", + "| NVIDIA-SMI 455.23.05 Driver Version: 418.67 CUDA Version: 10.1 |\n", + "|-------------------------------+----------------------+----------------------+\n", + "| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |\n", + "| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |\n", + "| | | MIG M. |\n", + "|===============================+======================+======================|\n", + "| 0 Tesla V100-SXM2... Off | 00000000:00:04.0 Off | 0 |\n", + "| N/A 35C P0 23W / 300W | 0MiB / 16130MiB | 0% Default |\n", + "| | | ERR! |\n", + "+-------------------------------+----------------------+----------------------+\n", + " \n", + "+-----------------------------------------------------------------------------+\n", + "| Processes: |\n", + "| GPU GI CI PID Type Process name GPU Memory |\n", + "| ID ID Usage |\n", + "|=============================================================================|\n", + "| No running processes found |\n", + "+-----------------------------------------------------------------------------+\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OpRdaVYgJtfI", + "outputId": "b7df6521-9a79-4a2f-8ece-08c09abc0c6a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "use_cuda = torch.cuda.is_available()\n", + "print(\"Torch version:\", torch.__version__)\n", + "if use_cuda:\n", + " print(\"Using GPU\")\n", + "else:\n", + " print(\"Not using GPU\")\n", + "device = 0" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Torch version: 1.6.0+cu101\n", + "Using GPU\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tet0P_HVm5vN" + }, + "source": [ + "Mounting Google Drive to Collab Notebook. You should go with the link and enter your personal authorization code:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mZkNPQnzvCHM", + "outputId": "ebda7124-02d7-46ee-ad45-d765f9f5cb5d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/drive')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Mounted at /content/drive\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_UuUV9s8nDUK" + }, + "source": [ + "Get the data. Add a shortcut to your Google Drive.\n", + "\n", + "Shared link: https://drive.google.com/drive/folders/1_63qnHOCUEzOUmUWhcmTXulmQMmJglwT?usp=sharing" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hv4_SZyhqCzi" + }, + "source": [ + "Here we have time series data of more than **800** participants. Around half of them have ASD, the others are healthy. The diagnosis is labelled in **\"DX_GROUP\"** column.\n", + "\n", + "You may also see that data collection is composed of smaller datasets provided from several different medical centers and research institutes (see the **\"SOURCE\"** column)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VN6gWzYzn_QR", + "outputId": "dd168723-59bb-402a-b6e5-b11ed1a4a6b8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 568 + } + }, + "source": [ + "folder_path = '/content/drive/My Drive/NeuroML/func_ABIDE/abide_ts'\n", + "targets_path = '/content/drive/My Drive/NeuroML/func_ABIDE/ABIDE1CPAC_targets.csv'\n", + "\n", + "# look at the target distribution\n", + "targets_df = pd.read_csv(targets_path)\n", + "display(targets_df.head())\n", + "display(targets_df[\"DX_GROUP\"].value_counts())\n", + "display(targets_df[\"SOURCE\"].value_counts())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
SITE_IDSUB_IDDX_GROUPDSM_IV_TRAGE_AT_SCANSEXHANDEDNESS_CATEGORYHANDEDNESS_SCORESFIQVIQPIQFIQ_TEST_TYPEVIQ_TEST_TYPEPIQ_TEST_TYPEADI_R_SOCIAL_TOTAL_AADI_R_VERBAL_TOTAL_BVADI_RRB_TOTAL_CADI_R_ONSET_TOTAL_DADI_R_RSRCH_RELIABLEADOS_MODULEADOS_TOTALADOS_COMMADOS_SOCIALADOS_STEREO_BEHAVADOS_RSRCH_RELIABLEADOS_GOTHAM_SOCAFFECTADOS_GOTHAM_RRBADOS_GOTHAM_TOTALADOS_GOTHAM_SEVERITYSRS_VERSIONSRS_RAW_TOTALSRS_AWARENESSSRS_COGNITIONSRS_COMMUNICATIONSRS_MOTIVATIONSRS_MANNERISMSSCQ_TOTALAQ_TOTALCOMORBIDITYCURRENT_MED_STATUSMEDICATION_NAMEOFF_STIMULANTS_AT_SCANVINELAND_RECEPTIVE_V_SCALEDVINELAND_EXPRESSIVE_V_SCALEDVINELAND_WRITTEN_V_SCALEDVINELAND_COMMUNICATION_STANDARDVINELAND_PERSONAL_V_SCALEDVINELAND_DOMESTIC_V_SCALEDVINELAND_COMMUNITY_V_SCALEDVINELAND_DAILYLVNG_STANDARDVINELAND_INTERPERSONAL_V_SCALEDVINELAND_PLAY_V_SCALEDVINELAND_COPING_V_SCALEDVINELAND_SOCIAL_STANDARDVINELAND_SUM_SCORESVINELAND_ABC_STANDARDVINELAND_INFORMANTWISC_IV_VCIWISC_IV_PRIWISC_IV_WMIWISC_IV_PSIWISC_IV_SIM_SCALEDWISC_IV_VOCAB_SCALEDWISC_IV_INFO_SCALEDWISC_IV_BLK_DSN_SCALEDWISC_IV_PIC_CON_SCALEDWISC_IV_MATRIX_SCALEDWISC_IV_DIGIT_SPAN_SCALEDWISC_IV_LET_NUM_SCALEDWISC_IV_CODING_SCALEDWISC_IV_SYM_SCALEDEYE_STATUS_AT_SCANAGE_AT_MPRAGEBMIparticipant_idAGE_GROUPSOURCEDX_GROUP_CPAC
0CALTECH514561455.41RNaN126.0118.0128.0WASIWASIWASI-9999.0-9999.0-9999.0-9999.0NaN4.09.02.07.02.01.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN2NaNNaNsub-005145630-65CALTECHNaN
1CALTECH514571422.91AmbiNaN107.0119.093.0WASIWASIWASI23.017.05.03.01.04.08.03.05.01.01.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN2NaNNaNsub-005145720-30CALTECHNaN
2CALTECH514581139.21RNaN93.080.0108.0WASIWASIWASI13.018.07.04.01.04.020.06.014.02.01.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN2NaNNaNsub-005145830-65CALTECHNaN
3CALTECH514591122.81RNaN106.094.0118.0WASIWASIWASI12.012.02.01.01.04.012.04.08.00.01.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN2NaNNaNsub-005145920-30CALTECHNaN
4CALTECH514601134.62AmbiNaN133.0135.0122.0WASIWASIWASI21.011.06.03.01.04.013.04.09.01.01.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN2NaNNaNsub-005146030-65CALTECHNaN
\n", + "
" + ], + "text/plain": [ + " SITE_ID SUB_ID DX_GROUP ... AGE_GROUP SOURCE DX_GROUP_CPAC\n", + "0 CALTECH 51456 1 ... 30-65 CALTECH NaN\n", + "1 CALTECH 51457 1 ... 20-30 CALTECH NaN\n", + "2 CALTECH 51458 1 ... 30-65 CALTECH NaN\n", + "3 CALTECH 51459 1 ... 20-30 CALTECH NaN\n", + "4 CALTECH 51460 1 ... 30-65 CALTECH NaN\n", + "\n", + "[5 rows x 78 columns]" + ] + }, + "metadata": { + "tags": [] + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "2 572\n", + "1 539\n", + "Name: DX_GROUP, dtype: int64" + ] + }, + "metadata": { + "tags": [] + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "NYU 184\n", + "UM 145\n", + "UCLA 109\n", + "USM 101\n", + "LEUVEN 64\n", + "PITT 57\n", + "MAX 57\n", + "YALE 56\n", + "KKI 55\n", + "TRINITY 49\n", + "STANFORD 40\n", + "CALTECH 38\n", + "SDSU 36\n", + "OLIN 36\n", + "SBL 30\n", + "CMU 27\n", + "OHSU 27\n", + "Name: SOURCE, dtype: int64" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hqZksnfwt34o" + }, + "source": [ + "### Dataset for loading ROI time series data\n", + "\n", + "Here is the Dataset class that you can use to load time series data for training. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0RzbAAkDs2fT" + }, + "source": [ + "class ROIDataset(data.Dataset):\n", + " def __init__(self, folder_path, labels_path, \n", + " target=None, encode_target=False,\n", + " roi_file_suffix=\"\",\n", + " get_patient_id=lambda p: \"sub-\" + p.split(\"_\")[-3],\n", + " start_pos=0, seq_len=None,\n", + " transform=None,\n", + " source_col=\"SOURCE\", use_sources=[],\n", + " ):\n", + " self.roi_paths = {\n", + " \"participant_id\" : [],\n", + " \"path\" : [],\n", + " }\n", + " \n", + " self.folder_path = folder_path\n", + " self.labels = pd.read_csv(labels_path)\n", + " self.target = None\n", + " \n", + " self.roi_file_suffix = roi_file_suffix\n", + " self.get_patient_id = get_patient_id\n", + " \n", + " self.start_pos = start_pos\n", + " self.seq_len = seq_len\n", + " self.transform = transform\n", + " self.source_col = source_col\n", + " self.use_sources = use_sources\n", + " \n", + " for participant_file in os.listdir(self.folder_path):\n", + " if self.roi_file_suffix in participant_file:\n", + " participant_id = self.get_patient_id(participant_file)\n", + " self.roi_paths[\"participant_id\"].append(participant_id)\n", + " participant_path = os.path.join(self.folder_path, participant_file)\n", + " self.roi_paths[\"path\"].append(participant_path)\n", + " self.roi_paths = pd.DataFrame(self.roi_paths)\n", + " \n", + " self.labels = self.labels.merge(self.roi_paths, on=\"participant_id\")\n", + " self.roi_ts = self.labels.path.tolist()\n", + " print(f\"{len(self.roi_ts)} ROI time series files found.\")\n", + "\n", + " self.roi_ts = [pd.read_csv(f, sep=\"\\t\").values.T for f in tqdm(self.roi_ts)]\n", + " self.target = self.set_target(target, encode_target)\n", + " \n", + " def set_target(self, target=None, encode_target=False):\n", + " if target is not None:\n", + " self.target = self.labels[target].copy()\n", + " if (self.source_col is not None) and self.use_sources:\n", + " # preserve only targets for objects from sources of interest\n", + " null_idx = ~self.labels[self.source_col].isin(self.use_sources)\n", + " self.target[null_idx] = np.nan\n", + " if encode_target:\n", + " enc = LabelEncoder()\n", + " idx = self.target.notnull()\n", + " self.target[idx] = enc.fit_transform(self.target[idx])\n", + " return self.target\n", + " \n", + " def get_time_series(self, roi, start_pos=None, seq_len=None):\n", + " if seq_len is None:\n", + " seq_len = roi.shape[-1]\n", + " if seq_len > roi.shape[-1]:\n", + " n_repeats = seq_len // roi.shape[-1] + 1 # add copies of roi values from the very beginning \n", + " roi = np.concatenate([roi] * n_repeats, axis=-1)[:, :seq_len]\n", + " if start_pos is None:\n", + " if roi.shape[-1] - seq_len == 0:\n", + " start_pos = 0\n", + " else:\n", + " start_pos = np.random.choice(roi.shape[-1] - seq_len)\n", + " return roi[:, start_pos:start_pos + seq_len]\n", + " \n", + " def __getitem__(self, index):\n", + " if (self.source_col is not None) and self.use_sources:\n", + " s = self.labels[self.source_col][index]\n", + " if s not in self.use_sources:\n", + " return None\n", + " \n", + " roi = self.get_time_series(self.roi_ts[index], self.start_pos, self.seq_len)\n", + " if self.transform is not None:\n", + " roi = self.transform(roi)\n", + " \n", + " return roi if (self.target is None) else (roi, self.target[index])\n", + " \n", + " def __len__(self):\n", + " return len(self.roi_ts)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RTTZBbJwd_nt" + }, + "source": [ + "# transforms (just convert data to torch.Tensor for training)\n", + "class ToTensor(object):\n", + " def __call__(self, data):\n", + " return torch.FloatTensor(data)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0pBPMqehr18a" + }, + "source": [ + "Data from different acqusition sites may have some differences. At least, they have various time series length.\n", + "\n", + "It is possible to load data from only a part of sources by indicating them in the `use_source` argument and train several models separately. However, for now, we will trim all time series to a fixed length of **256** time steps from start (`start_pos=0`, `seq_len=256`) and try to train the model on the entire dataset." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "R-zX15t1s2fY", + "outputId": "3ae0ff1f-5de8-4229-f020-d9783cd440b8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "dataset = ROIDataset(folder_path=folder_path, \n", + " labels_path=targets_path, \n", + " target=\"DX_GROUP\",\n", + " start_pos=0, seq_len=256,\n", + " source_col=\"SOURCE\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "\r 0%| | 0/883 [00:00" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D4_cLqPStvNy" + }, + "source": [ + "### Train and utils functions\n", + "\n", + "Here we define functions for training and validation the model. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A6B9BYnzSo-B" + }, + "source": [ + "def compute_probs(outputs):\n", + " \"\"\"\n", + " Computes class probabilities from logits predicted by the model.\n", + " If classification problem is binary, outputs probabilities of the 1st class.\n", + " Else, outputs array of probabilities of each class. \n", + " \"\"\"\n", + " if outputs.size(1) <= 2:\n", + " probs = F.softmax(outputs, dim=-1)[:, 1]\n", + " else:\n", + " probs = F.softmax(outputs, dim=-1)\n", + " return probs\n", + "\n", + "def train(train_loader, val_loader, model, opt, scheduler=None, \n", + " criterion=nn.CrossEntropyLoss(), metric=roc_auc_score,\n", + " n_epochs=100, epsilon=0):\n", + " \n", + " def plot_results(epoch, start_time):\n", + " clear_output(True)\n", + " plt.figure(figsize=(10, 5))\n", + " plt.subplot(121)\n", + " plt.plot(train_stats[\"mean_train_loss\"])\n", + " plt.plot(train_stats[\"mean_val_loss\"])\n", + " plt.title(\"losses\")\n", + " plt.subplot(122)\n", + " plt.plot(train_stats[\"mean_train_metric\"])\n", + " plt.plot(train_stats[\"mean_val_metric\"])\n", + " plt.gca().set_ylim([0, 1])\n", + " plt.title(\"metrics\")\n", + " plt.show()\n", + " \n", + " print(\"Epoch {} of {} took {:.3f}s\".format(\n", + " epoch + 1, n_epochs, time.time() - start_time))\n", + " print(\" training loss (in-iteration): \\t{:.6f}\".format(train_stats[\"mean_train_loss\"][-1]))\n", + " print(\" validation loss: \\t\\t\\t{:.6f}\".format(train_stats[\"mean_val_loss\"][-1]))\n", + " print(\" training metric: \\t\\t\\t{:.2f}\".format(train_stats[\"mean_train_metric\"][-1]))\n", + " print(\" validation metric: \\t\\t\\t{:.2f}\".format(train_stats[\"mean_val_metric\"][-1]))\n", + " \n", + " train_stats = {\n", + " \"mean_train_loss\" : [],\n", + " \"mean_train_metric\" : [],\n", + " \"mean_val_loss\" : [],\n", + " \"mean_val_metric\" : [],\n", + " }\n", + " \n", + " for epoch in range(n_epochs):\n", + " start_time = time.time()\n", + " \n", + " # train epoch\n", + " model.train(True)\n", + " train_loss, train_preds, train_targets = [], [], []\n", + " for inputs_batch, targets_batch in tqdm(train_loader):\n", + " inputs_batch, targets_batch = inputs_batch.float().to(device), targets_batch.long().to(device) \n", + " logits_batch = model(inputs_batch)\n", + "\n", + " loss = criterion(logits_batch, targets_batch)\n", + " loss.backward()\n", + " opt.step()\n", + " opt.zero_grad()\n", + " \n", + " train_loss.append(loss.item())\n", + " preds = compute_probs(logits_batch)\n", + " train_preds.extend(list(preds.cpu().data.numpy()))\n", + " train_targets.extend(list(targets_batch.cpu().data.numpy()))\n", + " train_metric = metric(train_targets, train_preds)\n", + "\n", + " # validate \n", + " model.train(False)\n", + " val_loss, val_preds, val_targets = [], [], []\n", + " for inputs_batch, targets_batch in tqdm(val_loader):\n", + " inputs_batch, targets_batch = inputs_batch.float().to(device), targets_batch.long().to(device)\n", + " logits_batch = model(inputs_batch)\n", + " \n", + " loss = criterion(logits_batch, targets_batch)\n", + "\n", + " val_loss.append(loss.item())\n", + " preds = compute_probs(logits_batch)\n", + " val_preds.extend(list(preds.cpu().data.numpy()))\n", + " val_targets.extend(list(targets_batch.cpu().data.numpy()))\n", + " val_metric = metric(val_targets, val_preds)\n", + "\n", + " if scheduler is not None:\n", + " scheduler.step()\n", + " print(\"current lr:\", scheduler.get_lr()[0])\n", + "\n", + " # save stats\n", + " train_stats[\"mean_train_loss\"].append(np.mean(train_loss))\n", + " train_stats[\"mean_train_metric\"].append(train_metric)\n", + " train_stats[\"mean_val_loss\"].append(np.mean(val_loss))\n", + " train_stats[\"mean_val_metric\"].append(val_metric)\n", + " \n", + " plot_results(epoch, start_time)\n", + " \n", + " if train_stats[\"mean_train_loss\"][-1] < epsilon:\n", + " break \n", + " return train_stats" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vlu1fvBts2fN" + }, + "source": [ + "## RNN for multivariate time series\n", + "\n", + "Since the data is essentially a multidimensional time series, it seems natural to try to analyze it with a recurrent neural network. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_Pbss93ttqMP" + }, + "source": [ + "### RNN on ROI time series (with GRU units)\n", + "\n", + "Here we define a general RNN architecture that consists of **1 or more** recurrent layers with GRU units followed by **2** fully connected layers. \n", + "\n", + "Data is sequentially processed by recurrent layers. Then we take the **last** computed hidden state, **mean** of all hidden states or a vector of **concatenated hidden states**, feed them into fully connected layer and predict the ASD probability. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UH8t0Yi5s2fd" + }, + "source": [ + "class GRUModel(nn.Module):\n", + " def __init__(self, input_size=116, seq_length=152, n_outputs=2, \n", + " hidden_size=128, n_layers=1, dropout_rnn=0.,\n", + " n_fc_units=128, use_states=\"last\", dropout=0):\n", + " super(self.__class__, self).__init__()\n", + " self.input_size = input_size\n", + " self.seq_length = seq_length\n", + " self.n_outputs = n_outputs\n", + " \n", + " self.hidden_size = hidden_size\n", + " self.n_layers = n_layers\n", + " self.gru = nn.GRU(\n", + " input_size, \n", + " hidden_size, n_layers, \n", + " batch_first=True, # (batch, seq, feature)\n", + " dropout=dropout_rnn,\n", + " )\n", + " \n", + " self.use_states = use_states\n", + " if use_states == \"last\":\n", + " self.gru_out_size = hidden_size\n", + " elif use_states == \"mean\":\n", + " self.gru_out_size = hidden_size\n", + " elif use_states == \"all\":\n", + " self.gru_out_size = hidden_size * seq_length\n", + " \n", + " self.dropout = nn.Dropout(dropout)\n", + " self.fc1 = nn.Linear(self.gru_out_size, n_fc_units)\n", + " self.relu = nn.ReLU(inplace=True)\n", + " self.fc2 = nn.Linear(n_fc_units, n_outputs)\n", + " \n", + " def forward(self, x):\n", + " n_objects, n_roi, seq_length = x.size()\n", + " x = x.permute(0, 2, 1) # (batch, seq, feature)\n", + " \n", + " out, _ = self.gru(x)\n", + " \n", + " if self.use_states == \"last\":\n", + " out = out[:, -1, :]\n", + " elif self.use_states == \"mean\":\n", + " out = out.mean(dim=1)\n", + " elif self.use_states == \"all\":\n", + " out = out.reshape(n_objects, self.hidden_size * seq_length)\n", + " \n", + " out = self.dropout(out)\n", + " out = self.fc1(out) \n", + " out = self.relu(out)\n", + " out = self.dropout(out)\n", + " out = self.fc2(out)\n", + " return out" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FNQJZ7fvquzi" + }, + "source": [ + "### Training\n", + "\n", + "Split data into training and validation parts, and create **train and val dataloaders**. Then create **GRUModel** with parameters of your choice (don't make it too complex), optimizer and scheduler (if needed). Train the model to detect patients with ASD from healthy control and measure its **ROC AUC** on the validation set. \n", + "\n", + "You can define a model with arguments of your choice. For example, try to vary `hidden_size`, `n_layers`, `use_states` and `n_fc_units` arguments. However, remember that the training sample is still quite small for DL, and the recurrent network has many parameters, so don't make it too large. \n", + "\n", + "Also, since ovefitting is very probable, you may want to properly choose `dropout`, `weight_decay` and `n_epochs` values. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HaJmYFivqFxW", + "outputId": "cfed60cb-4f0f-4b18-e649-676162b06d3c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 420 + } + }, + "source": [ + "# use data from all sources\n", + "dataset.use_sources = []\n", + "\n", + "# dataset have target classes 1 and 2\n", + "# encode target with LabelEncoder to use classes 0 and 1 instead\n", + "dataset.set_target(\"DX_GROUP\", encode_target=True)\n", + "\n", + "# we need to convert training data to torch.Tensor\n", + "dataset.transform = ToTensor()\n", + "\n", + "notnull_idx = dataset.target[dataset.target.notnull()].index\n", + "train_idx, val_idx = train_test_split(notnull_idx, \n", + " test_size=0.2, random_state=42)\n", + "batch_size = 64\n", + "train_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, train_idx), batch_size=batch_size, shuffle=True)\n", + "val_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, val_idx), batch_size=batch_size, shuffle=False)\n", + "\n", + "model = GRUModel(\n", + " input_size=200, # number of rois\n", + " seq_length=256,\n", + " n_outputs=2, \n", + " hidden_size=16,\n", + " n_layers=1,\n", + " use_states=\"mean\",\n", + " n_fc_units=32,\n", + " dropout=0.3,\n", + ").to(device) \n", + "opt = torch.optim.Adam(model.parameters(), lr=1e-3, weight_decay=1e-3)\n", + "scheduler = torch.optim.lr_scheduler.StepLR(opt, step_size=50, gamma=0.5)\n", + "\n", + "train_stats = train(train_loader, val_loader, model, opt, scheduler, \n", + " criterion=nn.CrossEntropyLoss(), metric=roc_auc_score,\n", + " n_epochs=150)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + }, + { + "output_type": "stream", + "text": [ + "Epoch 150 of 150 took 0.705s\n", + " training loss (in-iteration): \t0.040953\n", + " validation loss: \t\t\t1.231258\n", + " training metric: \t\t\t1.00\n", + " validation metric: \t\t\t0.60\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "l_JpnUmfzpzn", + "outputId": "229453c1-2efa-4c96-cfc0-74794f3cad57", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 420 + } + }, + "source": [ + "# for comparison, train on the data from a single acquisition site\n", + "dataset.use_sources = [\"NYU\"]\n", + "\n", + "# dataset have target classes 1 and 2\n", + "# encode target with LabelEncoder to use classes 0 and 1 instead\n", + "dataset.set_target(\"DX_GROUP\", encode_target=True)\n", + "\n", + "# we need to convert training data to torch.Tensor\n", + "dataset.transform = ToTensor()\n", + "\n", + "notnull_idx = dataset.target[dataset.target.notnull()].index\n", + "train_idx, val_idx = train_test_split(notnull_idx, \n", + " test_size=0.2, random_state=42)\n", + "batch_size = 64\n", + "train_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, train_idx), batch_size=batch_size, shuffle=True)\n", + "val_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, val_idx), batch_size=batch_size, shuffle=False)\n", + "\n", + "model = GRUModel(\n", + " input_size=200, # number of rois\n", + " seq_length=256,\n", + " n_outputs=2, \n", + " hidden_size=16,\n", + " n_layers=1,\n", + " use_states=\"mean\",\n", + " n_fc_units=32,\n", + " dropout=0.2,\n", + ").to(device) \n", + "opt = torch.optim.Adam(model.parameters(), lr=1e-3, weight_decay=0)\n", + "scheduler = torch.optim.lr_scheduler.StepLR(opt, step_size=50, gamma=0.5)\n", + "\n", + "train_stats = train(train_loader, val_loader, model, opt, scheduler, \n", + " criterion=nn.CrossEntropyLoss(), metric=roc_auc_score,\n", + " n_epochs=150)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + }, + { + "output_type": "stream", + "text": [ + "Epoch 150 of 150 took 0.393s\n", + " training loss (in-iteration): \t0.036117\n", + " validation loss: \t\t\t0.668526\n", + " training metric: \t\t\t1.00\n", + " validation metric: \t\t\t0.69\n" + ], + "name": "stdout" + } + ] + } + ] +} \ No newline at end of file diff --git a/seminar6/seminar6_part2_fullsize_fMRI.ipynb b/seminar6/seminar6_part2_fullsize_fMRI.ipynb new file mode 100644 index 0000000..ca19e58 --- /dev/null +++ b/seminar6/seminar6_part2_fullsize_fMRI.ipynb @@ -0,0 +1,1628 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + }, + "colab": { + "name": "seminar6_part2_fullsize_fMRI.ipynb", + "provenance": [], + "collapsed_sections": [ + "C4A2xz0u0__H", + "wnpcbAJmtX0p", + "usWsKTWQtdjd", + "kP-GKJd6uSPh", + "kfEsIDcSx0-H" + ] + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "TZIZlv5Hs2e-" + }, + "source": [ + "\"Open\n", + "\n", + "# **Seminar 6: Deep Learning for fMRI**\n", + "\n", + "## **Classification of full-size fMRI**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XMj175Fw7_eP" + }, + "source": [ + "#### Introduction\n", + "In this notebook we will work with full-size fMRI data which represents 4D tensor or a 3D video of the brain functional activity.\n", + "\n", + "**We will train a network for detection of Autistm Spectrum Disorder (ASD) based on full-size fMRI series.** \n", + "\n", + "**Also, we will apply a conventional domain adaptation approach to reduce the part of the site-related variability in the data.**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PPx5Ba3ks2fA" + }, + "source": [ + "import os\n", + "import time\n", + "from tqdm import tqdm\n", + "import nibabel as nib\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from IPython.display import clear_output\n", + "\n", + "from sklearn.preprocessing import LabelEncoder\n", + "from sklearn.model_selection import StratifiedKFold, train_test_split\n", + "from sklearn.metrics import roc_auc_score\n", + "\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "import torch.utils.data as data\n", + "import torchvision\n", + "import torchvision.transforms as transforms" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7MjR5PKZJpsm", + "outputId": "7bc74241-652c-4678-af81-558b343b7f6f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 373 + } + }, + "source": [ + "# check if gpu is available\n", + "!nvidia-smi" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fri Oct 2 10:55:27 2020 \n", + "+-----------------------------------------------------------------------------+\n", + "| NVIDIA-SMI 455.23.05 Driver Version: 418.67 CUDA Version: 10.1 |\n", + "|-------------------------------+----------------------+----------------------+\n", + "| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |\n", + "| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |\n", + "| | | MIG M. |\n", + "|===============================+======================+======================|\n", + "| 0 Tesla V100-SXM2... Off | 00000000:00:04.0 Off | 0 |\n", + "| N/A 37C P0 37W / 300W | 13155MiB / 16130MiB | 0% Default |\n", + "| | | ERR! |\n", + "+-------------------------------+----------------------+----------------------+\n", + " \n", + "+-----------------------------------------------------------------------------+\n", + "| Processes: |\n", + "| GPU GI CI PID Type Process name GPU Memory |\n", + "| ID ID Usage |\n", + "|=============================================================================|\n", + "| No running processes found |\n", + "+-----------------------------------------------------------------------------+\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OpRdaVYgJtfI", + "outputId": "bf7e13d0-ea3b-4122-bb03-20ace4ad9cad", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "use_cuda = torch.cuda.is_available()\n", + "print(\"Torch version:\", torch.__version__)\n", + "if use_cuda:\n", + " print(\"Using GPU\")\n", + "else:\n", + " print(\"Not using GPU\")\n", + "device = 0" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Torch version: 1.6.0+cu101\n", + "Using GPU\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lakVWOUC9Ao0" + }, + "source": [ + "Mounting Google Drive to Collab Notebook. You should go with the link and enter your personal authorization code:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mZkNPQnzvCHM", + "outputId": "246b1e7c-dce9-4b57-ac9a-5c276c8fe7f4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 54 + } + }, + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/drive')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6A_hJE5g9Dxv" + }, + "source": [ + "Get the data. Add a shortcut to your Google Drive.\n", + "\n", + "Shared link: https://drive.google.com/drive/folders/1_63qnHOCUEzOUmUWhcmTXulmQMmJglwT?usp=sharing\n", + "\n", + "(You will need the same data directory, as in the first part of the seminar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aHZJKicK9ngX" + }, + "source": [ + "We will use full-size fMRI series from the same data collection, that we analysed in the first part. However, here we will only consider the data from **2** acquistion sites - **USM** and **UCLA** with around **70** participants from each. \n", + "\n", + "\n", + "\n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iZfznwFb9fPd" + }, + "source": [ + "folder_path = '/content/drive/My Drive/NeuroML/func_ABIDE/abide_fmri/'\n", + "targets_path = '/content/drive/My Drive/NeuroML/func_ABIDE/ABIDE1CPAC_targets.csv'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C4A2xz0u0__H" + }, + "source": [ + "### Dataloader to load full-size fMRI data. \n", + "\n", + "Below you can see a Dataset class for loading full-size fMRI. \n", + "\n", + "What is implemented here:\n", + "\n", + "- Collecting all the fMRI files from a given folder;\n", + "- Loading fMRI 4D time series from a `.nii` of `.npy` file;\n", + "- **Preloading** all the images into RAM or **loading them online** (`load_online` argument);\n", + "- **Cropping a brain image** to the given size, if needed (`coord_min` and `img_shape` arguments);\n", + "- **Taking a subsequence** of a given size starting from a given time step, or sampling at a random time step, if not given (`start_pos`, `seq_len` arguments)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X4Dbi6ins2fj" + }, + "source": [ + "def load_nii_to_array(nii_path):\n", + " return np.asanyarray(nib.load(nii_path).dataobj)\n", + "\n", + "class fMRIDataset(data.Dataset):\n", + " \"\"\"\n", + " Arguments:\n", + " folder_path: path to data folder\n", + " labels_path: path to file with targets and additional information\n", + " target: column of targets df with target to predict. If None, loads images only\n", + " encode_target: if True, encode target with LabelEncoder\n", + " mri_file_suffix (str): consider only files with given keyword in filename\n", + " load_online (bool): if True, load mri images online. Else, preload everything during initialization\n", + " transform (torchvision.transforms): if given, apply transformation to the item. If None, return item without modifications\n", + " \"\"\"\n", + " \n", + " def __init__(self, folder_path, labels_path, target=None, encode_target=False, domain_target=None,\n", + " mri_file_suffix=\"\", load_online=False, transform=None,\n", + " source_col=\"SOURCE\", use_sources=[],\n", + " coord_min=(6, 5, 6), img_shape=(48, 64, 48), \n", + " start_pos=None, seq_len=None):\n", + " self.mri_paths = {\n", + " \"participant_id\" : [],\n", + " \"path\" : [],\n", + " }\n", + " \n", + " self.folder_path = folder_path\n", + " self.labels = pd.read_csv(labels_path)\n", + " self.target, self.domain_target = None, None\n", + " self.load_online = load_online\n", + " \n", + " self.mri_file_suffix = mri_file_suffix\n", + " self.source_col = source_col\n", + " self.use_sources = use_sources\n", + "\n", + " self.coord_min = coord_min\n", + " self.img_shape = img_shape\n", + " self.start_pos = start_pos\n", + " self.seq_len = seq_len\n", + " self.transform = transform\n", + "\n", + " def get_participant_id(participant_file):\n", + " return \"sub-\" + participant_file.split(\"_\")[-4]\n", + " \n", + " participant_files = os.listdir(self.folder_path)\n", + " for participant_file in tqdm(participant_files):\n", + " if (self.mri_file_suffix in participant_file):\n", + " # is participant file\n", + " participant_path = os.path.join(self.folder_path, participant_file)\n", + " participant_id = get_participant_id(participant_file)\n", + " self.mri_paths[\"path\"].append(participant_path)\n", + " self.mri_paths[\"participant_id\"].append(participant_id)\n", + " \n", + " self.mri_paths = pd.DataFrame(self.mri_paths)\n", + " self.labels = self.labels.merge(self.mri_paths, on=\"participant_id\")\n", + " self.mri_files = self.labels[\"path\"].tolist()\n", + " print(f\"{len(self.mri_files)} image files found.\")\n", + " \n", + " if not self.load_online:\n", + " self.mri_files = [self.get_image(index, self.start_pos, self.seq_len) for index in tqdm(range(len(self.mri_files)))]\n", + "\n", + " # update self.img_shape (and other params ?)\n", + " self.output_img_shape = self[0].shape[1:4]\n", + " self.target, self.domain_target = self.set_target(target, encode_target, domain_target)\n", + " \n", + " \n", + " def set_target(self, target=None, encode_target=False, domain_target=None):\n", + " self.target, self.domain_target = None, None\n", + " if target is not None:\n", + " self.target = self.labels[target].copy()\n", + " if (self.source_col is not None) and self.use_sources:\n", + " # preserve only targets for objects from sources of interest\n", + " null_idx = ~self.labels[self.source_col].isin(self.use_sources)\n", + " self.target[null_idx] = np.nan\n", + " if encode_target:\n", + " enc = LabelEncoder()\n", + " idx = self.target.notnull()\n", + " self.target[idx] = enc.fit_transform(self.target[idx])\n", + " if domain_target is not None:\n", + " self.domain_target = self.labels[domain_target].copy()\n", + " if (self.source_col is not None) and self.use_sources:\n", + " # preserve only targets for objects from sources of interest\n", + " null_idx = ~self.labels[self.source_col].isin(self.use_sources)\n", + " self.domain_target[null_idx] = np.nan\n", + " self.domain_enc = LabelEncoder()\n", + " idx = self.domain_target.notnull()\n", + " self.domain_target[idx] = self.domain_enc.fit_transform(self.domain_target[idx])\n", + " return self.target, self.domain_target\n", + "\n", + " \n", + " def reshape_image(self, mri_img, coord_min, img_shape):\n", + " seq_len = mri_img.shape[-1]\n", + " return mri_img[coord_min[0]:coord_min[0] + img_shape[0],\n", + " coord_min[1]:coord_min[1] + img_shape[1],\n", + " coord_min[2]:coord_min[2] + img_shape[2], :].reshape((1,) + img_shape + (seq_len,))\n", + " \n", + " def get_image(self, index, start_pos=None, seq_len=None):\n", + " \n", + " def load_mri(mri_file):\n", + " if \"nii\" in mri_file:\n", + " img = load_nii_to_array(mri_file)\n", + " else:\n", + " img = np.load(mri_file)\n", + " return img\n", + " \n", + " mri_file = self.mri_files[index]\n", + " img = load_mri(mri_file) \n", + " img = self.reshape_image(img, self.coord_min, self.img_shape)\n", + " \n", + " if seq_len is None:\n", + " seq_len = img.shape[-1]\n", + " if start_pos is None:\n", + " start_pos = np.random.choice(np.arange(img.shape[-1] - seq_len + 1))\n", + " if seq_len == 1:\n", + " img = img[:, :, :, :, start_pos]\n", + " else:\n", + " img = img[:, :, :, :, start_pos:start_pos + seq_len]\n", + " img = img.transpose((4, 0, 1, 2, 3))\n", + " return img\n", + " \n", + " def __getitem__(self, index):\n", + " if (self.source_col is not None) and self.use_sources:\n", + " s = self.labels[self.source_col][index]\n", + " if s not in self.use_sources:\n", + " return None\n", + "\n", + " img = self.get_image(index, self.start_pos, self.seq_len) if self.load_online else self.mri_files[index]\n", + " if self.transform is not None:\n", + " img = self.transform(img)\n", + "\n", + " if self.target is None:\n", + " item = img\n", + " else:\n", + " item = [img, self.target[index]]\n", + " if self.domain_target is not None:\n", + " item += [self.domain_target[index]]\n", + " return item\n", + "\n", + " def __len__(self):\n", + " return len(self.mri_files)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ouARZ4ir2F1L" + }, + "source": [ + "\n", + "\n", + "\n", + "\n", + "Transforms are applied to each image returned by `fMRIDataset` object. For now, we will only need to transform the fMRI image from `np.array` to `torch.tensor`. \n", + "However, you can implement additional transformation to add various types of augmentations. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y0b51CscR05M" + }, + "source": [ + "# transforms\n", + "import warnings\n", + "\n", + "class ToTensor(object):\n", + " def __call__(self, img):\n", + " return torch.FloatTensor(img)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t57ZzM1_nZ5b" + }, + "source": [ + "### Load data\n", + "\n", + "Create a dataset that loads data from `func_ABIDE/abide_fmri`.\n", + "\n", + "In general, fMRI sequences are too large, so we cannot process the whole sequence with neural network on GPU. A common practice is to **select random subsequences at the training** stage, and at the testing, to split the sequence into several parts and **average the predictions** over them.\n", + "\n", + "However, now, for faster training, we will use a prepared dataset of short subsequences from **0**th to **16**th time step of each series." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QkLWqRDqLleU", + "outputId": "f9eaf491-238c-45be-eecb-1189efc03e0f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 67 + } + }, + "source": [ + "# create the dataset and load fMRI sequences\n", + "\n", + "folder_path = '/content/drive/My Drive/NeuroML/func_ABIDE/abide_fmri'\n", + "targets_path = '/content/drive/My Drive/NeuroML/func_ABIDE/ABIDE1CPAC_targets.csv'\n", + "\n", + "transform = transforms.Compose([\n", + " ToTensor(),\n", + "])\n", + "\n", + "dataset = fMRIDataset(\n", + " folder_path, \n", + " labels_path=targets_path,\n", + " target=None,\n", + " mri_file_suffix=\"npy\",\n", + " load_online=False,\n", + " transform=transform,\n", + " source_col=\"SOURCE\",\n", + " use_sources=[\"USM\", \"UCLA\"],\n", + " start_pos=0,\n", + " seq_len=16,\n", + ")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "100%|██████████| 145/145 [00:00<00:00, 42149.43it/s]\n", + " 0%| | 0/145 [00:00" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y4FZzU2rs2fi" + }, + "source": [ + "## **ConvTempNet for 4D full-size fMRI**\n", + "\n", + "Now, we will train a ConvTempNet model to analyze this data and distinguish **patients with autism spectrum disorder** from the **healthy control group**. \n", + "\n", + "First, remind that ConvTempNet arhitecture consisits of two parts - convolutional and recurrent. It allows us to first extract vector of spatial features from each 3D brain image with **3D CNN**, and then process this sequence of vectors with **RNN** (or another suitable model, for example, temporal convoltions) to capture temporal patterns. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wnpcbAJmtX0p" + }, + "source": [ + "### Convolutional blocks\n", + "\n", + "**ConvEncoder** is an intermediate model, that extracts vector of spatial features from each 3D image in fMRI sequence and returns sequence of feature vectores. " + ] + }, + { + "cell_type": "code", + "metadata": { + "jupyter": { + "source_hidden": true + }, + "id": "ifo-_I4Fs2fw" + }, + "source": [ + "class Flatten(nn.Module):\n", + " def forward(self, input):\n", + " return input.view(input.size(0), -1)\n", + "\n", + "class CNN3d(nn.Module):\n", + " def __init__(self, \n", + " input_shape=(64, 64, 64), \n", + " n_outputs=None, \n", + " conv_model=[32, 64, 128, 256], \n", + " n_flatten_units=None):\n", + " super(self.__class__, self).__init__()\n", + " input_shape = np.array(input_shape)\n", + " self.n_layers = len(conv_model)\n", + " \n", + " self.model = []\n", + " C_in = 1\n", + " for C_out in conv_model:\n", + " self.model += [\n", + " nn.Conv3d(C_in, C_out, 4, 2, 1, bias=False),\n", + " nn.BatchNorm3d(C_out),\n", + " nn.ReLU(inplace=True),\n", + " ]\n", + " C_in = C_out\n", + " \n", + " self.model += [Flatten()]\n", + " print(\"n activations:\", C_out,\n", + " \"of size:\", list(input_shape // (2 ** self.n_layers)))\n", + " self.n_flatten_units = int(np.prod(input_shape // (2 ** self.n_layers)) * C_out)\n", + " print(\"n flatten units:\", self.n_flatten_units)\n", + " if n_outputs is not None:\n", + " self.model += [\n", + " nn.Linear(self.n_flatten_units, n_outputs)\n", + " ]\n", + " self.model = nn.Sequential(*self.model)\n", + " \n", + " def forward(self, x):\n", + " return self.model(x)\n", + " \n", + "\n", + "class ResBlock3d(nn.Module):\n", + " def __init__(self, C):\n", + " super(self.__class__, self).__init__()\n", + " self.C = C\n", + " self.block = [\n", + " nn.BatchNorm3d(C),\n", + " nn.ReLU(inplace=True),\n", + " nn.Conv3d(C, C, kernel_size=3, padding=1),\n", + " ]\n", + " self.block = nn.Sequential(*self.block)\n", + " \n", + " def forward(self, x):\n", + " return x + self.block(x)\n", + " \n", + "\n", + "class ResNet3d(nn.Module):\n", + " def __init__(self, \n", + " input_shape=(64, 64, 64), \n", + " n_outputs=None, \n", + " conv_model=[32, 64, 128, 256], \n", + " n_flatten_units=None):\n", + " super(self.__class__, self).__init__()\n", + " input_shape = np.array(input_shape)\n", + " self.n_layers = len(conv_model)\n", + " \n", + " self.model = []\n", + " C_in = 1\n", + " for C_out in conv_model:\n", + " # here instead of 3x3-BN-ReLU\n", + " # we use 1x1-ResBlock3d-1x1 (1x1-BN-ReLU-3x3-1x1)\n", + " self.model += [\n", + " nn.Conv3d(C_in, C_out, 1, 1, 0, bias=False), # 1x1, add channels\n", + " ResBlock3d(C_out),\n", + " nn.Conv3d(C_out, C_out, 1, 2, 0, bias=False), # 1x1 reduce spatial dim\n", + " ]\n", + " C_in = C_out\n", + " \n", + " self.model += [Flatten()]\n", + " print(\"n activations:\", C_out,\n", + " \"of size:\", list(input_shape // (2 ** self.n_layers)))\n", + " self.n_flatten_units = int(np.prod(input_shape // (2 ** self.n_layers)) * C_out)\n", + " print(\"n flatten units:\", self.n_flatten_units)\n", + " if n_outputs is not None:\n", + " self.model += [\n", + " nn.Linear(self.n_flatten_units, n_outputs)\n", + " ]\n", + " self.model = nn.Sequential(*self.model)\n", + " \n", + " def forward(self, x):\n", + " return self.model(x)\n", + "\n", + "\n", + "class ConvEncoder(nn.Module):\n", + " def __init__(self, input_shape=(64, 64, 64),\n", + " conv_model=[32, 64, 128, 256], conv_model_type=\"CNN\",\n", + " n_flatten_units=None):\n", + " super(self.__class__, self).__init__()\n", + " self.conv_model_type = conv_model_type\n", + " if conv_model_type == \"CNN\":\n", + " self.conv_model = CNN3d(\n", + " input_shape, None, \n", + " conv_model, n_flatten_units, \n", + " )\n", + " elif conv_model_type == \"ResNet\":\n", + " self.conv_model = ResNet3d(\n", + " input_shape, None, \n", + " conv_model, n_flatten_units, \n", + " )\n", + " \n", + " def forward(self, x):\n", + " n_objects, seq_length = x.size()[0:2]\n", + " x = x.reshape([n_objects * seq_length] + list(x.size()[2:]))\n", + " x = self.conv_model(x)\n", + " x = x.reshape([n_objects, seq_length, -1])\n", + " return x" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "usWsKTWQtdjd" + }, + "source": [ + "### ClfGRU model\n", + "\n", + "**ClfGRU** is a recurrent model with GRU units, that takes sequence of feature vectors (in our case, extracted by ConvEncoder) and predicts the target variable. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N84tpN78s2f0" + }, + "source": [ + "class ConvGRU(nn.Module):\n", + " def __init__(self, n_latent_units, seq_length, n_outputs, \n", + " hidden_size=128, n_layers=1,\n", + " n_fc_units=128, use_states=\"last\", dropout=0):\n", + " super(self.__class__, self).__init__()\n", + " self.n_latent_units = n_latent_units\n", + " self.seq_length = seq_length\n", + " self.n_outputs = n_outputs\n", + " \n", + " self.hidden_size = hidden_size\n", + " self.n_layers = n_layers\n", + " self.gru = nn.GRU(\n", + " n_latent_units, \n", + " hidden_size, n_layers, \n", + " batch_first=True\n", + " )\n", + " \n", + " self.use_states = use_states\n", + " if use_states == \"last\":\n", + " self.gru_out_size = hidden_size\n", + " elif use_states == \"mean\":\n", + " self.gru_out_size = hidden_size\n", + " elif use_states == \"all\":\n", + " self.gru_out_size = hidden_size * seq_length\n", + " \n", + " self.dropout = nn.Dropout(dropout)\n", + " self.fc1 = nn.Linear(self.gru_out_size, n_fc_units)\n", + " self.relu = nn.ReLU(inplace=True)\n", + " self.fc2 = nn.Linear(n_fc_units, n_outputs)\n", + " \n", + " def forward(self, x):\n", + " out, _ = self.gru(x)\n", + " \n", + " if self.use_states == \"last\":\n", + " out = out[:, -1, :]\n", + " elif self.use_states == \"mean\":\n", + " out = out.mean(dim=1)\n", + " elif self.use_states == \"all\":\n", + " out = out.reshape(n_objects, self.hidden_size * seq_length)\n", + " \n", + " out = self.dropout(out)\n", + " out = self.fc1(out) \n", + " out = self.relu(out)\n", + " out = self.dropout(out)\n", + " out = self.fc2(out)\n", + " return out" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kP-GKJd6uSPh" + }, + "source": [ + "### Train and utils functions" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2LODB7clGcU9" + }, + "source": [ + "def compute_probs(outputs):\n", + " \"\"\"\n", + " Computes class probabilities from logits predicted by the model.\n", + " If classification problem is binary, outputs probabilities of the 1st class.\n", + " Else, outputs array of probabilities of each class. \n", + " \"\"\"\n", + " if outputs.size(1) <= 2:\n", + " probs = F.softmax(outputs, dim=-1)[:, 1]\n", + " else:\n", + " probs = F.softmax(outputs, dim=-1)\n", + " return probs\n", + "\n", + "\n", + "def train(train_loader, val_loader, args,\n", + " C, T, C_opt, T_opt,\n", + " crit=nn.CrossEntropyLoss(),\n", + " metric=roc_auc_score):\n", + " \n", + " def plot_results(epoch):\n", + " clear_output(True)\n", + " print(\"EPOCH {}\".format(epoch))\n", + "\n", + " plt.figure(figsize=(10, 5))\n", + " plt.subplot(121)\n", + " plt.plot(train_stats[\"mean_train_loss\"], label=\"train_loss\")\n", + " plt.plot(train_stats[\"mean_val_loss\"], label=\"val_loss\")\n", + " plt.title(\"losses\")\n", + " plt.legend()\n", + " plt.subplot(122)\n", + " plt.plot(train_stats[\"mean_train_metric\"], label=\"train_metric\")\n", + " plt.plot(train_stats[\"mean_val_metric\"], label=\"val_metric\")\n", + " plt.gca().set_ylim([0, 1])\n", + " plt.title(\"metrics\")\n", + " plt.legend()\n", + " plt.show()\n", + " \n", + " print(\" training loss (in-iteration): \\t{:.6f}\".format(train_stats[\"mean_train_loss\"][-1]))\n", + " print(\" validation loss: \\t\\t\\t{:.6f}\".format(train_stats[\"mean_val_loss\"][-1]))\n", + " print()\n", + " print(\" training AUC: \\t\\t\\t{:.2f}\".format(train_stats[\"mean_train_metric\"][-1]))\n", + " print(\" validation AUC: \\t\\t\\t{:.2f}\".format(train_stats[\"mean_val_metric\"][-1]))\n", + " \n", + " train_stats = {\n", + " \"mean_train_loss\" : [],\n", + " \"mean_val_loss\" : [],\n", + " \"mean_train_metric\" : [],\n", + " \"mean_val_metric\" : [],\n", + " }\n", + " \n", + " for epoch in range(args[\"n_epochs\"]):\n", + " print(\"TRAIN EPOCH {}...\".format(epoch))\n", + " train_loss, train_preds, train_targets = [], [], []\n", + " val_loss, val_preds, val_targets = [], [], []\n", + " \n", + " # train epoch\n", + " C.train(True), T.train(True)\n", + " for inputs_batch, targets_batch in tqdm(train_loader):\n", + " inputs_batch, targets_batch = inputs_batch.float().to(device), targets_batch.long().to(device)\n", + "\n", + " latents_batch = C(inputs_batch)\n", + " logits_batch = T(latents_batch)\n", + " loss = crit(logits_batch, targets_batch)\n", + " loss.backward()\n", + " T_opt.step(), C_opt.step()\n", + " T_opt.zero_grad(), C_opt.zero_grad()\n", + " \n", + " train_loss.append(loss.item())\n", + " preds = compute_probs(logits_batch)\n", + " train_preds.extend(list(preds.cpu().data.numpy()))\n", + " train_targets.extend(list(targets_batch.cpu().data.numpy()))\n", + " train_loss = np.mean(train_loss)\n", + " train_metric = metric(train_targets, train_preds)\n", + " \n", + " # validate\n", + " C.train(False), T.train(False)\n", + " for inputs_batch, targets_batch in tqdm(val_loader):\n", + " inputs_batch, targets_batch = inputs_batch.float().to(device), targets_batch.long().to(device)\n", + " \n", + " latents_batch = C(inputs_batch)\n", + " logits_batch = T(latents_batch)\n", + " loss = crit(logits_batch, targets_batch)\n", + " val_loss.append(loss.item())\n", + " preds = compute_probs(logits_batch)\n", + " val_preds.extend(list(preds.cpu().data.numpy()))\n", + " val_targets.extend(list(targets_batch.cpu().data.numpy())) \n", + " val_metric = metric(val_targets, val_preds)\n", + "\n", + " # save stats\n", + " train_stats[\"mean_train_loss\"].append(np.mean(train_loss))\n", + " train_stats[\"mean_val_loss\"].append(np.mean(val_loss))\n", + " train_stats[\"mean_train_metric\"].append(train_metric)\n", + " train_stats[\"mean_val_metric\"].append(val_metric)\n", + " \n", + " plot_results(epoch) \n", + " return train_stats" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J6eLXsBOuoqo" + }, + "source": [ + "### Training\n", + "\n", + "We will train the model on **3** data samples: from this **USM** only, from **UCLA** only, and from both **USM+UCLA**. \n", + "\n", + "For each sample, split data into training and validation parts, and create **train and val dataloaders**. \n", + "\n", + "Then, create **ConvEncoder** and **ClfGRU** models with parameters of your choice (don't make it too complex), optimizer and scheduler (if needed). Train the model to detect patients with ASD from healthy control and measure its **ROC AUC** on the validation set. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Lf5yyP46K8vm" + }, + "source": [ + "# train on the data from USM only\n", + "dataset.use_sources = [\"USM\"]\n", + "\n", + "# dataset have target classes 1 and 2\n", + "# encode target with LabelEncoder to use classes 0 and 1 instead\n", + "dataset.set_target(\"DX_GROUP\", encode_target=True)\n", + "\n", + "notnull_idx = dataset.target[dataset.target.notnull()].index\n", + "train_idx, val_idx = train_test_split(notnull_idx, stratify=dataset.target[notnull_idx],\n", + " test_size=0.2, random_state=42)\n", + "batch_size = 16\n", + "train_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, train_idx), batch_size=batch_size, shuffle=True)\n", + "val_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, val_idx), batch_size=batch_size, shuffle=False)\n", + "\n", + "model = ConvGRU(\n", + " input_shape=(48, 64, 48),\n", + " seq_length=16,\n", + " n_outputs=2, \n", + " conv_model=[32, 64, 128, 256],\n", + " conv_model_type=\"CNN\",\n", + " hidden_size=64,\n", + " n_layers=1,\n", + " use_states=\"mean\",\n", + " n_fc_units=128,\n", + " dropout=0.2,\n", + ").to(device) \n", + "opt = torch.optim.Adam(model.parameters(), lr=1e-4, weight_decay=1e-3)\n", + "scheduler = torch.optim.lr_scheduler.StepLR(opt, step_size=5, gamma=0.5)\n", + "\n", + "train_stats = train(train_loader, val_loader, model, opt, scheduler, \n", + " criterion=nn.CrossEntropyLoss(), metric=roc_auc_score,\n", + " n_epochs=25)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "B1fG5b_E1vLp", + "outputId": "aca67ba4-0cab-4ed9-c780-92a92ede19a2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 437 + } + }, + "source": [ + "dataset.use_sources = [\"USM\"]\n", + "\n", + "# dataset have target classes 1 and 2\n", + "# encode target with LabelEncoder to use classes 0 and 1 instead\n", + "dataset.set_target(\"DX_GROUP\", encode_target=True)\n", + "\n", + "notnull_idx = dataset.target[dataset.target.notnull()].index\n", + "train_idx, val_idx = train_test_split(notnull_idx, stratify=dataset.target[notnull_idx],\n", + " test_size=0.2, random_state=42)\n", + "batch_size = 16\n", + "train_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, train_idx), batch_size=batch_size, shuffle=True)\n", + "val_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, val_idx), batch_size=batch_size, shuffle=False)\n", + "\n", + "C_model = ConvEncoder(input_shape=(48, 64, 48), \n", + " conv_model=[32, 64, 128, 256], \n", + " conv_model_type=\"CNN\",\n", + " n_flatten_units=None).to(device)\n", + "T_model = ClfGRU(n_latent_units=C_model.conv_model.n_flatten_units, \n", + " seq_length=16, \n", + " n_outputs=2,\n", + " hidden_size=64,\n", + " n_layers=1,\n", + " use_states=\"mean\",\n", + " n_fc_units=128,\n", + " dropout=0.2).to(device)\n", + "lr = 1e-4\n", + "wd = 0 \n", + "C_opt = torch.optim.Adam(C_model.parameters(), lr=lr, weight_decay=wd)\n", + "T_opt = torch.optim.Adam(T_model.parameters(), lr=lr, weight_decay=wd)\n", + "\n", + "args = {\"n_epochs\" : 25}\n", + "train_stats = train(train_loader, val_loader, args,\n", + " C_model, T_model, C_opt, T_opt,\n", + " crit=nn.CrossEntropyLoss(), metric=roc_auc_score)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "EPOCH 24\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + }, + { + "output_type": "stream", + "text": [ + " training loss (in-iteration): \t0.106279\n", + " validation loss: \t\t\t0.625981\n", + "\n", + " training AUC: \t\t\t1.00\n", + " validation AUC: \t\t\t0.76\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "F4ViGw0nFN4x", + "outputId": "da4749ab-df9a-4d4e-a34f-d74edb7d94fc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 437 + } + }, + "source": [ + "# train on the data from UCLA only\n", + "dataset.use_sources = [\"UCLA\"]\n", + "\n", + "# dataset have target classes 1 and 2\n", + "# encode target with LabelEncoder to use classes 0 and 1 instead\n", + "dataset.set_target(\"DX_GROUP\", encode_target=True)\n", + "\n", + "notnull_idx = dataset.target[dataset.target.notnull()].index\n", + "train_idx, val_idx = train_test_split(notnull_idx, stratify=dataset.target[notnull_idx],\n", + " test_size=0.2, random_state=42)\n", + "batch_size = 16\n", + "train_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, train_idx), batch_size=batch_size, shuffle=True)\n", + "val_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, val_idx), batch_size=batch_size, shuffle=False)\n", + "\n", + "C_model = ConvEncoder(input_shape=(48, 64, 48), \n", + " conv_model=[32, 64, 128, 256], \n", + " conv_model_type=\"CNN\",\n", + " n_flatten_units=None).to(device)\n", + "T_model = ClfGRU(n_latent_units=C_model.conv_model.n_flatten_units, \n", + " seq_length=16, \n", + " n_outputs=2,\n", + " hidden_size=64,\n", + " n_layers=1,\n", + " use_states=\"mean\",\n", + " n_fc_units=128,\n", + " dropout=0.2).to(device)\n", + "lr = 1e-4\n", + "wd = 0 \n", + "C_opt = torch.optim.Adam(C_model.parameters(), lr=lr, weight_decay=wd)\n", + "T_opt = torch.optim.Adam(T_model.parameters(), lr=lr, weight_decay=wd)\n", + "\n", + "args = {\"n_epochs\" : 25}\n", + "train_stats = train(train_loader, val_loader, args,\n", + " C_model, T_model, C_opt, T_opt,\n", + " crit=nn.CrossEntropyLoss(), metric=roc_auc_score)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "EPOCH 24\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + }, + { + "output_type": "stream", + "text": [ + " training loss (in-iteration): \t0.063626\n", + " validation loss: \t\t\t0.596836\n", + "\n", + " training AUC: \t\t\t1.00\n", + " validation AUC: \t\t\t0.80\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QFCvl0DWFPYa", + "outputId": "2cfc7b8e-f45a-49cc-ce5c-179fb98957ca", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 437 + } + }, + "source": [ + "# train on the data from USM+UCLA\n", + "dataset.use_sources = [\"USM\", \"UCLA\"]\n", + "\n", + "# dataset have target classes 1 and 2\n", + "# encode target with LabelEncoder to use classes 0 and 1 instead\n", + "dataset.set_target(\"DX_GROUP\", encode_target=True)\n", + "\n", + "notnull_idx = dataset.target[dataset.target.notnull()].index\n", + "train_idx, val_idx = train_test_split(notnull_idx, stratify=dataset.target[notnull_idx],\n", + " test_size=0.2, random_state=42)\n", + "batch_size = 16\n", + "train_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, train_idx), batch_size=batch_size, shuffle=True)\n", + "val_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, val_idx), batch_size=batch_size, shuffle=False)\n", + "\n", + "C_model = ConvEncoder(input_shape=(48, 64, 48), \n", + " conv_model=[32, 64, 128, 256], \n", + " conv_model_type=\"CNN\",\n", + " n_flatten_units=None).to(device)\n", + "T_model = ClfGRU(n_latent_units=C_model.conv_model.n_flatten_units, \n", + " seq_length=16, \n", + " n_outputs=2,\n", + " hidden_size=64,\n", + " n_layers=1,\n", + " use_states=\"mean\",\n", + " n_fc_units=128,\n", + " dropout=0.2).to(device)\n", + "lr = 1e-4\n", + "wd = 0 \n", + "C_opt = torch.optim.Adam(C_model.parameters(), lr=lr, weight_decay=wd)\n", + "T_opt = torch.optim.Adam(T_model.parameters(), lr=lr, weight_decay=wd)\n", + "\n", + "args = {\"n_epochs\" : 25}\n", + "train_stats = train(train_loader, val_loader, args,\n", + " C_model, T_model, C_opt, T_opt,\n", + " crit=nn.CrossEntropyLoss(), metric=roc_auc_score)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "EPOCH 24\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlcAAAE/CAYAAABrdOYuAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdd3iUVfbA8e9JJwktJPRAKKF3QrGgFKXoCq4Kin0t6Iq9rLj6s7vq6ro2FBF1rSCiKCo2FEQUkEDovSYBEkJJCJCElPv7404wYEgmYZJ3ZnI+z5MnmZl33jkJ5M2Ze889V4wxKKWUUkopzwhwOgCllFJKKX+iyZVSSimllAdpcqWUUkop5UGaXCmllFJKeZAmV0oppZRSHqTJlVJKKaWUB2lypdwmIttF5Byn41BKKW8kIodEpLXTcSjnaXKllFJKlUFE5onIDeUdZ4yJNMZsrY6YlHfT5EoppZQ6BSIS5HQMyrtocqUqTERCReRFEdnl+nhRREJdj0WLyFcikiki+0XkFxEJcD12v4jsFJFsEdkgIkNc9weIyAQR2SIi+0RkuohEuR4LE5EPXPdnisgSEWnk3HevlPIVrlKG+0RkpYgcFpG3RKSRiHzjug7NEZH6rmP7i8hvruvMChEZ6Lr/KWAA8Kpr2u9V1/1GRMaLyCZgU4n72rq+riUi/xGRHSKSJSILXPfpNa0G0GxbVcaDQH+gB2CAL4CHgP8D7gFSgRjXsf0BIyLtgVuBPsaYXSISBwS6jrkNuBA4G8gAXgYmAmOBa4C6QCyQ53rNnCr97pRS/uRi4Fzs37skoCdwPbAOmA3cLiJTgK+Bq4BvgSHApyLSwRjzoIicAXxgjJlywrkvBPpR+jXpeaAzcDqQ5jquCLgWvab5PR25UpVxBfC4MWaPMSYDeAx7UQLIB5oALY0x+caYX4zdwLIQCAU6iUiwMWa7MWaL6zk3Aw8aY1KNMXnAo8AlrqH2fKAB0NYYU2iMWWqMOVht36lSyte9YoxJN8bsBH4BFhtjkowxucBMbLJ1JTDbGDPbGFNkjPkBSATOK+fcTxtj9htjjkuOXKP11wF3GGN2uq5dv7mub3pNqwE0uVKV0RTYUeL2Dtd9AM8Bm4HvRWSriEwAMMZsBu7EJk57RGSaiBQ/pyUw0zVEnol9R1kINALeB74DprmmIP8tIsFV++0ppfxIeomvc0q5HYm9Bo0uvga5rkNnYt8oliXlJPdHA2HAllIe02taDaDJlaqMXdiLUbEWrvswxmQbY+4xxrQGRgJ3F9dWGWM+Msac6XquAZ51PT8FGGGMqVfiI8z1ji/fGPOYMaYTdnj9L8DV1fJdKqVqihTg/ROuQRHGmGdcj5uTPO9k9+8FcoE2f3qCXtNqBE2uVGVMBR4SkRgRiQYeBj4AEJG/iEhbEREgCzsCVSQi7UVksKvwPRf7jrHIdb5JwFMi0tJ1jhgRGeX6epCIdBWRQOAgdki9CKWU8pwPgAtEZJiIBLqKzgeKSHPX4+mA2/2rjDFFwNvACyLS1HXO01yLgfSaVgNocqUq40lsPcJKYBWwzHUfQDwwBzgELAReM8bMxdZbPYN9R5cGNAQecD3nJWAWdioxG1iELf4EaAzMwF6E1gE/Y4fVlVLKI4wxKcAo4J/YRTUpwH388TfyJWwd6AERednN096LvT4uAfZjR+oD0GtajSC21lgppZRSSnmCjlwppZRSSnmQJldKKb8mIm+LyB4RWX2Sx0VEXhaRza5mk72qO0allH/R5Eop5e/+Bwwv4/ER2FrBeGAc8Ho1xKSU8mOaXCml/JoxZj62oPhkRgHvGWsRUE9EyutvpJRSJ6XJlVKqpmvG8c0gU133KaVUpTi2t2B0dLSJi4tz6uWVUg5YunTpXmNMTPlHeh8RGYedNiQiIqJ3hw4dHI7IWUXGcORoITlHC+3n/EIKCotO2lVTgMAAITBAEMTewbFPyHG35U/PV6oqNK4bRnhIYPkHUrHrl2PJVVxcHImJiU69vFLKASKyo/yjqt1O7Ca6xZq77juOMWYyMBkgISHB1KTrV35hERvSslmeksnylExWpGSyOeMQxtg0qEt0BF2b1aVpvVo0iAihfkQIURHBREWEEhUeQv2IYCJDgxDRpEn5ropcvxxLrpRSykvMAm4VkWnY5rVZxpjdDsfkFYwxPPHVOj5cvIO8AttEvEFECD1i63FB96Z0j61H9+Z1qRce4nCkSnkXTa6UUn5NRKYCA4FoEUkFHgGCAYwxk4DZwHnYDcePAH9zJlLvM21JCm//uo0LujdlaKdG9IitR/P6tXQESqlyaHKllPJrxpix5TxugPHVFI7PWLvrII/MWsOA+GheurQHAQGaUCnlLk2ulFJKHedQXgHjP1pG/fBg/quJlSPy8/NJTU0lNzfX6VBqnLCwMJo3b05wcHClz+FWciUiw7EbVwYCU4wxz5zw+H+BQa6b4UBDY0y9SkellFLKEcYYHvhsFTv2HWbqjf2Jjgx1OqQaKTU1ldq1axMXF6fTsNXIGMO+fftITU2lVatWlT5PucmViAQCE4Fzsf1flojILGPM2hLB3FXi+NuAnpWOSCmllGM+XJzMlyt2cd+w9vRr3cDpcGqs3NxcTawcICI0aNCAjIyMUzqPO01E+wKbjTFbjTFHgWnYjsYnMxaYekpRKaWUqnard2bx+FdrObtdDH8/u43T4dR4mlg5wxM/d3eSK7e7F4tIS6AV8NMpR6aUUqraHMzNZ/xHy4gKD9E6K6VOkae3v7kMmGGMKSztQREZJyKJIpJ4qkNuSimlPMMYwwOfriL1QA6vXt6TqAjtW1XTZWZm8tprr1X4eeeddx6ZmZlVEFHZ/vWvf5X5eHXH5U5y5Vb3YpfLKGNK0Bgz2RiTYIxJiIlxbweM3PxC3vl1GwcOH3XreKWUUhXz/qIdfL1qN/cNa09CXJTT4SgvcLLkqqCgoMznzZ49m3r1qn8928mSK2MMRUVF1R6XO8nVEiBeRFqJSAg2gZp14kEi0gGoDyz0ZIDJ+4/w2JdrefvXbZ48rVJKKWBVahZPfrWOQe1jGDegtdPhKC8xYcIEtmzZQo8ePejTpw8DBgxg5MiRdOrUCYALL7yQ3r1707lzZyZPnnzseXFxcezdu5ft27fTsWNHbrzxRjp37szQoUPJyck56esNHDiQu+66i4SEBDp27MiSJUu46KKLiI+P56GHHjp23AcffEDfvn3p0aMHN910E4WFhUyYMIGcnBx69OjBFVdcwfbt22nfvj1XX301Xbp0ISUl5VhcAO+99x7dunWje/fuXHXVVVXy8yt3taAxpkBEbgW+w7ZieNsYs0ZEHgcSjTHFidZlwDRXQz6PadeoNiO6NOZ/v27nhgGtqVur8n0nlFJK/SErJ59bPlpKg8gQXhijdVbe6rEv17B210GPnrNT0zo8ckHnkz7+zDPPsHr1apYvX868efM4//zzWb169bH2BG+//TZRUVHk5OTQp08fLr74Yho0OH516aZNm5g6dSpvvvkmY8aM4dNPP+XKK6886WuGhISQmJjISy+9xKhRo1i6dClRUVG0adOGu+66iz179vDxxx/z66+/EhwczC233MKHH37IM888w6uvvsry5csB2L59O5s2beLdd9+lf//+x73GmjVrePLJJ/ntt9+Ijo5m//79lf0RlsmtPlfGmNnYLSJK3vfwCbcf9VxYx7t1cFu+WZ3Gu79t5/Yh8VX1MkopVWMYY7h/xkp2Z+by8U39qa91VqoMffv2Pa7v08svv8zMmTMBSElJYdOmTX9Krlq1akWPHj0A6N27N9u3by/zNUaOHAlA165d6dy5M02aNAGgdevWpKSksGDBApYuXUqfPn0AyMnJoWHDhqWeq2XLln9KrAB++uknRo8eTXR0NABRUVUzDe4THdo7N63LOR0b8taCbVx3ZisiQ30ibKWU8lqzV6Xx7Zo0/nleB3q31Dorb1bWCFN1iYiIOPb1vHnzmDNnDgsXLiQ8PJyBAweW2kk+NPSPBrSBgYFlTguWPD4gIOC45wYEBFBQUIAxhmuuuYann366QvE6wdOrBavMbYPjycrJ572F250ORSmlfN60Jck0q1eLG87UOiv1Z7Vr1yY7O7vUx7Kysqhfvz7h4eGsX7+eRYsWVUtMQ4YMYcaMGezZsweA/fv3s2PHDgCCg4PJz88v9xyDBw/mk08+Yd++fcfOURV8JrnqHluPs9vFMOWXbRw5WvZqBaWUUie3OyuHBZv3cnHv5lpnpUrVoEEDzjjjDLp06cJ999133GPDhw+noKCAjh07MmHChFKn36pCp06dePLJJxk6dCjdunXj3HPPZffu3QCMGzeObt26ccUVV5R5js6dO/Pggw9y9tln0717d+6+++4qiVU8XH/utoSEBJOYmFih5yzdsZ+LX1/IQ+d35AZd1aKUzxGRpcaYBKfjOFWVuX55k4lzN/Pcdxv4+b6BtGzg7PSJKt26devo2LGj02HUWKX9/Cty/fKZkSuA3i2jOL1NA96Yv5Xc/FL7lCqllCqDMYZPl6bSt1WUJlZKVRGfSq7A1l5lZOcx7fdkp0NRSimfsyw5k617D3NJ7+ZOh6JqoPHjx9OjR4/jPt555x2nw/I4n1t21791FH3jopj081bG9mtBaFCg0yEppZTPmLE0lVrBgZzXtYnToagaaOLEiU6HUC18buRKRLhtSFvSDuYyY2mq0+EopZTPyM0v5KsVuxjRtbG2tFGqCvlccgVwZttoesTW4/V5W8gvLHI6HKWU8gnfrUkjO69ApwSVqmK+kVztXgElVjWKCHcMiSf1QA4zk062h7RSSqmSZixNpVm9WvRv1aD8g5VSleb9ydXOpTB5IPz4+HEJ1sD2MXRtVpeJczdToKNXSilVpl2Z2ttKqeri/clV017Q6xpY8ALMf/7Y3SLCrYPbsmPfEb5cucvBAJVSyvvNTNqJMXBxr2ZOh6L8UGRkZJWde968efz2228nfXzWrFk888wzVfb6leH9FY0icP4LUJALc5+E4DA4/TYAzu3YiA6Na/PqT5sZ2b0ZgfpuTCml/sQYwwztbaV81Lx584iMjOT000//02MFBQWMHDny2KbP3sL7kyuAgAAY+apNsL5/CILCoO+NBAQItw2OZ/xHy/hm9W7+0q2p05EqpZTXWZZ8gG17D3PLwDZOh6Iq45sJkLbKs+ds3BVGnHy0Z8KECcTGxjJ+/HgAHn30UYKCgpg7dy4HDhwgPz+fJ598klGjRpX7UvPmzeORRx6hXr16rFq1ijFjxtC1a1deeuklcnJy+Pzzz2nTpg0ZGRncfPPNJCfbPpYvvvgizZo1Y9KkSQQGBvLBBx/wyiuv8NZbbxEWFkZSUhJnnHEG3bp1IzExkVdffZX09HRuvvlmtm7dCsDrr79ealJW1bx/WrBYYBBc9Ca0Pw9m3wtJHwAwoktj2jaM5JUfN1NU5MxWPkop5c1mLE0lPER7Wyn3XXrppUyfPv3Y7enTp3PNNdcwc+ZMli1bxty5c7nnnntwdwu9FStWMGnSJNatW8f777/Pxo0b+f3337nhhht45ZVXALjjjju46667WLJkCZ9++ik33HADcXFx3Hzzzdx1110sX76cAQMGAJCamspvv/3GCy+8cNzr3H777Zx99tmsWLGCZcuW0blzZw/9RCrGN0auigUGw+j/wdTL4ItbISiMgK6XcOugttz58XK+X5vO8C6NnY5SKaW8Rs7RQr5asZsRXZoQob2tfFMZI0xVpWfPnuzZs4ddu3aRkZFB/fr1ady4MXfddRfz588nICCAnTt3kp6eTuPG5f/d7dOnD02a2OS+TZs2DB06FICuXbsyd+5cAObMmcPatWuPPefgwYMcOnSo1PONHj2awMA/NxH/6aefeO+99wAIDAykbt26FfvGPcT3ftOCQuHSD+GjMfDZOAgK5S/dzufFORt5cc5GBndoSEiQ7wzIKaVUVfp+rfa2UpUzevRoZsyYQVpaGpdeeikffvghGRkZLF26lODgYOLi4sjNzXXrXKGhoce+DggIOHY7ICCAgoICAIqKili0aBFhYWHlni8iwrtrB30zCwkJh7FToVlv+ORvBG2Zw4QRHVmfls2DM1e5PUypVJXYtwXeHgEpS5yOpGoV5NkedMqrzViaSvP6tejXKsrpUJSPufTSS5k2bRozZsxg9OjRZGVl0bBhQ4KDg5k7dy47duzw6OsNHTr02BQhwPLlywGoXbs22dnZbp1jyJAhvP766wAUFhaSlZXl0Rjd5ZvJFUBobbjiE2jUCT6+kuHh67ljSDyfLE3ljflbnY7ueEWFTkegqtN3/4Tk3+CTa+HIfqejqRq7kuCNs+G9UZB70Olo1Ekc623VS3tbqYrr3Lkz2dnZNGvWjCZNmnDFFVeQmJhI165dee+99+jQoYNHX+/ll18mMTGRbt260alTJyZNmgTABRdcwMyZM+nRowe//PJLmed46aWXmDt3Ll27dqV3797HTTNWJ3FqlCchIcEkJiae+omO7If/nQ8HtmOu/JTbfg3j61W7mXRlb4Z19oL6q22/wLQroN9NMOiftrWE8l+b58AHF0P3sbBqBrQ9x46y+su/e8FR+OV523MusiGMfAXiz3X76SKy1BiTUIURVguPXb+q2MS5m3nuuw3Mv28QLRqEOx2OqoB169bRsWNHp8OosUr7+Vfk+uW7I1fFwqPg6i+gTjPkvVG8WP8TTm8ayJ3TlrN6pzPDgcfsSoKpY8EUwvx/w7ynnY1HVa3CfPj2n1C/FVzwEgx9AjZ+Awv9ZBf49DUwZTD8/Cx0HQ23LKxQYqWqV3Fvq36tojSxUqqa+X5yBfYd9N9mQ9cxBC1+nfcPjePWkK8Y/79fST/oXrGdx2VstCMYterD+MXQ80r7R2med3WRVR6U+Dbs3QDDnrILL/rdDB3+AnMegVTvH+U4qcIC+OU/dhowO80uKLnoDft/W3mt4t5WWsiuqsuqVavo0aPHcR/9+vVzOixH+N5qwZOJbAgXToTTxhMw51HGb3qfiwpmM3XyVdx064PUCgupvlgyU+D9C0EC4OrPoW5zuOAVuzfivKft/Wf/o/riUVXvyH6Y+y9oPdD2YgM7FTjqVZh0FnzyN7h5vu8lJBkb4fOb7R6fnS6E8/8DEdFOR6XcoL2tVHXr2rXrsSL0ms4/Rq5KatQJrpgO13xFeIOm3HnoRfa/0JeiDd8dt/FzlTmUYROrvENw5WfQwNUROSDA1qd0Hwtznzpun0TlB+b+C/IOwrCnj6+vqlUfRr8D2btsbzZfWclaVAi/vQpvDID9W+GSt2HMu5pY+QjtbeUfdOW7Mzzxc/ff37pWA6h72y/8OOMN2qx6gYCpYyBuAJz7mG3hUBVys+CDiyBrJ1w1E5p0O/7xgEAYNRFMEfz0hB3BGnB31cSiqs+edXZKMOE6m9yfqHkCnPOo3bpp8RvQ/+bqjrBsBXmQlQoHtkPmDjiwA7b/Yker2o2w9WO1GzkdpaoA7W3l+8LCwti3bx8NGjRA/GVBjA8wxrBv3z63em2VxX+TKwARBl9yEw+aPgSteJcHd31J6JuDodVZ0OVi6DjSFsR7Qn4OfHQZ7FkLY6dBy9NKPy4gEC583SZYPz5mE6wz7/RMDKr6GQPfPmBbgwx68OTHnXYrbF9gE6zYvtCsV/XFWMwY2PIjpPxuE6jiRCp7N1DinVpAMNSPs/9Pu4/1n5WONciMpanERmlvK1/WvHlzUlNTycjIcDqUGicsLIzmzU/tjYl/J1eAiPDoRT25OvMo/XeczVd9V9Nsxxfw5R3w9T3QZjB0vgg6nA9hdSr3IoX5tqdR8kK4eEr5K6gCAuHCSTbBmvOIvX36bZV7beWsDd/A1rkw/NmyE3URm6xMGgAz/gY3zYewatqWoagQ1s2yRelpqwCBOs2gfktbI1a/JdRrAfVa2q9rN7H/J5VP2p1le1vdPjhee1v5sODgYFq1auV0GKqS/D65AggJCmDSlb25cGIuI1eezue33Ets3iZY8xms/gw23QyBoTYp6nIxtBsGIW621i8qgs9vgY3fwvkvQNdL3HteYBD8dbJNsL5/yI5gnTa+8t9kZeQehMAQCD614c8aqyAPvn8QottDn+vLPz48ytYuvTMCZt1u98msylGhwnxYOR0W/Bf2bYIGbWHUa/b/aFBo+c9XPunzpF0YAxf1auZ0KErVWDUiuQKoFx7CW9f24a8Tf2XslMVMvbE/sec+Duc8BqlLbJK1Zias/wqCw6HtEIhqDZGNXB8NIbKx/RxW1/5RNAa+vR9WTYchD7v3B7akwCC46E2bYH33Tzh6BBL+5rmi4aIiO+VzYJutp9nv+lx8+8g+CKtnpyX73mS3FVLuW/yGLfa+4lO7qbg7WvSDIf8Hcx6FxLegzw1/PqawAPZvsX2l0tfY9g4RMdCku/1o2Kns5Cg/B5I+gF9fgqwUaNzVJnIdR+qIlJ8zxvDZslQSWtanZQPv3ntNKX/m+x3aK2hlaiZXvfU7tYID+ejGfrSOifzjwaJCO7W3+lPY/KNNTAqP/vkkgaE24QqtDXvW2Cm9c5+o/ChEYT7MuM5O3YD94xk3AFoNgJZnuFcXlnMAdq+E3cvtfm9pq20CVZj3xzESaNtC1I+DqFZ2Gih5IWz63iaOZ/8Del3tfqJQkx3aAy/3gpan29WpFVFUZDce3zbfbuFkCiF9rU2k9qyBPev/+HeTQJvkH95jF0yArYlq2NEmWk17QJMe0Kiz/X+U+LZtWnp4D8T2gwH32hFZL6mb0g7tVWv1ziz+8soCnvprF67o19LpcJTyKxW5frmVXInIcOAlIBCYYoz5UydMERkDPIqtjF1hjLm8rHM6eXFat/sgV05ZjIjw0Y39aNeodukHGgO5mfYP6aF0+zk77Y+vD6VB876e2damqAh2Jto/uNt/geTFUJADiB15aHWWTbhanmaTwN3LYZcrkdq93CZSxerGQuNutg1EcSJVP87eX1ritOM3+PFxm2jVb2ULs7tcbNtHqNLNug2WfwS3LILo+Io///BemHSmq5jcJbKxTZIadYJGXWySHdPejlIZY/+Ni5PnXcvt1zkH7HMl0B6Xf8TWEQ64xybmXpJUFdPkqmo99uUaPlyUzJIHz6FuuL5JUuqkjLGzNyEREFzLrad4NLkSkUBgI3AukAosAcYaY9aWOCYemA4MNsYcEJGGxpg9ZZ3X6YvT5j3ZXP7mYgqKDO9f35fOTaupuNhdBXl2Kfy2X2yylfK7azRDOG5lV72Wf4xeNOluP0c0qPjrGQObfrArGNNXQ6Oudvoqfmjpf6CLiuz0YvpqWySdttrGN/ABuxrOn+1eYbuV978Fhv+r8udJX2v/bRt2hIadK/7vZoyd9itOto7sg15XVV2rEQ/Q5Krq5BcWcdrTP9InLorXr/Te/wNKVZviBGr/Vti3xX7ev8X19TbIy4IrP7V7wLrB08nVacCjxphhrtsP2JjN0yWO+Tew0Rgzxa0I8Y6L0/a9h7liymKyc/N57/p+9Iit52g8ZcrPhdTf7ShTUJgroeru+Y7fRUW20P+nJ23yFNsfBj8IwRGQtvKPZCp9DRw9ZJ8jARDdDnIy7Whez6tsLVtlkjxvZwy8c56tg7ptGdTy4v8zXkiTq6rz0/p0rvtfIm9encC5nbQvWZmKCuHgzhJ/cLfa2YjTxttra0129IhdBAO2BrhOU2fjqYjcLNgyFzbPsX+r9m21CVQxCbAro6NaQ1Qb+7nDeXZmxw0VuX65U9DeDEgpcTsVOHGzoHauF/4VO3X4qDHmW3cCcFJcdAQf39Sfy99czJVTFvPO3/rQJ85L+8IEh9mpwVZnVe3rBATY1WSdRsGy9+Dnf8O7F/zxeEhtaNwFelxup64ad7UjL8G1bFf6n5+FRa/ZhQFDHoFe1/jX9OKamZD8G/zlv5pYKa/y6bKdREWEcHa7GKdD8S6ZKbautDiJ2rflz/WoQbUgIAi2/AQ3zLGlFL4kLxt2LnO94T6F69LuFTDjeru6GIEFL9iFMP1usjWcFS0zMMa+Kd+/1b3jazexCU9EjHuvZYxNojb9YBOq5EW2hjW0LjTvDd3G2PM1aGOTqXotIKh6tsLz1GrBICAeGAg0B+aLSFdjTGbJg0RkHDAOoEWLFh566VPTvH440286jcunLOLqt35nyjUJnNFWt/ggMNiufuw+FtZ+bov3G3Wx05AnS5ZCI2HoEzbx+voe+OpOSHrf7kfXtGf1xu9JeYdssrhiKmz92f4cel3jdFRKHZOVk88Pa9MZ2yeWkCA/ejNzqg7sgCnn2AUeQWH2D210PLQffvzoRe0mdrrorXPhw0vg+h8812C6Khhjd4bY/INNLJIXQVE+1IqyMw29rrWr0d1VVAQLX7W1txHRcPUX9lq/ZAose9/OZjTpbjej73xR2e17cjJt779Nc2x8h9Ir/v2F1IYGrf/4N2rQ5o+vg0Jg6zybMBcvPAP7Rv+MO+wCnuZ9K/b9VwFPTQtOAhYbY95x3f4RmGCMWXKy83rbsHpGdh5XTlnMtn2HeeOq3gxq39DpkHybMbbH0vcPweEM23Jg8ENlv6s6vBcy1kPGBrsdS70Wtqi7YYfqa7hZrKjQ/gKv/BjWfWkLxeu1hG6X2qSzduPqjcdP6LRg1Zj2ezITPlvFF+PPoLs3lze4Iz/XbiPWpDsMfaryI985B+CtofaP+9VfQOPu5Z9rx0J4b5R9M3j1F5XrAXhgB3x6vV2AdM4jlYu9NHnZ9s3d5h9s4nIw1d7fsJOtGWqeAIsnw44FENPR1oO2GVz+eQ/utpuzb50HHf5i98AtmVgePWyvg4vfsNfn8Gg7XZhwnZ0yNMaWihQneim/29GjsLr29duea6dapZyfvSmCg7v+XBuVmWzPd6LQutBmkE2m2p5TLddkT9dcBWEL2ocAO7EF7ZcbY9aUOGY4tsj9GhGJBpKAHsaYfSc7r7ddnAD2Hz7KVW8tZmN6Nq9e3othnfUP6CnLybQbVS+ZAuENbMuKVmfZmqWMkh/rIWd/iSeeULhfpxnEdHAVf7s+otvb0TJPSlttR6hWzbD1Y2F1ofNfodtl0KK/162+8zVOJFflrYr0lh4AACAASURBVHYWkRbAu0A91zETjDGzyzqnt12/xryxkL2H8vjx7rN9fx+6H5+AX1wb2/f+m23OXNEEqyAP3v+r7WF41ecQd4b7z139md1FodOFcMk7FXvt1KUw9VL7RhFje+DFu1csfVKbf7Q1UMWjUyG1ofXZfyQVdUts02KMHWX//iE79dluBAx9EqLbln7u9V/bDeXzc2D409D72pNf44yBbT/bBG7DbNszL26AHUE7lGaPadzNxhU/FJoleGb0qDDfJljFSVfeQYg705HRqapoxXAe8CL2wvO2MeYpEXkcSDTGzBL72/wfYDhQCDxljJlW1jm97eJULCsnn2ve/p1VO7P46rYz6dikklviqOPtWm6nCnee8G8eVs8mTTHt7Ofo9rb9QJ2mdiXcnvWQsc7+Au9ZZxOxkrUSkY1sUX9YPTsqVvz5uPvqQlGBLdTMP2zfiZX29d7Nts9UQJC9OHS7FNoN1w72HlTdyZWbq50nA0nGmNdFpBMw2xgTV9Z5ven6lbL/CAP+PZf7hrVn/KCT/BH1Felr4I2zoOtoOxKx4L8VT7CKiuCzG2y/wovfcn/XjJJ+fRl++D/bw3Dok+49Z+0X8Nk4e0269AP7dc5++PvCyi/uSVttpzUjG0LnC+0oUGy/8uuGCvJg0esw/3nb0qfvTbaPYfHMwdEjtnH10nfsCOFFU+w12F37t9k3zBu+gSbdbFxtz/H7Dd49nlxVBW+6OJ0o88hRBvx7Lqe1bsDkq31+BsN7FK9EzDlgE6iYDu4XLh47R6F9R7ZnrU28MnfYXmQ5ma7PWfZz3sHyzxUYanuchETYrvyRDW0hf+eL/HOloxdwILlyp6zhDWCrMeZZ1/H/McacXtZ5ven69cqPm/jPDxtZcP8gmtf34V0WigrtNN6BbTB+iZ2a+vGxiidYcx61zznnUTjzrsrFYgzMvg+WvAkjnoN+48o+9teX7D6xzfvC2Km2biltFUweZLdTu/SDio9652TCm4NsInTT/MolLof2wE9P2LqpWvVtPVbTXjDzJti7EU6/HQb/X7UVefs6T68WrHHqhYdww5mt+e+cjaxKzaJrcy/rgeWrilcintI5Am1xY4M20PGCkx9XWGCX5ea6kq6A4D+SqOLPDhc8qmrhzmrnR4HvReQ2IAIodR7HGxfkGGP4LGkn/VtH+XZiBXYkZGei3RKs+M3NEFfNUnFrgPISrCVv2WMTroMz7qx8LCIw4llb+/nt/VC3GXQ4/8/HFebD13fbldWdL7KbsxePdDfuautM5zwCyz+Enle6//rFe9ZmJsO1X1d+RCiyoa2h6nMjfPuAnT0AW8B/9Rd243ZVJXRZyUlcd2YcdWsF8+KcjU6HoiojMMheoBu0sU01m7g61tdpAmF1NLFSJY0F/meMaQ6cB7wv8ufqW2PMZGNMgjEmISbGO9odJKVksm3vYS7q1bz8g71ZVqpdqdZmiJ0SLCZiE6wz77JTWF/fbROP0mz4FmbfC/HD7GjTqdaeBQTCJW/Zxswzrrf1VCXlZtmVhcveszsiXPzWn0sITr/N7pTwzf12Ks1dv74IG762U5It+p/a9wH2+nftV3YErf94+PtvmlhVMU2uTqJ2WDDjzmrNj+v3kJR8wOlwlFKVsxOILXG7ueu+kq7H7jCBMWYhEAb4RD+Wmct2EhoUwIguXrD4pqCUfVjdYYwdUTFFtn/ciUmROwnWzmW2CL1xN7jkbc+9eQqJgMs/tiNAH435I0E6sMNOYW5fAKMmwpCHSx9RCwiEv06yK+Vm3mynPsuzdZ6dyut8kW194CkidrR/+L+8u82En9DkqgzXnh5HVEQI/52zyelQlFKVswSIF5FWIhICXAbMOuGYZOxqaESkIza5yqjWKCvhaEERX67cxbDOjakd5vA+gilL4NmWMPsfdkq+ItbMhI3f2j1N659ks+myEqwDO+CjS22LgMune34FcWRDu0WKKbQjVZt+gClDbH+lKz8rf7qvXgs473lIWfTH9ObJZO20o2TR7ex0nq+v/KzBNLkqQ0RoEDef3Zr5GzNI3L6//CcopbyKMaYAuBX4DlgHTDfGrBGRx0VkpOuwe4AbRWQFMBW41ji10qcC5m7YQ+aRfP7aq1nFnlhUCKmJMPdp+PRGOHKK17a8Q/DZjXZ05vc3YNrltieTO3IO2CmzJj3KH6UpLcE6st8mPIV5cMUnVbdaLToeLptqu71/eImt2bz+B9sSwR3dxtiWLvOehl1JpR9TcBQ+uQYKcmHM+55PElW10sKTclzVP47J87fx3zkb+fAGD8x9K6Wqlatn1ewT7nu4xNdrgQo0QvIOny1LJToylAHu7ChxeK/tl7T5B/s5Zz8gNiHKzYSxH1e+Wed3/7QreK/9yrZKmX0fvD3CTqfVLSfx++Fhu7HulTPcm8orTrDAjgKtm2UTuatm2mbDVanlaTD6f3bF87CnIbICdXcithg/ebFt0TDuZwg5YQHCd/+0fblGv1uxtgjKK+nIVTlqhQTy94Ft+HXzPhZtPWlPVKWUqjaZR47y0/o9jOrRlKDAUi7jJUen3hwMz7WFmePsprbxQ23x9T+2wnn/ttuIzH+ucoGsnw3L3rWF23Fn2t0Lrphuk60pQ+xedSezfYEtBj9tvO215K6SI1g5B2DUa/a1q0OH8+DiKRVLrIqFR8GFr9kWCD88fPxjKz62bR9Ou9X2s1I+T0eu3HBFvxZMnr+FF37YyMfj+vt+B2SllE/7cuVu8gsNF5WcEjzZ6FTzBBj4gO0U3qTn8SNUCdfbeql5T9tVtRXpJn5oD8y6DRq5Wg4Ua3sOXP8dfDjGjmBd8ha0H3H8c/Nz4cs7oH6cja2iRFx9rO62q399RZtB0O/vsPh126A4/hzbKPTLO+yqwnMeczpC5SGaXLkhLDiQ8YPa8vAXa/htyz7d2Fkp5b75z9tl+yU3n63dpPLTcNgpwU6NwulUuBHmujbI3bkMMLawO36o3YakzeCyV4aJ2BV66attV/NxP5+8qLwkY2xilZdtpwODQo9/vFFnuPFHmHqZrcEa9jT0L1FTNf852LfZTuedOD1WEb6UWBU75xG7sfEXt8B138L0q+wuEpe8oy1i/Ij+S7rp0j6xvD7Pjl6d3qaBjl4ppdyT8rv9Y1pYolVBUC2IauVKtlrbxKt+HASVv9XSnpRNXL17KsPD1iBvZVLu6FR5QsJhzHu2m/j0q+G678rf8mnp/+wKv2FP230+S1O7sW2A+dk424hz/xZ7/N4Nto9T97HubSzsb4Jr2Uapbw6G18+0xfjXfOX3W8fUNJpcuSk0KJBbB7flwZmr+XljBgPbN3Q6JKWUL7hiuq2BOrjzj81n92+1X+/dZGueCt3vEdUQGBBQB9oOg07Dyx+dckeDNrYf07Sx8M0/YOTLJz923xZbfN3q7PJX+IVE2MTth4dh4au2bcKRfXakZuhTpxazL2vS7Y/u7cOetsXyyq9oclUBo3vb0av//rCRs9vF6OiVUso9AYG231G9FrbupqTixOvADijKL/M0RUVww4wtFMR04b1LPfwHucN5toZpwQsQ27f0/k2FBXYkKjDYbvXizghZQCAMe8qO1M3+h+0XVXKLm5rqjDtsU8+o1k5HoqqAJlcVEBIUwO2D4/nHpyv5af0ehnTUYVyl1CkqmXiVI3Hbfn7KyuG/w2PLPbZSBj8EO5fajumNu/55Fd8vz9v9/y55u/w2CyfqcwM0aAu7lh+/xU1NJWJHDJVf0lYMFfTXXs1o2SCcF37YiA/0GVRK+ZHZq3ZTKziQYZ2raLubgECbOIU3gI+vsq0OiqUmws//hm6XQpeLK3f+1gPhzDu187jye5pcVVBwYAB3DIlnza6DfLcm3elwlFI1yNIdB+jZoh7hIVU46RARbeukDu6yU4BFRX90Ya/TFM6rZE8spWoQTa4qYWT3prSOieDFORspKtLRK6VU1cs5Wsi63Qfp2aJe1b9Y8wQY8Ywttv/lefj+Qbtp8V8n2WJ0pVSZNLmqhCDX6NX6tGy+WZ3mdDhKqRpg9a4sCooMPWPrV88LJlwP3S6Duf+yrReKu7ArpcqlyVUl/aVbU9o1iuTBz1fx4zqdHlRKVa2kZFv/1KM6Rq7gjwajTbpB057Hd2FXSpVJk6tKCgwQJl+VQNO6tbj+3USe+GotRwuKnA5LKeWnkpIzaREVTnRkaPkHe0pIONzwE1z/w5+7sCulTkqTq1MQFx3BZ7eczjWnteStBdu4ZNJv7Nh32OmwlFJ+KCk5s3rqrU4UGGT7Wiml3KbJ1SkKCw7ksVFdmHRlb7bvPcz5Ly/gyxW7nA5LKeVHdmflkHYwl56xDiRXSqkK0+TKQ4Z3aczsOwbQrlEkt01N4oHPVpJztNDpsJRSfiApOROAni2qqZhdKXVKNLnyoOb1w/n4ptP4+8A2TP09hVETF7ApPdvpsJRSPi4p+QAhQQF0bFLH6VCUUm7Q5MrDggMDuH94B967ri/7Dx/lglcX8PGSZO3mrpSqtKTkTLo2q0tIkF6ylfIF+ptaRc5qF8Ps2wfQu2V97v90FVN/T3E6JKWUDzpaUMSqnVlab6WUD9Hkqgo1rBPGe9f1o29cFC/8sJHDeQVOh6SU8jHr0w6SV1Ck9VZK+RBNrqpYYIAw4bwO7D2Ux5RftjkdjlLKx/xRzK4jV0r5Ck2uqkGvFvUZ0aUxk+dvYe+hPKfDUUr5kKTkAzSqE0qTumFOh6KUcpMmV9Xk3mHtyS0o4pUfNzkdilLKhySlZNIztj4i4nQoSik3aXJVTdrERHJZn1g+XJysXdyVUm7ZdyiPHfuO6JSgUj7GreRKRIaLyAYR2SwiE0p5/FoRyRCR5a6PGzwfqu+7Y0g8wYEBPPfdBqdDUUr5gOUp2jxUKV9UbnIlIoHARGAE0AkYKyKdSjn0Y2NMD9fHFA/H6Rca1gnjxgGt+GrlblamZjodjlLKyyUlZxIYIHRtVtfpUJRSFeDOyFVfYLMxZqsx5igwDRhVtWH5rxvPak1URAjPfLNeG4sqpcqUlHKAjk1qUysk0OlQlFIV4E5y1Qwo2QEz1XXfiS4WkZUiMkNEYj0SnR+qHRbMbYPb8tuWfczftNfpcJRSXqqwyLAiJYuesTolqJSv8VRB+5dAnDGmG/AD8G5pB4nIOBFJFJHEjIwMD72077miX0tio2rxzDfrKSrS0Sul1J9t3nOIQ3kFWsyulA9yJ7naCZQciWruuu8YY8w+Y0xxA6cpQO/STmSMmWyMSTDGJMTExFQmXr8QEhTAvUPbs273Qb5YsbP8Jyilapyk5AOAFrMr5YvcSa6WAPEi0kpEQoDLgFklDxCRJiVujgTWeS5E/3RBt6Z0aVaH57/bSF5BodPhKKW8TFJyJvXCg4lrEO50KEqpCio3uTLGFAC3At9hk6bpxpg1IvK4iIx0HXa7iKwRkRXA7cC1VRWwvwgIECYM78jOzBzeX7jD6XCUUl4mKeUAPWPrafNQpXxQkDsHGWNmA7NPuO/hEl8/ADzg2dD835nx0QyIj+bVuZsZ0yeWOmHBToeklPICB3Pz2bTnEBd0a+p0KEqpStAO7Q67f3gHMo/kM2neFqdDUUp5iZUpWRij9VZK+SpNrhzWpVldLuzRlLd/3UZaVq7T4SilvEBS8gFEoFusNg9VyhdpcuUF7hnansIiw0s/bnQ6FKWUF1iWfID4hpFaKqCUj9LkygvERoVzVf84pi1J4bct2lhUqZrMGENSSqY2D1XKh2ly5SXuGdqOVtER3DltOXsP5ZX/BKWUX9q+7wiZR/K1eahSPkyTKy8RERrExMt7kZmTz93TV2jndqVqKG0eqpTv0+TKi3RsUodHLujE/I0ZvDF/q9PhKKUckJScSWRoEG0bRjodilKqkjS58jKX923B+d2a8Pz3G1i6Y7/T4SilqllSygG6x9YlMECbhyrlqzS58jIiwtMXdaVZvVrc9lESmUeOOh2SUqqa5BwtZN3ubC1mV8rHaXLlheqEBfPq5T3JOJTHvZ+sxBitv1KqJli1M4vCIqPF7Er5OE2uvFS35vV4YERH5qxL551ftzsdjlKqGhQXs/eI1eRKKV+myZUX+9sZcZzTsRFPf7OOlamZToejlKpiScmZtGwQToPIUKdDUUqdAk2uvJiI8PzobsREhnLrR0kczM13OiSlfI6IDBeRDSKyWUQmnOSYMSKyVkTWiMhH1R0j2Oahy5IP0FNHrZTyeZpcebl64SG8cnlPdmbm8MBnq7T+SqkKEJFAYCIwAugEjBWRTiccEw88AJxhjOkM3FntgQK7s3LZk52n/a2U8gOaXPmA3i2juHdoe75euZuPfk92OhylfElfYLMxZqsx5igwDRh1wjE3AhONMQcAjDF7qjlGwE4JAlrMrpQf0OTKR9x0VmvOahfDY1+uZe2ug06Ho5SvaAaklLid6rqvpHZAOxH5VUQWicjwaouuhKTkA4QGBdChcR0nXl4p5UGaXPmIgADhhTHdqRMWzGNfrnE6HKX8SRAQDwwExgJvisifho9EZJyIJIpIYkZGhseDSErJpGuzuoQE6WVZKV+nv8U+JDoylFsGtmHxtv3avV0p9+wEYkvcbu66r6RUYJYxJt8Ysw3YiE22jmOMmWyMSTDGJMTExHg0yKMFRazamaVTgkr5CU2ufMxlfWOJighh4twtToeilC9YAsSLSCsRCQEuA2adcMzn2FErRCQaO01YrZt7bkzP5mhBEd11paBSfkGTKx8THhLEdWfE8dP6PazZleV0OEp5NWNMAXAr8B2wDphujFkjIo+LyEjXYd8B+0RkLTAXuM8Ys68649yQlg3YzduVUr5PkysfdNVpcUSGBvH6PB29Uqo8xpjZxph2xpg2xpinXPc9bIyZ5fraGGPuNsZ0MsZ0NcZMq+4YN6ZnExIUQMuo8Op+aaVUFdDkygfVrRXMVae15OtVu9maccjpcJRSp2hDejZtYyIJCtRLslL+QH+TfdT1Z7YiJDCAST/r6JVSvm5jWjbtG9d2OgyllIdocuWjoiNDGdu3BZ8t28nOzBynw1FKVdLB3Hx2ZeXSrpEmV0r5C02ufNiNZ7UG4M351bqwSSnlQZvSbTF7+8aRDkeilPIUTa58WLN6tfhrz2ZMW5LM3kN5ToejlKqE9a6VgjpypZT/0OTKx908sA15BUW8vWCb06EopSphY1o2ESGBNKtXy+lQlFIeosmVj2sTE8l5XZrw/sIdZOXkOx2OUqqCNqRn065xbUTE6VCUUh6iyZUfuGVQG7LzCvhg0Q6nQ1FKVYAxhg1p2bTXKUGl/IomV36gc9O6DGofw1sLtnHkaIHT4Sil3LT30FEOHMnXeiul/IxbyZWIDBeRDSKyWUQmlHHcxSJiRCTBcyEqd4wf1Jb9h48y7fcUp0NRSrlp47GVgppcKeVPyk2uRCQQmAiMADoBY0WkUynH1QbuABZ7OkhVvoS4KPq2imLy/K0cLShyOhyllBs26EpBpfySOyNXfYHNxpitxpijwDRgVCnHPQE8C+R6MD5VAeMHtSXtYC4zk1KdDkUp5YaN6dlERYQQHRnidChKKQ9yJ7lqBpSca0p13XeMiPQCYo0xX5d1IhEZJyKJIpKYkZFR4WBV2c6Kj6Zrs7q8Pm8LBYU6eqWUt9uQnk27RpG6UlApP3PKBe0iEgC8ANxT3rHGmMnGmARjTEJMTMypvrQ6gYgwflAbtu87wuzVaU6Ho5QqgzHG7imoU4JK+R13kqudQGyJ281d9xWrDXQB5onIdqA/MEuL2p0xtFNj2sRE8NrczRhjnA5HKXUSOzNzOHy0kHZazK6U33EnuVoCxItIKxEJAS4DZhU/aIzJMsZEG2PijDFxwCJgpDEmsUoiVmUKCBDGD2rL+rRsPvo92elwlFIncWyloI5cKeV3yk2ujDEFwK3Ad8A6YLoxZo2IPC4iI6s6QFVxF/ZoxlntYnj8y7XHViMppbzLhrRDAMRrcqWU33Gr5soYM9sY084Y08YY85TrvoeNMbNKOXagjlo5KyBA+M/o7tQOC+a2qcvIOVrodEhKqRNsTM+mSd0w6tYKdjoUpZSHaYd2PxVTO5QXxnRnY/ohnvh6rdPhKKVOsCEtW/tbKeWnNLnyY2e1i+Gms1vz0eJkZq/a7XQ4SimXgsIiNmcc0s7sSvkpTa783L1D29Mjth73f7qSlP1HnA5HKQXs2H+EowVFOnKllJ/S5MrPBQcG8MrYnmDgjmlJ5GtzUaUctzFNVwoq5c80uaoBYqPC+ddFXVmWnMmLczY6HY5SNd6G9GxEoG3DSKdDUUpVAU2uaogLujfl0oRYXpu3hd8273U6HKVqtI3p2bSMCqdWSKDToSilqoAmVzXIIyM70To6gjs+Xs7eQ3lOh6NUjaUrBZXyb5pc1SDhIUG8enkvsnLyufeTFRQV6fY4SlW33PxCtu87oisFlfJjmlzVMB2b1OH/zu/IvA0ZvP3rNqfDUarG2ZpxmMIioyNXSvkxTa5qoCv7t2RY50Y8++16VqVmOR2OUjXKsT0FdeRKKb+lyVUNJCI8e3E3YiJDuXv6cgp1elCparMhPZvgQCGuQYTToSilqogmVzVUvfAQHvpLJzbtOcSXK3Y5HY5SNcbGtGxaR0cSEqSXX6X8lf5212DDOzemQ+PavPTjJgq0uahS1WJDejbtdEpQKb+myVUNFhAg3H1uO7btPczMpJ1Oh6OU3zuUV0DqgRzaN9LmoUr5M02uarhzOzWia7O6vPzTJt0aR6kqtslVzK4rBZXyb5pc1XAidvQqZX8OM5amOh2OUn5NVwoqVTNocqUY2D6Gni3q8cqPm8grKHQ6HKX81oa0Q4QFBxBbP9zpUJRSVUiTK3Vs9GpXVi7Tl6Q4HY5Sfmtjut32JiBAnA5FKVWFNLlSAJzZNpq+cVG8Onczufk6eqVUVdiQrnsKKlUTaHKlADt6dde57Ug/mMeHi5OdDkcpv7P/8FEysvNor8mVUn5Pkyt1zGltGnB6mwa8Pm8zR44WOB2OUn6luJhde1wp5f80uVLHufvcduw9dJT3F+5wOhSl/MqxlYI6cqWU39PkSh0nIS6Ks9rFMOnnLRzK09ErpTxlQ1o2dcKCaFQn1OlQlFJVTJMr9Sd3n9uOA0fyefe37U6HopTf2JieTfvGtRHRlYJK+TtNrtSf9Iitx5AODZk8fysHc/OdDkcpn2eMYUNatjYPVaqG0ORKlequc9uRlZPP2wu2OR2KUj4v/WAeB3MLtN5KqRpCkytVqi7N6jKscyPe+mUbWUd09EqpU7FB9xRUqkbR5Eqd1J3ntCM7r4A3f9nqdChKVZqIDBeRDSKyWUQmlHHcxSJiRCTB0zFsTNPkSqmaRJMrdVIdm9Th/G5NeOfXbew/fNTpcJSqMBEJBCYCI4BOwFgR6VTKcbWBO4DFVRHHhvRsGtYOpX5ESFWcXinlZdxKrsp75yciN4vIKhFZLiILSrt4Kd9055B4cvILeerrdU6HolRl9AU2G2O2GmOOAtOAUaUc9wTwLJBbFUEUrxRUStUM5SZXbr7z+8gY09UY0wP4N/CCxyNVjohvVJtbB7Xl02WpfLF8p9PhKFVRzYCSu5Gnuu47RkR6AbHGmK+rIoCiInNsw2alVM3gzshVue/8jDEHS9yMAIznQlROu31IPL1b1uehmatJ2X/E6XCU8hgRCcC+GbzHjWPHiUiiiCRmZGS4/RopB46Qm1+kKwWVqkHcSa7KfecHICLjRWQLduTqds+Ep7xBUGAAL17aAwRun5ZEfmGR0yEp5a6dQGyJ281d9xWrDXQB5onIdqA/MKu0onZjzGRjTIIxJiEmJsbtADak6Z6CStU0HitoN8ZMNMa0Ae4HHirtmMq+81POi40K519/7UpSciYvzdnkdDhKuWsJEC8irUQkBLgMmFX8oDEmyxgTbYyJM8bEAYuAkcaYRE8FULynYHzDSE+dUinl5dxJrsp753eiacCFpT1Q2Xd+yjtc0L0po3s3Z+K8zSzcss/pcJQqlzGmALgV+A5YB0w3xqwRkcdFZGR1xLAh/RCxUbWICA2qjpdTSnkBd5KrMt/5AYhIfImb5wM6tOGnHh3ZmVYNIrjr4+Uc0PYMygcYY2YbY9oZY9oYY55y3fewMWZWKccO9OSoFcCm9Gytt1Kqhik3uXLznd+tIrJGRJYDdwPXVFnEylERoUG8PLYn+w7ncf+nKzFG1y4oVZbPx5/B0xd1czoMpVQ1cmuc2hgzG5h9wn0Pl/j6Dg/HpbxYl2Z1uX94B578eh0fLk7myv4tnQ5JKa8VFhxIWHCg02EopaqRdmhXlXLdGa04q10MT3y19ljBrlJKKaU0uVKVFBAg/Gd0d2qHBXH71CRy8wudDkkppZTyCppcqUqLqR3K86O7sz4tm6dn6/Y4SimlFGhypU7RwPYNuf7MVry7cAdz1qY7HY5SSinlOE2u1Cn7x/D2dG5ah/tmrCAtq0r2vVVKKaV8hiZX6pSFBgXy8tie5BUUcce0JAqLtD2DUkqpmkuTK+URbWIieWJUFxZv28/LP2oPWaWUUjWXJlfKYy7u3ZyLejXjlZ826fY4SimlaixNrpRHPTGqC3HREdz5cRL7DuU5HY5SSilV7TS5Uh4VERrEq2N7ceBIPvd+soIirb9SSilVw2hypTyuU9M6/N/5HZm7IYO3FmxzOhyllFKqWmlyparElf1bMqxzI579dj3LUzKdDkcppZSqNppcqSohIvz74u40qhPGbVOXcTA33+mQlFJKqWqhyZWqMnXDg3l5bE92ZebywKerMEbrr5RSSvk/Ta5Ulerdsj73Dm3P16t289HvyU6Ho5RSSlU5Ta5UlbvprNac1S6Gx79cy/q0g06Ho5RSSlUpTa5UlQsIEF4Y0506tYIZ/+EyjhwtcDokpZRSqspocqWqRXRkKC9e2oOtew9z34yVuv+gUkopv6XJiX8l0AAAGEdJREFUlao2Z7SNZsLwDny9cjcPfb5aC9yVUkr5pSCnA1A1y01ntyErJ5/X5m2hTlgQE0Z0QEScDksppZTyGE2uVLW7b1h7snMLeGP+VluHNait0yEppZRSHqPJlap2IsJjIztzKK+A577bQGRoENecHud0WEoppZRHaHKlHBEQIDx3STcO5RXwyKw1RIYGcXHv5k6HpZRSSp0yLWhXjgkKDOCVsT05o20D7puxgm9XpzkdklJKKXXKNLlSjgoLDmTyVQl0j63H7VOT+GVThtMhKaWUUqdEkyvluIjQIP53bV9ax0Qw7r2lLN2x3+mQlFJKqUrT5Ep5hbrhwbx/fT8a1w3j2neWsGZXltMhKaWUUpWiyZXyGjG1Q/nghn7UDg3i6rd+Z/OebKdDUkoppSpMkyvlVZrVq8X7N/RDRLhs8mI27znkdEhKKaVUhWhypbxOm5hIpo3rB8DYNxexJUMTLKWUUr7DreRKRIaLyAYR2SwiE0p5/G4RWSsiK0XkRxFp6flQVU3StmFtpt7YD2MMYycvYqsmWEoppXxEucmViAQCE4ERQCdgrIh0OuGwJCDBGNMNmAH829OBqponvlFtPrqxP4VFhrFvLmLb3sNOh6SUUkqVy52Rq77AZmPMVmPMUWAaMKrkAcaYucaYI66biwBtta08op0rwSooNFw2eaEmWEoppbyeO8lVMyClxO1U130ncz3wzakEpVRJ7RvbBCu/0E4RbtcESymllBfzaEG7iFwJJADPneTxcSKSKCKJGRnaiVu5zyZY/ThaWMTYNxexY58mWEoppbyTO8nVTiC2xO3mrvuOIyLnAA8CI40xeaWdyBgz2RiTYIxJiImJqUy8qgbr0LgOH97Qj9z8QsZOXkTyviPlP0kppZSqZu4kV0uAeBFpJSIhwGXArJIHiEhP4A1sYrXH82EqZXVsUocPb+hPTn4hl01eqAmWUkopr1NucmWMKQBuBb4D1gHTjTFrRORxERnpOuw5IBL4RESWi8isk5xOqVPWqalNsI7kF3LBqwt4bd5mjhwtcDospZRS6v/bu/f4qKp77+OfX5IhgRAgBCSQcAl3lChIwAiCWq0FikI5Aip6xKPVIkj0WCovq61ysOVUi5fnQai1VKVYQDgIFXh4jopSUZAQAxgSwsVAAnILCEEbQ2CdPybakMMlgSF7ZvJ9v168MrP3npnvzGZWftl77bUAMOecJy+clpbmMjMzPXltCQ/b9pfwm2V5vJ+3n4TYeoy9rgN3prclxhfpdTQ5AzNb75xL8zrHhVL7JVL31KT90gjtErI6XhLHrDG9WTi2L91aNmLK0lyufXYlsz8p4NvyE17HExGROkrFlYS8Xm3j+ct9VzH3/nTaNo3lycU5/OC5D5m3bhfHT5z0Op6IiNQxKq4kbKS3T2DeA+m88W99aBYXzWMLN3HjtA9Z9FkRJ056c/pbRETqHhVXElbMjAGdm/P2g3159V/TiK0XxSPzNvDk4s+9jiYiInWEiisJS2bGjZe24J2HruGBAe15c+0u/vrpLq9jiYhIHaDiSsJaRITxi4FdGdC5Ob9enEPWrsNeR5JaZmYDzWyLmW0zs0mnWf/vZrbZzDaa2Xtm1taLnCISPlRcSdiLjDBeuq0HiY1jGPuX9ewvKfU6ktQSM4sEpgODgEuB283s0iqbfQakOecuBxYAv6vdlCISblRcSZ3QpEE9/nBXL47+o5xxc7IoK9dVhHVEH2Cbc26Hc64MmAsMrbyBc26lc+67of7X4J/iS0TkvKm4kjqjW8tG/Oetl7Ou4DDPLN3sdRypHUlAYaX7RRXLzuReYPnpVmjieRGpLhVXUqfcckUrfto/hdc/2clbmYXnfoDUGWZ2J5CGfzqv/0UTz4tIdam4kjrnsYFd6dshgV++/Tkbi77yOo5cXLuB1pXuJ1csO4WZ3Qj8Ev/k89/WUjYRCVMqrqTOiYqM4P/ecSXNG0bzs9nrOXhMv0vD2Dqgk5mlmFk94DbglInlzawn8Af8hdV+DzKKSJhRcSV1UtNYfwf34q/LGP9mFuWaJicsOefKgfHACiAXmO+cyzGzyWZ2S8VmzwINgbfMLNvMlpzh6UREqiXK6wAiXume1Jjf/CSVR9/awG+X5/HkkKpX6Es4cM4tA5ZVWfarSrdvrPVQIhLWVFxJnfYvvZLZtPsIf/roC1KTGjOs59kuJBMRETk3FVdS5/3yx93YvOcov1i4ETMY2kMFloiInD/1uZI6zxcZwcy7etEjuQkZc7P57fJcTpx0XscSEZEQpeJKBH8H97/cdxV3prfhDx/u4N9eW8eRb457HUtEREKQiiuRCvWiIpgyLJXfDk/l4+0HGfbyarbtL/E6loiIhBgVVyJV3N6nDX/9aTolpeUMm/4x727e53UkEREJISquRE4jrV1T/vZQP9o3j+WnszP5P+9txTn1wxIRkXNTcSVyBi0b12f+A1czrEcSv//vfB6ck8XX35Z7HUtERIKciiuRs4jxRTJt5BU88eNurMjZy7/M+JidxV97HUtERIJYUI1zdfz4cYqKiigtLfU6SsiLiYkhOTkZn8/ndZSQZ2bc1789XRLjGP/mZwx84e88elNnxvRtR1Sk/j4REZFTBVVxVVRURFxcHO3atcPMvI4TspxzFBcXU1RUREpKitdxwkb/Ts1ZltGfX739OVOW5vJ29m6mDr+c7kmNvY4mIiJBJKj+7C4tLSUhIUGF1QUyMxISEnQE8CJIalKfV+9OY/odV7L3yLcMnb6aZ5Zu5psy9cUSERG/oCquABVWAaLP8eIxM358eUve+/drGZnWmj/+/Qt+OG0VH2zZ73U0EREJAkFXXImEisYNfPx2eCrzH7iaGF8EY/68jgl//YwDJd96HU1ERDyk4qqSr776ipdffrnGjxs8eDBfffVVjR83ZswYFixYUOPHSXDpk9KUZRn9ybihE8s//5Ibp33I/HWFGhdLRKSOUnFVyZmKq/Lys/enWbZsGU2aNLlYsSQEREdF8sgPO7M8oz+dWzTkFws38q+zPqXo8DdeRxMRkVpWrasFzWwg8CIQCbzqnJtaZf0A4AXgcuA259wFH455+m85bN5z9EKf5hSXtmrEr2++7IzrJ02axPbt2+nRowc+n4+YmBji4+PJy8sjPz+fYcOGUVhYSGlpKRkZGdx///0AtGvXjszMTI4dO8agQYO45ppr+Pjjj0lKSmLx4sXUr1//nNnee+89fv7zn1NeXk7v3r2ZMWMG0dHRTJo0iSVLlhAVFcVNN93Ec889x1tvvcXTTz9NZGQkjRs3ZtWqVQH7jOTCdLwkjnn3X82cT3cxdVkuP3p+FZMGd2N0nzZERKgfnIhIXXDOI1dmFglMBwYBlwK3m9mlVTbbBYwB3gx0wNo0depUOnToQHZ2Ns8++yxZWVm8+OKL5OfnAzBr1izWr19PZmYmL730EsXFxf/rObZu3cq4cePIycmhSZMmLFy48JyvW1paypgxY5g3bx6bNm2ivLycGTNmUFxczKJFi8jJyWHjxo088cQTAEyePJkVK1awYcMGlixZEtgPQS5YRIRxV3pb/t/DA+jZJp4n3/6c0a+uZVexjmKJiNQF1Tly1QfY5pzbAWBmc4GhwObvNnDOFVSsOxmoYGc7wlRb+vTpc8o4US+99BKLFi0CoLCwkK1bt5KQkHDKY1JSUujRowcAvXr1oqCg4Jyvs2XLFlJSUujcuTMAd999N9OnT2f8+PHExMRw7733MmTIEIYMGQJAv379GDNmDCNHjmT48OGBeKtyEbRu2oDZ9/Zh7rpCnlmay49eWMWkQV25K72tjmKJiISx6vS5SgIKK90vqlgW9mJjY7+//cEHH/Duu+/yySefsGHDBnr27HnacaSio6O/vx0ZGXnO/lpnExUVxaeffsqtt97KO++8w8CBAwGYOXMmU6ZMobCwkF69ep32CJoEBzPj9j5tWPHIAHqnNOXXS3K47Y9rKDioKXRERMJVrXZoN7P7zSzTzDIPHDhQmy9dLXFxcZSUlJx23ZEjR4iPj6dBgwbk5eWxZs2agL1uly5dKCgoYNu2bQDMnj2ba6+9lmPHjnHkyBEGDx7M888/z4YNGwDYvn07V111FZMnT6Z58+YUFhae7eklCCQ1qc/r9/Tmd7deTu6XRxn44ir+9NEXnDipKwpFRMJNdU4L7gZaV7qfXLGsxpxzrwCvAKSlpQXdb5WEhAT69etH9+7dqV+/Pi1atPh+3cCBA5k5cybdunWjS5cupKenB+x1Y2Ji+POf/8yIESO+79D+s5/9jEOHDjF06FBKS0txzjFt2jQAJk6cyNatW3HOccMNN3DFFVcELItcPGbGyLTWDOjUnMcXbeI/3tnMnDU76dGmCd0SG9G1ZRxdExvRPC763E8mIiJBy841Fo+ZRQH5wA34i6p1wB3OuZzTbPsa8E51rhZMS0tzmZmZpyzLzc2lW7du1Q4vZ6fPM3g551icvYf/+mw3W/YeZd/Rfw482qxhPbomNqJrYhxdW/p/dkmMwxcGk0Sb2XrnXJrXOS7U6dovEQlvNWm/znnkyjlXbmbjgRX4h2KY5ZzLMbPJQKZzbomZ9QYWAfHAzWb2tHPO+x7pIkHKzBjWM4lhPf3dFw99XUbe3qPkfVni/7m3hNlrdvJtuf8akdh6kfRJaUq/js24ukMC3RIbqVO8iEiQqtY4V865ZcCyKst+Ven2OvynC+U0xo0bx+rVq09ZlpGRwT333ONRIgk2TWPr0bdDM/p2aPb9shMnHQXFX7N5z1HWflHMx9uLWbk0F4D4Bj7S2yfQt2Mz+nZIoH2zWM0nKSISJKpVXMmFmT59utcRJARFRhgdmjekQ/OG3HxFKwC+PPIPPtnuL7Q+3naQ5Z/vBaBFo2gGdGrOg9d3JKVZ7NmeVkRELjIVVyIhpGXj+gy/MpnhVybjnGNn8Tf+Qmv7QZZu+pJFn+3mzvS2TLihE01j63kdV0SkTlJxJRKizIx2zWJp1yyWO65qw/6SUl54dytvfFLAwqwixl3fkTF92xHji/Q6qohInRL6lx+JCACXxMXwm5+ksuLhAfRu15Spy/O44fcfsjh7Nyc1npaISK1RcSUSZjq1iGPWmN68ed9VNGngI2NuNsNeXs2aHRrJX0SkNqi4ugANGzY847qCggK6d+9ei2lETtW3YzP+Nv4apo28ggMl33LbK2u47/VM3svdR3bhV+wq/oaS0uOca6w7ERGpGfW5EgljERHG8CuTGZzaklmrv+Dlldt5N3ffKdv4Io34BvX8/2J9NI2tR7OG0fw4tSV9UppqiAcRkRoK3uJq+STYuymwz5mYCoOmnnH1pEmTaN26NePGjQPgqaeeIioqipUrV3L48GGOHz/OlClTGDp0aI1etrS0lLFjx5KZmUlUVBTTpk3j+uuvJycnh3vuuYeysjJOnjzJwoULadWqFSNHjqSoqIgTJ07w5JNPMmrUqAt62yIxvkgevK4jo69qy44Dxzj8TRmHvj7O4a/LOPRNmf/n12Uc/qaMLXtL+ODIAd74ZCepSY25r38Kg1NbhsUI8SIitSF4iysPjBo1iocffvj74mr+/PmsWLGCCRMm0KhRIw4ePEh6ejq33HJLjf6anz59OmbGpk2byMvL46abbiI/P5+ZM2eSkZHB6NGjKSsr48SJEyxbtoxWrVqxdOlSwD9htEigNK7vo2eb+HNu94+yEyzMKmLW6i/ImJvN1OV53N23Hbf3bkPjBr5aSCoiErqCt7g6yxGmi6Vnz57s37+fPXv2cODAAeLj40lMTOSRRx5h1apVREREsHv3bvbt20diYmK1n/ejjz7ioYceAqBr1660bduW/Px8rr76ap555hmKiooYPnw4nTp1IjU1lUcffZTHHnuMIUOG0L9//4v1dkXOqH69SO5Mb8sdfdrwQf5+Xv37F0xdnsdL721lZFpr7unXjrYJGqxUROR0dJy/ihEjRrBgwQLmzZvHqFGjmDNnDgcOHGD9+vVkZ2fTokULSktLA/Jad9xxB0uWLKF+/foMHjyY999/n86dO5OVlUVqaipPPPEEkydPDshriZyPiAjjB11b8OZP01k64RoGdk9kztqdXPfcBzwwO5N1BYfUIV5EpAoVV1WMGjWKuXPnsmDBAkaMGMGRI0e45JJL8Pl8rFy5kp07d9b4Ofv378+cOXMAyM/PZ9euXXTp0oUdO3bQvn17JkyYwNChQ9m4cSN79uyhQYMG3HnnnUycOJGsrKxAv0WR83JZq8ZMG9mD1Y/9gHHXdWTtF4e497V1/OP4Ca+jiYgEleA9LeiRyy67jJKSEpKSkmjZsiWjR4/m5ptvJjU1lbS0NLp27Vrj53zwwQcZO3YsqampREVF8dprrxEdHc38+fOZPXs2Pp+PxMREHn/8cdatW8fEiROJiIjA5/MxY8aMi/AuRc7fJY1i+PmPujDu+o7k7j1Kg3pqRkREKjOvDumnpaW5zMzMU5bl5ubSrVs3T/KEI32eEmzMbL1zLs3rHBfqdO2XiIS3mrRfOi0oIiIiEkA6nn+BNm3axF133XXKsujoaNauXetRIhEREfGSiqsLlJqaSnZ2ttcxREREJEgE3WlBXdYdGPocRUREvBFUxVVMTAzFxcUqDC6Qc47i4mJiYmK8jiIiIlLnBNVpweTkZIqKijhw4IDXUUJeTEwMycnJXscQERGpc4KquPL5fKSkpHgdQ0TCiJkNBF4EIoFXnXNTq6yPBt4AegHFwCjnXEFt5xSR8BFUpwVFRALJzCKB6cAg4FLgdjO7tMpm9wKHnXMdgeeB/6zdlCISblRciUg46wNsc87tcM6VAXOBoVW2GQq8XnF7AXCDmVktZhSRMKPiSkTCWRJQWOl+UcWy027jnCsHjgAJtZJORMKSZ32u1q9ff9DMajILcjPg4MXKUwuU31vK763v8rf1Osj5MrP7gfsr7h4zsy01eHi47L9QpfzeCpf81W6/PCuunHPNa7K9mWWG8pxkyu8t5feWh/l3A60r3U+uWHa6bYrMLApojL9j+ymcc68Ar5xPCO0/bym/t+pifp0WFJFwtg7oZGYpZlYPuA1YUmWbJcDdFbdvBd53GmxPRC5AUA3FICISSM65cjMbD6zAPxTDLOdcjplNBjKdc0uAPwGzzWwbcAh/ASYict5Cqbg6r8PxQUT5vaX83vIsv3NuGbCsyrJfVbpdCoy4yDG0/7yl/N6qc/lNR79FREREAkd9rkREREQCKOiLKzMbaGZbzGybmU3yOk9NmVmBmW0ys2wzy/Q6z7mY2Swz229mn1da1tTM/tvMtlb8jPcy49mcIf9TZra7Yh9km9lgLzOejZm1NrOVZrbZzHLMLKNieUjsg7PkD5l9EEih3n6B2rDapjbMW4Fqw4L6tGDF1BX5wA/xD/63DrjdObfZ02A1YGYFQJpzLiTG+DCzAcAx4A3nXPeKZb8DDjnnplb8goh3zj3mZc4zOUP+p4BjzrnnvMxWHWbWEmjpnMsyszhgPTAMGEMI7IOz5B9JiOyDQAmH9gvUhtU2tWHeClQbFuxHrqozdYUEkHNuFf4rpiqrPD3I6/j/owWlM+QPGc65L51zWRW3S4Bc/COIh8Q+OEv+ukjtlwfUhnlLbZhfsBdX1Zm6Itg54P+b2Xrzj/Acilo4576suL0XaOFlmPM03sw2VhxyD8rD0VWZWTugJ7CWENwHVfJDCO6DCxQO7ReoDQsWIff9qcttWLAXV+HgGufclcAgYFzFId+QVTG4YvCeSz69GUAHoAfwJfB7b+Ocm5k1BBYCDzvnjlZeFwr74DT5Q24fyPfUhnkv5L4/db0NC/biqjpTVwQ159zuip/7gUX4TxWEmn0V56G/Ox+93+M8NeKc2+ecO+GcOwn8kSDfB2bmw/+lnuOc+6+KxSGzD06XP9T2QYCEfPsFasOCQah9f9SGBX9xVZ2pK4KWmcVWdIjDzGKBm4DPz/6ooFR5epC7gcUeZqmx777QFX5CEO8DMzP8I4bnOuemVVoVEvvgTPlDaR8EUEi3X6A2LFiE0vdHbVjF9sF8tSBAxeWOL/DPqSue8ThStZlZe/x/6YF/NPw3gz2/mf0VuA7/LOD7gF8DbwPzgTbATmCkcy4oO1yeIf91+A/lOqAAeKDSuf+gYmbXAH8HNgEnKxY/jv+cf9Dvg7Pkv50Q2QeBFMrtF6gN84LaMG8Fqg0L+uJKREREJJQE+2lBERERkZCi4kpEREQkgFRciYiIiASQiisRERGRAFJxJSIiIhJAKq5EREREAkjFlYiIiEgAqbgSERERCaD/AVIspmaulafVAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + }, + { + "output_type": "stream", + "text": [ + " training loss (in-iteration): \t0.056803\n", + " validation loss: \t\t\t0.639335\n", + "\n", + " training AUC: \t\t\t1.00\n", + " validation AUC: \t\t\t0.83\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CmQcyjU9W5JX" + }, + "source": [ + "### Latent reprsentations\n", + "\n", + "Now, let's take a look at the latent features learnt by convolutional model." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "20A3fhq0UuFk" + }, + "source": [ + "from sklearn.decomposition import PCA\n", + "from sklearn.manifold import TSNE" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "oA33tKNRWdxy", + "outputId": "578853a7-a67b-44c5-c9a8-884fee381fe6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 433 + } + }, + "source": [ + "latents = []\n", + "dataset.set_target()\n", + "C_model.train(False)\n", + "for i in tqdm(notnull_idx):\n", + " x = dataset[i][[0]].unsqueeze(dim=0).to(device)\n", + " z = C_model(x)[0].cpu().detach().numpy()\n", + " latents.append(z)\n", + "latents = np.concatenate(latents, axis=0)\n", + "\n", + "pca = PCA(n_components=50)\n", + "tsne = TSNE(n_components=2)\n", + "latents_2d = tsne.fit_transform(pca.fit_transform(latents))\n", + "\n", + "source_colors = {\"USM\" : \"tab:blue\",\n", + " \"UCLA\" : \"tab:orange\",}\n", + "sources = np.array(dataset.labels.loc[notnull_idx, \"SOURCE\"].tolist())\n", + "\n", + "plt.figure(figsize=(12, 8))\n", + "for s in source_colors:\n", + " s_idx = (sources == s)\n", + " plt.scatter(latents_2d[s_idx, 0], latents_2d[s_idx, 1], \n", + " s=30, alpha=0.75, c=source_colors[s], label=s)\n", + "plt.legend()\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A2LplZQMs2f7" + }, + "source": [ + "## 3. Domain adaptation\n", + "\n", + "Let's try to make the model encode **less site-dependent** information.\n", + "\n", + "We will employ one of the most widespread domain adaptation approaches proposed by Ganin et al. [https://arxiv.org/pdf/1505.07818.pdf]. The model here is composed of 3 parts: \n", + "- a **feature extractor**, that transforms an input (in our case, an fMRI image) into a vector of high-level features,\n", + "- a **classifier (predictor)** - the main model, that takes extracted features and predicts the target;\n", + "- a **discriminator**, that takes extracted features and predicts the **domain** on the original sample. \n", + "\n", + "During optimization, the gradients from discriminator to feature extractor are **reversed**. So, the feature extractor is forced to learn the features, that are **as less informative as possible** for the discriminator, that is, contain **less information on the domain**. \n", + "\n", + "\n", + "The whole architecture is presented below:\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VvCmT0S6xP_M" + }, + "source": [ + "### Discriminator for DANN\n", + "\n", + "As a discriminator we will use a simple model that takes feature vector of each time step, applies fully-connected network to it to predict probability of each class (domain) and then averages the predcitions." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DsUh9r4_9SFY" + }, + "source": [ + "# discriminator to predict domain (site) of a sample\n", + "class DiscModel(nn.Module):\n", + " def __init__(self, n_latent_units, \n", + " n_domains=2,\n", + " fc_model=[1024, 256, 64], \n", + " batchnorm=True,\n", + " dropout=0):\n", + " super(self.__class__, self).__init__()\n", + " self.n_latent_units = n_latent_units\n", + " self.n_outputs = n_domains\n", + "\n", + " self.model = []\n", + " n_in = n_latent_units\n", + " for n_out in fc_model:\n", + " self.model += [nn.Dropout(dropout),\n", + " nn.Linear(n_in, n_out)]\n", + " if batchnorm:\n", + " self.model += [nn.BatchNorm1d(n_out)]\n", + " self.model += [\n", + " nn.ReLU(True),\n", + " ]\n", + " n_in = n_out\n", + " self.model += [nn.Dropout(dropout),\n", + " nn.Linear(n_in, self.n_outputs)]\n", + " self.model = nn.Sequential(*self.model)\n", + "\n", + " \n", + " def forward(self, x): \n", + " # reshape to (n_obj * n_time_steps, latent_size)\n", + " n_objects, seq_length = x.size()[0:2]\n", + " x = x.reshape([n_objects * seq_length] + list(x.size()[2:]))\n", + " # apply fc model\n", + " x = self.model(x)\n", + " # reshape to (n_obj, n_time_steps, logit), mean over time_steps\n", + " x = x.reshape([n_objects, seq_length, -1])\n", + " x = x.mean(dim=1)\n", + " return x" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kfEsIDcSx0-H" + }, + "source": [ + "### DANN train functions" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZRTPY-No2xoB" + }, + "source": [ + "def train_DA(train_loader, val_loader, args,\n", + " C, T, D, C_opt, T_opt, D_opt,\n", + " crit=nn.CrossEntropyLoss(), D_crit=nn.BCEWithLogitsLoss(),\n", + " metric=roc_auc_score):\n", + " \n", + " def plot_results(epoch):\n", + " clear_output(True)\n", + " print(\"EPOCH {}\".format(epoch))\n", + " \n", + " plt.figure(figsize=(10, 5))\n", + " plt.subplot(121)\n", + " plt.plot(train_stats[\"mean_train_loss\"], label=\"train_loss\")\n", + " plt.plot(train_stats[\"mean_val_loss\"], label=\"val_loss\")\n", + " plt.plot(train_stats[\"mean_total_loss\"], label=\"total_loss\")\n", + " plt.plot(train_stats[\"mean_D_loss\"], label=\"D_loss\")\n", + " plt.title(\"losses\")\n", + " plt.legend()\n", + " plt.subplot(122)\n", + " plt.plot(train_stats[\"mean_train_metric\"], label=\"train_metric\")\n", + " plt.plot(train_stats[\"mean_val_metric\"], label=\"val_metric\")\n", + " plt.gca().set_ylim([0, 1])\n", + " plt.title(\"metricss\")\n", + " plt.legend()\n", + " plt.show()\n", + " \n", + " print(\" training D_loss (in-iteration): \\t{:.6f}\".format(train_stats[\"mean_D_loss\"][-1]))\n", + " print(\" training total_loss (in-iteration): \\t{:.6f}\".format(train_stats[\"mean_total_loss\"][-1]))\n", + " print(\" training loss (in-iteration): \\t{:.6f}\".format(train_stats[\"mean_train_loss\"][-1]))\n", + " print(\" validation loss: \\t\\t\\t{:.6f}\".format(train_stats[\"mean_val_loss\"][-1]))\n", + " print()\n", + " print(\" training AUC: \\t\\t\\t{:.2f}\".format(train_stats[\"mean_train_metric\"][-1]))\n", + " print(\" validation AUC: \\t\\t\\t{:.2f}\".format(train_stats[\"mean_val_metric\"][-1]))\n", + " \n", + " train_stats = {\n", + " \"mean_D_loss\" : [],\n", + " \"mean_total_loss\" : [],\n", + " \"mean_train_loss\" : [],\n", + " \"mean_val_loss\" : [],\n", + " \"mean_train_metric\" : [],\n", + " \"mean_val_metric\" : [],\n", + " }\n", + " \n", + " for epoch in range(args[\"n_epochs\"]):\n", + " print(\"TRAIN EPOCH {}...\".format(epoch))\n", + " train_D_loss = []\n", + " train_loss, train_total_loss, train_preds, train_targets = [], [], [], []\n", + " val_loss, val_preds, val_targets = [], [], []\n", + " \n", + " D_n_upd = args[\"D_n_upd\"] if epoch < args[\"D_loop_epochs\"] else 1\n", + " if epoch <= args[\"n_pretr_epochs\"]:\n", + " cur_lambda = args[\"min_lambda\"]\n", + " elif cur_lambda < args[\"max_lambda\"]:\n", + " cur_lambda += args[\"inc_lambda\"]\n", + " else: \n", + " cur_lambda = args[\"max_lambda\"]\n", + " print(f\"Current lambda: {cur_lambda}\")\n", + " \n", + " C.train(True), T.train(True), D.train(True)\n", + " for inputs_batch, targets_batch, domains_batch in tqdm(train_loader):\n", + " domains_batch = torch.zeros((len(domains_batch), args[\"n_domains\"])).scatter(1, domains_batch.view(-1, 1), 1)\n", + " inputs_batch, targets_batch, domains_batch = inputs_batch.float().to(device), targets_batch.long().to(device), domains_batch.float().to(device)\n", + "\n", + " # train D\n", + " latents_batch = C(inputs_batch)\n", + " for _ in range(D_n_upd):\n", + " D_logits_batch = D(latents_batch.detach())\n", + " D_loss = D_crit(D_logits_batch, domains_batch)\n", + " D_opt.zero_grad()\n", + " D_loss.backward()\n", + " D_opt.step()\n", + " train_D_loss.append(D_loss.item())\n", + " \n", + " # train C & T\n", + " latents_batch = C(inputs_batch)\n", + " logits_batch = T(latents_batch)\n", + " loss = crit(logits_batch, targets_batch)\n", + " D_logits_batch = D(latents_batch)\n", + " D_loss = D_crit(D_logits_batch, 1 - domains_batch)\n", + " total_loss = loss + cur_lambda * D_loss\n", + " total_loss.backward()\n", + " T_opt.step(), C_opt.step()\n", + " T_opt.zero_grad(), C_opt.zero_grad()\n", + " \n", + " train_loss.append(loss.item())\n", + " train_total_loss.append(total_loss.item())\n", + " preds = compute_probs(logits_batch)\n", + " train_preds.extend(list(preds.cpu().data.numpy()))\n", + " train_targets.extend(list(targets_batch.cpu().data.numpy()))\n", + " train_metric = metric(train_targets, train_preds)\n", + " \n", + " C.train(False), T.train(False)\n", + " for inputs_batch, targets_batch, domains_batch in tqdm(val_loader):\n", + " inputs_batch, targets_batch, domains_batch = inputs_batch.float().to(device), targets_batch.long().to(device), domains_batch.float().to(device)\n", + " \n", + " latents_batch = C(inputs_batch)\n", + " logits_batch = T(latents_batch)\n", + " loss = crit(logits_batch, targets_batch)\n", + " val_loss.append(loss.item())\n", + " preds = compute_probs(logits_batch)\n", + " val_preds.extend(list(preds.cpu().data.numpy()))\n", + " val_targets.extend(list(targets_batch.cpu().data.numpy())) \n", + " val_metric = metric(val_targets, val_preds)\n", + "\n", + " # save stats\n", + " train_stats[\"mean_D_loss\"].append(np.mean(train_D_loss))\n", + " train_stats[\"mean_total_loss\"].append(np.mean(train_total_loss))\n", + " train_stats[\"mean_train_loss\"].append(np.mean(train_loss))\n", + " train_stats[\"mean_val_loss\"].append(np.mean(val_loss))\n", + " train_stats[\"mean_train_metric\"].append(train_metric)\n", + " train_stats[\"mean_val_metric\"].append(val_metric)\n", + " \n", + " plot_results(epoch) \n", + " return train_stats" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Sr-ojrLUIFgu" + }, + "source": [ + "### Training" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4isg3P6fd57x" + }, + "source": [ + "dataset.use_sources = [\"USM\", \"UCLA\"]\n", + "\n", + "# dataset have target classes 1 and 2\n", + "# encode target with LabelEncoder to use classes 0 and 1 instead\n", + "# also set the domain target column (\"SOURCE\")\n", + "dataset.set_target(\"DX_GROUP\", encode_target=True, domain_target=\"SOURCE\")\n", + "\n", + "notnull_idx = dataset.target[dataset.target.notnull()].index\n", + "train_idx, val_idx = train_test_split(notnull_idx, stratify=dataset.target[notnull_idx],\n", + " test_size=0.2, random_state=42)\n", + "batch_size = 16\n", + "train_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, train_idx), batch_size=batch_size, shuffle=True)\n", + "val_loader = torch.utils.data.DataLoader(\n", + " data.Subset(dataset, val_idx), batch_size=batch_size, shuffle=False)\n", + "\n", + "C_model = ConvEncoder(input_shape=(48, 64, 48), \n", + " conv_model=[32, 64, 128, 256], \n", + " conv_model_type=\"CNN\",\n", + " n_flatten_units=None).to(device)\n", + "T_model = ClfGRU(n_latent_units=C_model.conv_model.n_flatten_units, \n", + " seq_length=16, \n", + " n_outputs=2,\n", + " hidden_size=64,\n", + " n_layers=1,\n", + " use_states=\"mean\",\n", + " n_fc_units=128,\n", + " dropout=0.2,).to(device)\n", + "D_model = DiscModel(n_latent_units=C_model.conv_model.n_flatten_units, \n", + " n_domains=len(dataset.use_sources),\n", + " fc_model=[1024, 256, 64],\n", + " batchnorm=True,\n", + " dropout=0.3).to(device)\n", + "lr = 1e-4\n", + "wd = 0 \n", + "C_opt = torch.optim.Adam(C_model.parameters(), lr=lr, weight_decay=wd)\n", + "T_opt = torch.optim.Adam(T_model.parameters(), lr=lr, weight_decay=wd)\n", + "D_opt = torch.optim.Adam(D_model.parameters(), lr=lr, weight_decay=wd)\n", + "\n", + "args = {\n", + " \"n_domains\" : len(dataset.use_sources),\n", + " \"n_epochs\" : 25,\n", + " \"n_pretr_epochs\" : 0,\n", + " \"min_lambda\" : 0,\n", + " \"inc_lambda\" : 3e-4 / 20,\n", + " \"max_lambda\" : 3e-4,\n", + " \"D_loop_epochs\" : 15,\n", + " \"D_n_upd\" : 3,\n", + "}\n", + "\n", + "train_stats = train_DA(train_loader, val_loader, args,\n", + " C_model, T_model, D_model, C_opt, T_opt, D_opt)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "U6qg3V4SXmc7" + }, + "source": [ + "latents = []\n", + "dataset.set_target()\n", + "C_model.train(False)\n", + "for i in tqdm(notnull_idx):\n", + " x = dataset[i][[0]].unsqueeze(dim=0).to(device)\n", + " z = C_model(x)[0].cpu().detach().numpy()\n", + " latents.append(z)\n", + "latents = np.concatenate(latents, axis=0)\n", + "\n", + "pca = PCA(n_components=50)\n", + "tsne = TSNE(n_components=2)\n", + "latents_2d = tsne.fit_transform(pca.fit_transform(latents))\n", + "\n", + "source_colors = {\"USM\" : \"tab:blue\",\n", + " \"UCLA\" : \"tab:orange\",}\n", + "sources = np.array(dataset.labels.loc[notnull_idx, \"SOURCE\"].tolist())\n", + "\n", + "plt.figure(figsize=(12, 8))\n", + "for s in source_colors:\n", + " s_idx = (sources == s)\n", + " plt.scatter(latents_2d[s_idx, 0], latents_2d[s_idx, 1], \n", + " s=30, alpha=0.75, c=source_colors[s], label=s)\n", + "plt.legend()\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "krOVemKzXmfj" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JUV2nggOaXHt" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file