From 69262c4ef597741f3a7308b11ff95f8094ac434a Mon Sep 17 00:00:00 2001 From: andreagurioli1995 <38469046+andreagurioli1995@users.noreply.github.com> Date: Thu, 12 May 2022 00:00:35 +0200 Subject: [PATCH] Grad vit 25 epochs --- ViT_Face_Emotion_Recognition.ipynb | 1262 ++++++++++++++-------------- 1 file changed, 646 insertions(+), 616 deletions(-) diff --git a/ViT_Face_Emotion_Recognition.ipynb b/ViT_Face_Emotion_Recognition.ipynb index 4c6dc46..0cf411d 100644 --- a/ViT_Face_Emotion_Recognition.ipynb +++ b/ViT_Face_Emotion_Recognition.ipynb @@ -72,7 +72,7 @@ "base_uri": "https://localhost:8080/" }, "id": "TBLS3rKGcIUm", - "outputId": "826e6f8a-0daf-4334-c301-52c0c36383fe" + "outputId": "3efc62d5-6c38-48de-b571-27b07d4ee90e" }, "outputs": [ { @@ -81,124 +81,53 @@ "text": [ "Requirement already satisfied: Pillow in /usr/local/lib/python3.7/dist-packages (7.1.2)\n", "Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (1.3.5)\n", - "Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas) (2022.1)\n", - "Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas) (2.8.2)\n", "Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.7/dist-packages (from pandas) (1.21.6)\n", - "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas) (1.15.0)\n", - "Collecting timm\n", - " Downloading timm-0.5.4-py3-none-any.whl (431 kB)\n", - "\u001b[K |████████████████████████████████| 431 kB 5.1 MB/s \n", - "\u001b[?25hRequirement already satisfied: torchvision in /usr/local/lib/python3.7/dist-packages (from timm) (0.12.0+cu113)\n", - "Requirement already satisfied: torch>=1.4 in /usr/local/lib/python3.7/dist-packages (from timm) (1.11.0+cu113)\n", - "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from torch>=1.4->timm) (4.2.0)\n", - "Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from torchvision->timm) (1.21.6)\n", - "Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from torchvision->timm) (2.23.0)\n", - "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /usr/local/lib/python3.7/dist-packages (from torchvision->timm) (7.1.2)\n", - "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision->timm) (2.10)\n", - "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision->timm) (1.24.3)\n", - "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision->timm) (3.0.4)\n", - "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision->timm) (2021.10.8)\n", - "Installing collected packages: timm\n", - "Successfully installed timm-0.5.4\n" + "Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas) (2.8.2)\n", + "Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas) (2022.1)\n", + "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas) (1.15.0)\n" ] } ], "source": [ "!pip3 install Pillow\n", - "!pip install pandas\n", - "!pip install timm" + "!pip install pandas" ] }, { "cell_type": "code", - "source": [ - "!git clone https://github.com/davda54/sam.git" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "8wNJEIuURXEb", - "outputId": "e55da0f0-0c34-4206-af90-99c623798b04" - }, "execution_count": 2, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Cloning into 'sam'...\n", - "remote: Enumerating objects: 179, done.\u001b[K\n", - "remote: Counting objects: 100% (75/75), done.\u001b[K\n", - "remote: Compressing objects: 100% (22/22), done.\u001b[K\n", - "remote: Total 179 (delta 62), reused 53 (delta 53), pack-reused 104\u001b[K\n", - "Receiving objects: 100% (179/179), 650.16 KiB | 14.78 MiB/s, done.\n", - "Resolving deltas: 100% (84/84), done.\n" - ] - } - ] - }, - { - "cell_type": "code", - "execution_count": 75, "metadata": { "id": "66hzxAClAFAY" }, "outputs": [], "source": [ - "# classic libraries for collections\n", "import pandas as pd\n", - "import numpy as np\n", - "\n", - "# utility library\n", - "import random, time, copy\n", - "\n", - "# plot libraries\n", "import matplotlib.pyplot as plt\n", + "import numpy as np\n", "%matplotlib inline\n", "import seaborn as sns\n", - "\n", - "# libraries for image processing \n", - "import os, cv2, glob, imageio, sys\n", - "from PIL import Image\n", - "\n", - "# warning library for service warnings\n", - "import warnings\n", - "\n", - "# machine learning libraries \n", - "import timm, torch, torchvision\n", - "\n", - "# image dataset loading and transformations\n", - "from torchvision import datasets, models, transforms\n", - "\n", - "# utility functions for specific uses\n", - "from __future__ import print_function\n", - "from __future__ import division\n", - "\n", - "# optimizer libraries \n", - "from torch.optim import lr_scheduler\n", - "import torch.optim as optim\n", - "from sam.sam import SAM\n", - "\n", - "# library for basic building blocks\n", - "import torch.nn as nn\n", - "\n", - "# library for saving and loading checkpoints\n", - "import pickle\n", - "\n", - "# libraries for metrics and evaluation phase\n", - "from sklearn import metrics\n", - "from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, confusion_matrix, ConfusionMatrixDisplay" + "import os, cv2, glob, imageio, random" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "AQ-jkxorUiI-" + }, + "outputs": [], "source": [ - "### 2.2 Mount Google Drive" - ], + "from PIL import Image" + ] + }, + { + "cell_type": "markdown", "metadata": { - "id": "rJ_FETBdMj33" - } + "id": "NreShpCAC4SE" + }, + "source": [ + "Data sources about datasets described in the previous section are in Google Drive, so we need to manage files in a shared directory and integrate them into a single unit by merging images of the same classes from different datasets." + ] }, { "cell_type": "markdown", @@ -206,7 +135,7 @@ "id": "AxFAHkf9x7_E" }, "source": [ - "Data sources about datasets described in the previous section are in Google Drive, so we need to manage files in a shared directory and integrate them into a single unit by merging images of the same classes from different datasets. So, we need to mount the drive and load its data." + "Loading data from the Google Drive" ] }, { @@ -217,14 +146,13 @@ "base_uri": "https://localhost:8080/" }, "id": "0WafVw77sp2v", - "outputId": "5c2c63ac-230d-4491-9a28-11223c1f9d38" + "outputId": "e7875e46-9c7e-48db-9d8d-c3fa2574d476" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "Drive not mounted, so nothing to flush and unmount.\n", "Mounted at /content/drive\n" ] } @@ -235,34 +163,18 @@ "drive.mount('/content/drive')" ] }, - { - "cell_type": "markdown", - "source": [ - "### 2.3 Image Worker" - ], - "metadata": { - "id": "HROJ-iJ_MndC" - } - }, { "cell_type": "markdown", "metadata": { "id": "FYHpj1FEDFak" }, "source": [ - "ImageWorker provides some useful functions:\n", - "- Format Converter: For resize and move an image from *source_path* to *dest_path* filtered for *format_img*\n", - "- List Classes: Listing the classes and put them in an array to manipulate the subfolders for class functions divisions.\n", - "- Counter Samples per Class: Given a *dataset_path*, return a dictionary with counters of images classified by subfolders for plot or data visualization pourposes. \n", - "- Counter Samples: Given a *dataset_path*, return a counter of images in the tree.\n", - "- Extension Converter: Convert an image format for every image in a specified path\n", - "- Counter Files Extension: Given a *path*, return the counter of image in the directory with a specific *format*\n", - "- Navigate Path: Counter every file in a subtree" + "The following snippet of code describes essential functions used for the integration; ImageWorker is a class that we can use to convert the size format of an image (to make them in a standard dimension), change the extension of an image and can evaluate the number of images per class in each of exciting datasets." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "id": "mMiGrpYXLFNP" }, @@ -275,12 +187,12 @@ " pass\n", "\n", "\n", - " def format_converter(self, path, format_img, source_path, dest_path):\n", + " def format_converter(self, path, format_img, source_type, dest_path):\n", " count = 0\n", " for file in glob.glob(path + \"/*.\" + format_img):\n", " img = cv2.imread(file, cv2.IMREAD_UNCHANGED)\n", " resized = cv2.resize(img, (224,224), interpolation=cv2.INTER_CUBIC)\n", - " cv2.imwrite(dest_path + \"resized_on_\" + source_path + \"_\" + str(count) + \".\"+ format_img, resized)\n", + " cv2.imwrite(dest_path + \"resized_on_\" + source_type + \"_\" + str(count) + \".\"+ format_img, resized)\n", " count += 1\n", "\n", "\n", @@ -346,27 +258,6 @@ "iw = ImageWorker()" ] }, - { - "cell_type": "markdown", - "source": [ - "#### 2.4 Other useful functions" - ], - "metadata": { - "id": "of7icy3oMwUt" - } - }, - { - "cell_type": "markdown", - "source": [ - "We implemented some logic and reusable functions useful for the data analysis or data manipulation phases. These functions carry out support routines for ImageWorker's class. They are:\n", - "- Min, Max and Mean: According to values or set of values passed as parameter.\n", - "- Plot Dataset: Function for plot image's dataset and color values according to the mean of classes cardinalities.\n", - "- Channel Distribution: Analyze images and return counters of images for different channels dimension." - ], - "metadata": { - "id": "3yXNuG2JM0kR" - } - }, { "cell_type": "code", "execution_count": null, @@ -375,6 +266,8 @@ }, "outputs": [], "source": [ + "# Other utility functions related to properties of images\n", + "\n", "def mean(values):\n", " if len(values) <= 0:\n", " return 0\n", @@ -384,6 +277,8 @@ " sum += el\n", " return int(sum / len(values))\n", "\n", + "\n", + "\n", "def min(val):\n", " min = sys.maxsize\n", " for el in val.keys():\n", @@ -433,24 +328,6 @@ " return chan_size\n" ] }, - { - "cell_type": "markdown", - "source": [ - "## 3. Data Merging and Data Analysis" - ], - "metadata": { - "id": "dHHgMcQfN6xk" - } - }, - { - "cell_type": "markdown", - "source": [ - "In this section, we will provides partial data analysis related to data sources corresponding to subsets of images of the final dataset. Furthermore, we carry out the data merging in a temporal dataset located in AVFER folder. We will make the structure of this dataset with the creation of foldels corresponding to labels for the final loading. " - ], - "metadata": { - "id": "0y9AfDt7OGMt" - } - }, { "cell_type": "code", "execution_count": null, @@ -490,7 +367,7 @@ "id": "vAgvaOcbJeBj" }, "source": [ - "### 3.1 Merging FER2013 Dataset\n", + "### 2.2 FER2013 Dataset\n", "FER2013 is a dataset composed of 35.953 images in 7 classes (fear, disgust, sad, happy, neutral, surprise, angry). Images are in size 48x48 with a grey-scaled colours palette. The classes' variations and features distributions are helpful in the merging phase for other classes to obtain a good distribution and normalize the amount of data variation. According to the final classification, the contempt class was missed on this kind of dataset." ] }, @@ -952,7 +829,7 @@ "id": "ClgI0sjPvH5j" }, "source": [ - "### 3.2 Merging CK+ Dataset\n", + "### 2.3 CK+ Dataset\n", "It is a small dataset composed of 981 images in seven classes (fear, disgust, sad, happy, neutral, surprise, angry). Images are in size 48x48 with a grey-scaled colours palette. The classes' variations and features distributions are helpful in the merging phase for other classes to obtain a good distribution and normalize the amount of data variation. " ] }, @@ -964,18 +841,18 @@ "base_uri": "https://localhost:8080/" }, "id": "hU4DwQwKPPV5", - "outputId": "8fdd49e7-c8e4-402b-d2a7-7f4dafd8df5a" + "outputId": "bfdd4c88-9460-432e-f92b-5506bdc503b0" }, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "['fear', 'sadness', 'happy', 'anger', 'disgust', 'contempt', 'surprise']" ] }, + "execution_count": 21, "metadata": {}, - "execution_count": 22 + "output_type": "execute_result" } ], "source": [ @@ -1284,7 +1161,7 @@ "id": "fp75RuDu_GVY" }, "source": [ - "### 3.3 Merging AffectNet Dataset\n", + "### 2.4 AffectNet Dataset\n", "AffectNet dataset has samples of different sizes, high-quality images in grey-scale or coloured in RGB range. It has eight different classes (surprise, angry, sad, contempt, disgust, fear, neutral, and happy). As the FER-2013, there is a division between validation and training set; however, we will no merge it as well as we did with FER subsets, but put the validation set in the final val folder. Furthermore, we resize the different sizes of its images in 224x224 to establish the same amount of pixels for each sample." ] }, @@ -1878,7 +1755,7 @@ "id": "uMLuH1Ng4GxX" }, "source": [ - "### 3.4 Result of Integration: AVFER" + "### 2.5 AVFER" ] }, { @@ -2063,7 +1940,7 @@ "id": "fiKUpawZS342" }, "source": [ - "### 3.5 Data Analysis: AVFER\n" + "## 3. Data Analysis\n" ] }, { @@ -2072,6 +1949,7 @@ "id": "LPMuS0gLW0jc" }, "source": [ + "### 3.1 Data Analysis on AVFER\n", "First of all, we need to check the amount of png and jpg on the training set. Actually, validation and testing set are in jpg image format due to the AffectNet splitting" ] }, @@ -2394,7 +2272,7 @@ "id": "KsT90RRpoB3Y" }, "source": [ - "## 4. Loading and Balancing" + "## 4. Loading and Balancing Datasets" ] }, { @@ -2403,6 +2281,7 @@ "id": "MlUAtTmmoI-M" }, "source": [ + "### 4.1 AVFER Loading and Balancing\n", "AVFER contains AffectNet in the validation and testing set and FER-2013 and CK+48 in the training set. We need to balance it remains only a small amount of samples in the val/test sets and put the rest in the training set. We need to balance every class in the testing and validation set before put the residual samples in the training folder." ] }, @@ -3931,12 +3810,48 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 6, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "BItVISfStbBL", + "outputId": "2defeaef-ede4-4d80-aa4f-c64428ef46ba" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Requirement already satisfied: timm in /usr/local/lib/python3.7/dist-packages (0.5.4)\n", + "Requirement already satisfied: torch>=1.4 in /usr/local/lib/python3.7/dist-packages (from timm) (1.11.0+cu113)\n", + "Requirement already satisfied: torchvision in /usr/local/lib/python3.7/dist-packages (from timm) (0.12.0+cu113)\n", + "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from torch>=1.4->timm) (4.2.0)\n", + "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /usr/local/lib/python3.7/dist-packages (from torchvision->timm) (7.1.2)\n", + "Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from torchvision->timm) (2.23.0)\n", + "Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from torchvision->timm) (1.21.6)\n", + "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision->timm) (3.0.4)\n", + "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision->timm) (2.10)\n", + "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision->timm) (1.24.3)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->torchvision->timm) (2021.10.8)\n" + ] + } + ], + "source": [ + "!pip install timm" + ] + }, + { + "cell_type": "code", + "execution_count": 7, "metadata": { "id": "rZYiTth-y7yy" }, "outputs": [], "source": [ + "import timm, torch, os\n", + "from torchvision import datasets, models, transforms\n", + "\n", "input_size = (224,224)\n", "batch_size = 60\n", "\n", @@ -3945,7 +3860,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": { "id": "yk-iKrzguAQR" }, @@ -3958,13 +3873,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "MW0qScRotgal", - "outputId": "f9f63319-f21d-4616-b87a-8c696f13f29c" + "outputId": "9faa8dfc-df0c-4c91-a2cd-33c28eea469f" }, "outputs": [ { @@ -3973,14 +3888,6 @@ "text": [ "Initializing Datasets and Dataloaders...\n" ] - }, - { - "output_type": "stream", - "name": "stderr", - "text": [ - "/usr/local/lib/python3.7/dist-packages/torch/utils/data/dataloader.py:490: UserWarning: This DataLoader will create 8 worker processes in total. Our suggested max number of worker in current system is 4, which is smaller than what this DataLoader is going to create. Please be aware that excessive worker creation might get DataLoader running slow or even freeze, lower the worker number to avoid potential slowness/freeze if necessary.\n", - " cpuset_checked))\n" - ] } ], "source": [ @@ -4007,18 +3914,60 @@ "image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val']}\n", "\n", "# Create training and validation dataloaders\n", - "dataloaders_dict = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size, shuffle=True, num_workers=8,pin_memory=True) for x in ['train', 'val']}" + "dataloaders_dict = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size, shuffle=True, num_workers=16,pin_memory=True) for x in ['train', 'val']}" ] }, { "cell_type": "code", - "execution_count": null, + "source": [ + "!nvidia-smi" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "EYqeG93OyDsV", + "outputId": "4edc1c57-a1c3-4aae-e11d-f44890605eb3" + }, + "execution_count": 13, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Wed May 11 07:17:56 2022 \n", + "+-----------------------------------------------------------------------------+\n", + "| NVIDIA-SMI 460.32.03 Driver Version: 460.32.03 CUDA Version: 11.2 |\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 P100-PCIE... Off | 00000000:00:04.0 Off | 0 |\n", + "| N/A 41C P0 29W / 250W | 2MiB / 16280MiB | 0% Default |\n", + "| | | N/A |\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" + ] + } + ] + }, + { + "cell_type": "code", + "execution_count": 14, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "AkRMzh5uyj6n", - "outputId": "44158150-8e85-41f8-c8e3-94c88e469f7b" + "outputId": "d89b31a8-a493-4037-d94a-2d08ee2abfbe" }, "outputs": [ { @@ -4031,31 +3980,40 @@ } ], "source": [ + "from __future__ import print_function\n", + "from __future__ import division\n", + "from torch.optim import lr_scheduler\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import numpy as np\n", + "import torchvision\n", + "import time\n", + "import copy\n", "print(\"PyTorch Version: \",torch.__version__)\n", "print(\"Torchvision Version: \",torchvision.__version__)" ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 15, "metadata": { "id": "OY4wmSSvyR2r" }, "outputs": [], "source": [ "NUM_CLASSES = 8\n", - "model = timm.create_model('vit_base_patch16_sam_224', pretrained=True)" + "model = timm.create_model('vit_base_patch16_224', pretrained=True)" ] }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 16, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "kEh7xW8xycSX", - "outputId": "091f7a2b-07b8-4586-e696-17a945513262" + "outputId": "31b9107c-7040-4837-8d47-505cbcb9ea8a" }, "outputs": [ { @@ -4293,7 +4251,7 @@ ] }, "metadata": {}, - "execution_count": 28 + "execution_count": 16 } ], "source": [ @@ -4302,13 +4260,13 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 17, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "co_WIrPEyeGx", - "outputId": "20f452b5-b880-4f4e-b871-1e26f3d532f1" + "outputId": "313783ae-0e68-47fe-a7cb-c5928b153ec6" }, "outputs": [ { @@ -4546,7 +4504,7 @@ ] }, "metadata": {}, - "execution_count": 29 + "execution_count": 17 } ], "source": [ @@ -4556,12 +4514,15 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 18, "metadata": { "id": "MfPgq1CyyuRW" }, "outputs": [], "source": [ + "import pickle, sys\n", + "\n", + "\n", "def save_history(history, filename):\n", " if os.path.isfile(filename):\n", " os.remove(filename)\n", @@ -4705,23 +4666,52 @@ { "cell_type": "code", "source": [ - "optimizer_set = \"SAM\"" + "!git clone https://github.com/davda54/sam.git" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "BfLdUVTVLFav", + "outputId": "88d57292-bd0f-4cf5-98a0-b54946c6e0fe" + }, + "execution_count": 19, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Cloning into 'sam'...\n", + "remote: Enumerating objects: 179, done.\u001b[K\n", + "remote: Counting objects: 100% (75/75), done.\u001b[K\n", + "remote: Compressing objects: 100% (22/22), done.\u001b[K\n", + "remote: Total 179 (delta 62), reused 53 (delta 53), pack-reused 104\u001b[K\n", + "Receiving objects: 100% (179/179), 650.16 KiB | 1.37 MiB/s, done.\n", + "Resolving deltas: 100% (84/84), done.\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "optimizer_set = \"SGD\"" ], "metadata": { "id": "DmRq96ZqLHhy" }, - "execution_count": null, + "execution_count": 20, "outputs": [] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Ug7mEpCZzD6L", - "outputId": "4fe302cd-51ce-43c1-b641-81c24b49ac0c" + "outputId": "579b51fe-40a1-45b4-f6bb-2483a65de9dd" }, "outputs": [ { @@ -4886,6 +4876,7 @@ } ], "source": [ + "from sam.sam import SAM\n", "# Detect if we have a GPU available\n", "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", "print(device)\n", @@ -4906,7 +4897,7 @@ " print(\"\\t\",name)\n", "\n", "# stochasic gradient descent\n", - "lr_in = 0.01\n", + "lr_in = 0.001\n", "momentum_in = 0.9\n", "if optimizer_set == \"SGD\":\n", " optimizer_ft = optim.SGD(params_to_update, lr=lr_in, momentum=momentum_in)\n", @@ -4925,48 +4916,47 @@ "base_uri": "https://localhost:8080/" }, "id": "TxoRhdLgLgjd", - "outputId": "77f713af-a94e-4f4a-83c1-113ef138fab3" + "outputId": "109f9a70-c88c-4d20-cfbc-66b9f65729e5" }, - "execution_count": null, + "execution_count": 22, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ - "SAM (\n", + "SGD (\n", "Parameter Group 0\n", - " adaptive: False\n", " dampening: 0\n", - " lr: 0.01\n", + " lr: 0.001\n", " maximize: False\n", " momentum: 0.9\n", " nesterov: False\n", - " rho: 0.05\n", " weight_decay: 0\n", ")" ] }, "metadata": {}, - "execution_count": 15 + "execution_count": 22 } ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": { "id": "76ScGC4bVS1m" }, "outputs": [], "source": [ + "import warnings\n", "warnings.filterwarnings('ignore')\n", "\n", "# Setup the loss fxn\n", "criterion = nn.CrossEntropyLoss()\n", - "num_epochs = 10\n", + "num_epochs = 5\n", "\n", "# model general info\n", - "name_model = \"vfer_sam_5\"\n", + "name_model = \"vit_grad\"\n", "base_dir = \"/content/drive/MyDrive/Models/\"\n", "\n", "def mkdir_model(base_dir, name_model, counter):\n", @@ -4988,124 +4978,152 @@ "\n", "# Learning Rate schedule: decays the learning rate by a factor of `gamma` \n", "# every `step_size` epochs\n", - "scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=5, gamma=0.1)" + "scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=10, gamma=0.1)" ] }, { "cell_type": "code", - "execution_count": null, + "source": [ + "import torch, gc\n", + "gc.collect()\n", + "torch.cuda.empty_cache()" + ], "metadata": { - "id": "vSN5a2TqzHMc" + "id": "am5tOfEWkv6P" }, - "outputs": [], - "source": [ - "# Train and evaluate\n", - "model, train_hist, val_hist = train_model(model, dataloaders_dict, criterion, optimizer_ft,scheduler, num_epochs=num_epochs, \n", - " is_inception=False)\n", - "#Saving the updated model for the inference phase\n", - "torch.save(model.state_dict(), model_file)\n", - "\n", - "# Save histories data\n", - "save_history(train_hist, train_history)\n", - "save_history(val_hist, val_history)" - ] + "execution_count": 94, + "outputs": [] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": { - "id": "D5CdZlgJU8KM", + "id": "vSN5a2TqzHMc", "colab": { "base_uri": "https://localhost:8080/" }, - "outputId": "83874cd4-7ade-40af-a4ab-8d6f70c37c97" + "outputId": "b2a3919c-1ad6-49c7-a1c7-e1eb8e4c7193" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "Model loaded correctly\n", "Starting Training\n", "------------\n", - "Epoch 1/10\n", - "------------\n", - "1/10 - train step : 160020/160020 - train_accuracy : 0.770719 - train_loss : 0.619630\n", - "1/10 - val step : 5460/5460 - val_accuracy : 0.552574 - val_loss : 1.302963\n", - "\n", - "Epoch 1 complete in. 90m 7s with best local accuracy and with a learning rate of 1e-05\n", - "------------\n", - "Epoch 2/10\n", - "------------\n", - "2/10 - train step : 160020/160020 - train_accuracy : 0.772456 - train_loss : 0.616135\n", - "2/10 - val step : 5460/5460 - val_accuracy : 0.552757 - val_loss : 1.303394\n", - "\n", - "Epoch 2 complete in. 87m 55s with best local accuracy and with a learning rate of 1e-05\n", - "------------\n", - "Epoch 3/10\n", + "Epoch 1/5\n", "------------\n", - "3/10 - train step : 160020/160020 - train_accuracy : 0.771131 - train_loss : 0.617672\n", - "3/10 - val step : 5460/5460 - val_accuracy : 0.554044 - val_loss : 1.303366\n", + "1/5 - train step : 160020/160020 - train_accuracy : 0.561738 - train_loss : 1.158319\n", + "1/5 - val step : 5460/5460 - val_accuracy : 0.485846 - val_loss : 1.372934\n", "\n", - "Epoch 3 complete in. 88m 9s with best local accuracy and with a learning rate of 1e-05\n", + "Epoch 1 complete in. 167m 60s with best local accuracy and with a learning rate of 0.001\n", "------------\n", - "Epoch 4/10\n", + "Epoch 2/5\n", "------------\n", - "4/10 - train step : 160020/160020 - train_accuracy : 0.772444 - train_loss : 0.615426\n", - "4/10 - val step : 5460/5460 - val_accuracy : 0.553493 - val_loss : 1.302780\n", + "2/5 - train step : 160020/160020 - train_accuracy : 0.638794 - train_loss : 0.954725\n", + "2/5 - val step : 5460/5460 - val_accuracy : 0.525000 - val_loss : 1.279861\n", "\n", - "Epoch 4 complete in. 89m 59s and with a learning rate of 1e-05\n", + "Epoch 2 complete in. 86m 25s with best local accuracy and with a learning rate of 0.001\n", "------------\n", - "Epoch 5/10\n", + "Epoch 3/5\n", "------------\n", - "5/10 - train step : 160020/160020 - train_accuracy : 0.769363 - train_loss : 0.622166\n", - "5/10 - val step : 5460/5460 - val_accuracy : 0.552757 - val_loss : 1.302934\n", + "3/5 - train step : 160020/160020 - train_accuracy : 0.669663 - train_loss : 0.872559\n", + "3/5 - val step : 5460/5460 - val_accuracy : 0.531434 - val_loss : 1.255335\n", "\n", - "Epoch 5 complete in. 90m 9s and with a learning rate of 1e-05\n", + "Epoch 3 complete in. 87m 24s with best local accuracy and with a learning rate of 0.001\n", "------------\n", - "Epoch 6/10\n", + "Epoch 4/5\n", "------------\n", - "6/10 - train step : 160020/160020 - train_accuracy : 0.771838 - train_loss : 0.617192\n", - "6/10 - val step : 5460/5460 - val_accuracy : 0.552941 - val_loss : 1.303886\n", + "4/5 - train step : 160020/160020 - train_accuracy : 0.694225 - train_loss : 0.808225\n", + "4/5 - val step : 5460/5460 - val_accuracy : 0.541728 - val_loss : 1.237785\n", "\n", - "Epoch 6 complete in. 90m 7s and with a learning rate of 1e-05\n", + "Epoch 4 complete in. 87m 26s with best local accuracy and with a learning rate of 0.001\n", "------------\n", - "Epoch 7/10\n", + "Epoch 5/5\n", "------------\n", - "7/10 - train step : 160020/160020 - train_accuracy : 0.773363 - train_loss : 0.614351\n", - "7/10 - val step : 5460/5460 - val_accuracy : 0.552206 - val_loss : 1.304469\n", + "5/5 - train step : 160020/160020 - train_accuracy : 0.715281 - train_loss : 0.753358\n", + "5/5 - val step : 5460/5460 - val_accuracy : 0.554412 - val_loss : 1.291097\n", "\n", - "Epoch 7 complete in. 90m 7s and with a learning rate of 1e-05\n", + "Epoch 5 complete in. 87m 22s with best local accuracy and with a learning rate of 0.001\n", "------------\n", - "Epoch 8/10\n", - "------------\n", - "8/10 - train step : 160020/160020 - train_accuracy : 0.773000 - train_loss : 0.613886\n", - "8/10 - val step : 5460/5460 - val_accuracy : 0.552574 - val_loss : 1.305496\n", - "\n", - "Epoch 8 complete in. 90m 12s and with a learning rate of 1e-05\n", + "Training complete in 516m 40s\n", + "Best val accuracy: 0.554412\n" + ] + } + ], + "source": [ + "# Train and evaluate\n", + "model, train_hist, val_hist = train_model(model, dataloaders_dict, criterion, optimizer_ft,scheduler, num_epochs=num_epochs, \n", + " is_inception=False)\n", + "#Saving the updated model for the inference phase\n", + "torch.save(model.state_dict(), model_file)\n", + "\n", + "# Save histories data\n", + "save_history(train_hist, train_history)\n", + "save_history(val_hist, val_history)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "id": "D5CdZlgJU8KM", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "0e5f432c-502e-4c30-ad36-d138c338773e" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model loaded correctly\n", + "Starting Training\n", "------------\n", - "Epoch 9/10\n", + "Epoch 1/5\n", + "------------\n", + "1/5 - train step : 160020/160020 - train_accuracy : 0.735656 - train_loss : 0.703424\n", + "1/5 - val step : 5460/5460 - val_accuracy : 0.550368 - val_loss : 1.314648\n", + "\n", + "Epoch 1 complete in. 100m 32s with best local accuracy and with a learning rate of 0.001\n", + "------------\n", + "Epoch 2/5\n", "------------\n", - "9/10 - train step : 160020/160020 - train_accuracy : 0.771500 - train_loss : 0.619049\n", - "9/10 - val step : 5460/5460 - val_accuracy : 0.552757 - val_loss : 1.305415\n", + "2/5 - train step : 160020/160020 - train_accuracy : 0.753800 - train_loss : 0.656083\n", + "2/5 - val step : 5460/5460 - val_accuracy : 0.543199 - val_loss : 1.322297\n", "\n", - "Epoch 9 complete in. 90m 15s and with a learning rate of 1e-05\n", + "Epoch 2 complete in. 44m 11s and with a learning rate of 0.001\n", "------------\n", - "Epoch 10/10\n", + "Epoch 3/5\n", "------------\n", - "10/10 - train step : 160020/160020 - train_accuracy : 0.772288 - train_loss : 0.614038\n", - "10/10 - val step : 5460/5460 - val_accuracy : 0.552574 - val_loss : 1.305042\n", + "3/5 - train step : 160020/160020 - train_accuracy : 0.770938 - train_loss : 0.614027\n", + "3/5 - val step : 5460/5460 - val_accuracy : 0.520956 - val_loss : 1.435413\n", "\n", - "Epoch 10 complete in. 90m 4s and with a learning rate of 1.0000000000000002e-06\n", + "Epoch 3 complete in. 44m 10s and with a learning rate of 0.001\n", + "------------\n", + "Epoch 4/5\n", "------------\n", - "Training complete in 897m 13s\n", - "Best val accuracy: 0.554044\n" + "4/5 - train step : 160020/160020 - train_accuracy : 0.786463 - train_loss : 0.574789\n", + "4/5 - val step : 5460/5460 - val_accuracy : 0.540257 - val_loss : 1.361095\n", + "\n", + "Epoch 4 complete in. 44m 10s and with a learning rate of 0.001\n", + "------------\n", + "Epoch 5/5\n", + "------------\n", + "5/5 - train step : 160020/160020 - train_accuracy : 0.799069 - train_loss : 0.538970\n", + "5/5 - val step : 5460/5460 - val_accuracy : 0.550735 - val_loss : 1.313053\n", + "\n", + "Epoch 5 complete in. 44m 13s with best local accuracy and with a learning rate of 0.001\n", + "------------\n", + "Training complete in 277m 20s\n", + "Best val accuracy: 0.550735\n" ] } ], "source": [ "# model general info\n", - "name_model = \"vfer_sam_25\"\n", + "name_model = \"vit_grad_10\"\n", "base_dir = \"/content/drive/MyDrive/Models/\"\n", "mkdir_model(base_dir, name_model, 0)\n", "\n", @@ -5116,14 +5134,14 @@ "val_history = model_folder + name_model + \"_\" + \"history_val\"\n", "\n", "# changing starting lr\n", - "lr_in = 0.00001\n", + "lr_in = 0.001\n", "optimizer_ft = optim.SGD(model.parameters(), lr=lr_in, momentum=momentum_in)\n", "scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=10, gamma=0.1)\n", "\n", "# Train and evaluate\n", "model, train_hist, val_hist = train_model(model, dataloaders_dict, criterion, optimizer_ft,scheduler, num_epochs=num_epochs, \n", " is_inception=False, is_loaded=True, model_folder= model_folder,\n", - " load_state_ws=\"/content/drive/MyDrive/Models/vfer_sam_15/vfer_sam_15.pth\" )\n", + " load_state_ws=\"/content/drive/MyDrive/Models/vit_grad/vit_grad.pth\" )\n", "\n", "\n", "#Saving the updated model for the inference phase\n", @@ -5136,13 +5154,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "metadata": { "id": "2n9U0b9mnc7q", "colab": { "base_uri": "https://localhost:8080/" }, - "outputId": "a7ac5f70-8025-4f51-b56a-d662ab1e9580" + "outputId": "1a8beb89-86e7-4bfc-c4f9-68c290d0ef92" }, "outputs": [ { @@ -5154,47 +5172,47 @@ "------------\n", "Epoch 1/5\n", "------------\n", - "1/5 - train step : 160020/160020 - train_accuracy : 0.767606 - train_loss : 0.626660\n", - "1/5 - val step : 5460/5460 - val_accuracy : 0.552574 - val_loss : 1.303912\n", + "1/5 - train step : 160020/160020 - train_accuracy : 0.848019 - train_loss : 0.412751\n", + "1/5 - val step : 5460/5460 - val_accuracy : 0.556250 - val_loss : 1.548689\n", "\n", - "Epoch 1 complete in. 95m 45s with best local accuracy and with a learning rate of 0.0001\n", + "Epoch 1 complete in. 49m 54s with best local accuracy and with a learning rate of 0.0001\n", "------------\n", "Epoch 2/5\n", "------------\n", - "2/5 - train step : 160020/160020 - train_accuracy : 0.771350 - train_loss : 0.618279\n", - "2/5 - val step : 5460/5460 - val_accuracy : 0.550184 - val_loss : 1.305878\n", + "2/5 - train step : 160020/160020 - train_accuracy : 0.861225 - train_loss : 0.376756\n", + "2/5 - val step : 5460/5460 - val_accuracy : 0.548162 - val_loss : 1.571992\n", "\n", - "Epoch 2 complete in. 95m 35s and with a learning rate of 0.0001\n", + "Epoch 2 complete in. 44m 19s and with a learning rate of 0.0001\n", "------------\n", "Epoch 3/5\n", "------------\n", - "3/5 - train step : 160020/160020 - train_accuracy : 0.771700 - train_loss : 0.615982\n", - "3/5 - val step : 5460/5460 - val_accuracy : 0.550368 - val_loss : 1.308365\n", + "3/5 - train step : 160020/160020 - train_accuracy : 0.866044 - train_loss : 0.360820\n", + "3/5 - val step : 5460/5460 - val_accuracy : 0.549449 - val_loss : 1.639546\n", "\n", - "Epoch 3 complete in. 95m 41s and with a learning rate of 0.0001\n", + "Epoch 3 complete in. 44m 21s and with a learning rate of 0.0001\n", "------------\n", "Epoch 4/5\n", "------------\n", - "4/5 - train step : 160020/160020 - train_accuracy : 0.774106 - train_loss : 0.610770\n", - "4/5 - val step : 5460/5460 - val_accuracy : 0.551838 - val_loss : 1.315496\n", + "4/5 - train step : 160020/160020 - train_accuracy : 0.871231 - train_loss : 0.349658\n", + "4/5 - val step : 5460/5460 - val_accuracy : 0.548346 - val_loss : 1.748063\n", "\n", - "Epoch 4 complete in. 95m 47s and with a learning rate of 0.0001\n", + "Epoch 4 complete in. 44m 21s and with a learning rate of 0.0001\n", "------------\n", "Epoch 5/5\n", "------------\n", - "5/5 - train step : 160020/160020 - train_accuracy : 0.773713 - train_loss : 0.610680\n", - "5/5 - val step : 5460/5460 - val_accuracy : 0.550551 - val_loss : 1.315105\n", + "5/5 - train step : 160020/160020 - train_accuracy : 0.874781 - train_loss : 0.338371\n", + "5/5 - val step : 5460/5460 - val_accuracy : 0.541544 - val_loss : 1.740481\n", "\n", - "Epoch 5 complete in. 95m 48s and with a learning rate of 0.0001\n", + "Epoch 5 complete in. 44m 21s and with a learning rate of 0.0001\n", "------------\n", - "Training complete in 478m 44s\n", - "Best val accuracy: 0.552574\n" + "Training complete in 227m 22s\n", + "Best val accuracy: 0.556250\n" ] } ], "source": [ "# model general info\n", - "name_model = \"vfer_sam_15\"\n", + "name_model = \"vit_grad_15\"\n", "base_dir = \"/content/drive/MyDrive/Models/\"\n", "mkdir_model(base_dir, name_model, 0)\n", "\n", @@ -5214,7 +5232,133 @@ "# Train and evaluate\n", "model, train_hist, val_hist = train_model(model, dataloaders_dict, criterion, optimizer_ft,scheduler, num_epochs=num_epochs, \n", " is_inception=False, is_loaded=True, model_folder= model_folder,\n", - " load_state_ws=\"/content/drive/MyDrive/Models/vfer_sam_10/vfer_sam_10.pth\" )\n", + " load_state_ws=\"/content/drive/MyDrive/Models/vit_grad_10/vit_grad_10.pth\" )\n", + "\n", + "\n", + "#Saving the updated model for the inference phase\n", + "torch.save(model.state_dict(), model_file)\n", + "\n", + "# Save histories data\n", + "save_history(train_hist, train_history)\n", + "save_history(val_hist, val_history)" + ] + }, + { + "cell_type": "code", + "source": [ + "# model general info\n", + "name_model = \"vit_grad_20\"\n", + "base_dir = \"/content/drive/MyDrive/Models/\"\n", + "mkdir_model(base_dir, name_model, 0)\n", + "\n", + "# model files for saving history and model data\n", + "model_folder = base_dir + name_model + \"/\"\n", + "model_file = model_folder + name_model + \".pth\"\n", + "train_history = model_folder + name_model + \"_\" + \"history_train\"\n", + "val_history = model_folder + name_model + \"_\" + \"history_val\"\n", + "\n", + "# updating num_epochs\n", + "num_epochs = 5\n", + "# changing starting lr\n", + "lr_in = 0.0001\n", + "optimizer_ft = optim.SGD(model.parameters(), lr=lr_in, momentum=momentum_in)\n", + "scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=10, gamma=0.1)\n", + "\n", + "# Train and evaluate\n", + "model, train_hist, val_hist = train_model(model, dataloaders_dict, criterion, optimizer_ft,scheduler, num_epochs=num_epochs, \n", + " is_inception=False, is_loaded=True, model_folder= model_folder,\n", + " load_state_ws=\"/content/drive/MyDrive/Models/vit_grad_15/vit_grad_15.pth\" )\n", + "\n", + "\n", + "#Saving the updated model for the inference phase\n", + "torch.save(model.state_dict(), model_file)\n", + "\n", + "# Save histories data\n", + "save_history(train_hist, train_history)\n", + "save_history(val_hist, val_history)" + ], + "metadata": { + "id": "a9nPGOx1K-ae", + "outputId": "86adac6c-e0f5-46a1-eb62-9e1002e30cf4", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": 29, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model loaded correctly\n", + "Starting Training\n", + "------------\n", + "Epoch 1/5\n", + "------------\n", + "1/5 - train step : 160020/160020 - train_accuracy : 0.860738 - train_loss : 0.377989\n", + "1/5 - val step : 5460/5460 - val_accuracy : 0.542096 - val_loss : 1.654774\n", + "\n", + "Epoch 1 complete in. 44m 21s with best local accuracy and with a learning rate of 0.0001\n", + "------------\n", + "Epoch 2/5\n", + "------------\n", + "2/5 - train step : 160020/160020 - train_accuracy : 0.865456 - train_loss : 0.364007\n", + "2/5 - val step : 5460/5460 - val_accuracy : 0.553309 - val_loss : 1.604396\n", + "\n", + "Epoch 2 complete in. 44m 19s with best local accuracy and with a learning rate of 0.0001\n", + "------------\n", + "Epoch 3/5\n", + "------------\n", + "3/5 - train step : 160020/160020 - train_accuracy : 0.870194 - train_loss : 0.349755\n", + "3/5 - val step : 5460/5460 - val_accuracy : 0.545956 - val_loss : 1.710725\n", + "\n", + "Epoch 3 complete in. 44m 18s and with a learning rate of 0.0001\n", + "------------\n", + "Epoch 4/5\n", + "------------\n", + "4/5 - train step : 160020/160020 - train_accuracy : 0.874713 - train_loss : 0.340868\n", + "4/5 - val step : 5460/5460 - val_accuracy : 0.542279 - val_loss : 1.795161\n", + "\n", + "Epoch 4 complete in. 44m 19s and with a learning rate of 0.0001\n", + "------------\n", + "Epoch 5/5\n", + "------------\n", + "5/5 - train step : 160020/160020 - train_accuracy : 0.877938 - train_loss : 0.331511\n", + "5/5 - val step : 5460/5460 - val_accuracy : 0.537684 - val_loss : 1.902309\n", + "\n", + "Epoch 5 complete in. 44m 19s and with a learning rate of 0.0001\n", + "------------\n", + "Training complete in 221m 42s\n", + "Best val accuracy: 0.553309\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# model general info\n", + "name_model = \"vit_grad_25\"\n", + "base_dir = \"/content/drive/MyDrive/Models/\"\n", + "mkdir_model(base_dir, name_model, 0)\n", + "\n", + "# model files for saving history and model data\n", + "model_folder = base_dir + name_model + \"/\"\n", + "model_file = model_folder + name_model + \".pth\"\n", + "train_history = model_folder + name_model + \"_\" + \"history_train\"\n", + "val_history = model_folder + name_model + \"_\" + \"history_val\"\n", + "\n", + "# updating num_epochs\n", + "num_epochs = 5\n", + "# changing starting lr\n", + "lr_in = 0.00001\n", + "optimizer_ft = optim.SGD(model.parameters(), lr=lr_in, momentum=momentum_in)\n", + "scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=10, gamma=0.1)\n", + "\n", + "# Train and evaluate\n", + "model, train_hist, val_hist = train_model(model, dataloaders_dict, criterion, optimizer_ft,scheduler, num_epochs=num_epochs, \n", + " is_inception=False, is_loaded=True, model_folder= model_folder,\n", + " load_state_ws=\"/content/drive/MyDrive/Models/vit_grad_20/vit_grad_20.pth\" )\n", "\n", "\n", "#Saving the updated model for the inference phase\n", @@ -5223,6 +5367,62 @@ "# Save histories data\n", "save_history(train_hist, train_history)\n", "save_history(val_hist, val_history)" + ], + "metadata": { + "id": "veXeI3vYgGqN", + "outputId": "0adf9df0-6377-4cf8-8b82-c5c086c77e04", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": 31, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model loaded correctly\n", + "Starting Training\n", + "------------\n", + "Epoch 1/5\n", + "------------\n", + "1/5 - train step : 160020/160020 - train_accuracy : 0.872163 - train_loss : 0.346655\n", + "1/5 - val step : 5460/5460 - val_accuracy : 0.546875 - val_loss : 1.690988\n", + "\n", + "Epoch 1 complete in. 44m 19s with best local accuracy and with a learning rate of 1e-05\n", + "------------\n", + "Epoch 2/5\n", + "------------\n", + "2/5 - train step : 160020/160020 - train_accuracy : 0.874225 - train_loss : 0.340251\n", + "2/5 - val step : 5460/5460 - val_accuracy : 0.547243 - val_loss : 1.725897\n", + "\n", + "Epoch 2 complete in. 44m 17s with best local accuracy and with a learning rate of 1e-05\n", + "------------\n", + "Epoch 3/5\n", + "------------\n", + "3/5 - train step : 160020/160020 - train_accuracy : 0.876456 - train_loss : 0.336540\n", + "3/5 - val step : 5460/5460 - val_accuracy : 0.545956 - val_loss : 1.739916\n", + "\n", + "Epoch 3 complete in. 44m 19s and with a learning rate of 1e-05\n", + "------------\n", + "Epoch 4/5\n", + "------------\n", + "4/5 - train step : 160020/160020 - train_accuracy : 0.876056 - train_loss : 0.336857\n", + "4/5 - val step : 5460/5460 - val_accuracy : 0.542831 - val_loss : 1.763414\n", + "\n", + "Epoch 4 complete in. 44m 18s and with a learning rate of 1e-05\n", + "------------\n", + "Epoch 5/5\n", + "------------\n", + "5/5 - train step : 160020/160020 - train_accuracy : 0.875638 - train_loss : 0.336899\n", + "5/5 - val step : 5460/5460 - val_accuracy : 0.542647 - val_loss : 1.775629\n", + "\n", + "Epoch 5 complete in. 44m 18s and with a learning rate of 1e-05\n", + "------------\n", + "Training complete in 221m 37s\n", + "Best val accuracy: 0.547243\n" + ] + } ] }, { @@ -5243,18 +5443,9 @@ "\\In this section, we will evaluate the performances of our models based on the accuracy and loss values on the training and validation set with some histograms for the progress analysis during the training phase. " ] }, - { - "cell_type": "markdown", - "source": [ - "### 7.1 Utility Functions" - ], - "metadata": { - "id": "vgXMkT8ob2RG" - } - }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "id": "7cHhjlB665Yq" }, @@ -5262,261 +5453,122 @@ "source": [ "# plot and data management functions\n", "\n", - "def plot_graphs(train, val, num_epochs, limity = None, labelr = \"\", labelb =\"\", xlabel=\"Epochs\", ylabel=\"%\", title=\"Plot\", stepx_size = 1):\n", - " ran = list(range(1, num_epochs + 1, stepx_size))\n", - " print(ran)\n", - " plt.figure(figsize=(16,5))\n", - " plt.subplot(1, 2, 1)\n", - " plt.xlim(1, num_epochs)\n", - " plt.ylim(0, limity)\n", - " plt.plot(ran, train, marker='o', linestyle='--', color='r', label=labelr) \n", - " plt.plot(ran, val, marker='o', linestyle='--', color='b', label=labelb) \n", - " plt.xlabel(xlabel)\n", - " plt.ylabel(ylabel) \n", - " plt.title(title)\n", - " plt.legend() \n", - " plt.show()\n", - "\n", + "def plot_graphs(train, val, metric):\n", + " plt.plot(train)\n", + " plt.plot(val, '')\n", + " plt.xlabel(\"Epochs\")\n", + " plt.ylabel(metric)\n", + " plt.legend([metric, 'val_'+metric])\n", "\n", "def tensor_to_list(tensor_list):\n", " l = []\n", - " try:\n", - " # Tensor support\n", - " for el in tensor_list:\n", - " l.append(el.item())\n", - " except AttributeError:\n", - " # Case of simple list\n", - " for el in tensor_list:\n", - " l.append(el)\n", + " for el in tensor_list:\n", + " l.append(el.item())\n", " return l" ] }, - { - "cell_type": "code", - "source": [ - "def test_model(model, dataloaders, \n", - " is_loaded = False, load_state_ws=None,\n", - " model_folder=\"\"):\n", - " final_scores = []\n", - " overall_labels = []\n", - " if is_loaded and load_state_ws != None:\n", - " # load the model\n", - " state_dict = torch.load(load_state_ws)\n", - " model.load_state_dict(state_dict)\n", - " model.eval()\n", - " print('Model loaded correctly')\n", - " print(\"Testing phase start...\")\n", - " total = len(dataloaders['test'])\n", - " model = model.eval() # Set model to evaluate mode\n", - " dl = dataloaders['test']\n", - " totalIm=0\n", - " running_corrects = 0\n", - " # Iterate over data.\n", - " for inputs, labels in dl:\n", - " totalIm+=len(inputs)\n", - " inputs = inputs.to(device)\n", - " labels = labels.to(device)\n", - " # forward\n", - " # track history if only in train\n", - " with torch.set_grad_enabled(False):\n", - " scores = model(inputs)\n", - " #c oncatenating final scores and label list\n", - " final_scores=[*final_scores,*scores.tolist()]\n", - " overall_labels=[*overall_labels,*labels.tolist()]\n", - " \n", - "\n", - " return final_scores,overall_labels" - ], - "metadata": { - "id": "hwLVUh2VR7NN" - }, - "execution_count": 89, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "### 7.1 ResNet-18 evaluation" - ], - "metadata": { - "id": "ebScBIGXcHu4" - } - }, { "cell_type": "markdown", - "source": [ - "### 7.2 ViT-B/16/S evaluation" - ], "metadata": { - "id": "YPVSpJFQb-n_" - } - }, - { - "cell_type": "markdown", + "id": "nin-hhWX6wX_" + }, "source": [ - "### 7.3 ViT-B/16/SG evaluation" - ], - "metadata": { - "id": "shbf364CcEEC" - } + "\n", + "\n", + "```\n", + "# This is formatted as code\n", + "```\n", + "\n", + "## 7.1 ViT-B/16/SGD evaluation" + ] }, { "cell_type": "markdown", - "source": [ - "### 7.4 ViT-B/16/SAM evaluation" - ], "metadata": { - "id": "wDJ8bzcxRnqp" - } - }, - { - "cell_type": "markdown", + "id": "gb88ybkd7Rkc" + }, "source": [ - "In this section, we will evaluate the trained transformer on hybrid dataset and validated on AffectNet and on a testing set formed by original AffectNet images." - ], - "metadata": { - "id": "McUO4PgxRqIu" - } + "In this section, we will evaluate the trained transformer on hybrid dataset (AVFER) but validate on AffectNet (V2) and on a testing set formed by original AffectNet images." + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "lb7wirVwkZxe" + }, + "outputs": [], "source": [ "# load history divided by steps\n", - "steps = [5, 10, 15, 25]\n", + "steps = [10,20,25]\n", "base_dir = \"/content/drive/MyDrive/Models/\"\n", "train_accuracy = []\n", "val_accuracy = []\n", "train_loss = []\n", "val_loss = []\n", "for step in steps:\n", - " name_model = \"vfer_sam_\" + str(step)\n", + " name_model = \"vfer_grad_\" + str(step)\n", " model_folder = base_dir + name_model + \"/\"\n", " train_accuracy += tensor_to_list(load_history(model_folder + name_model + \"_history_train\"))\n", " val_accuracy += tensor_to_list(load_history(model_folder + name_model + \"_history_val\"))\n", " step_loss = load_history(base_dir + name_model + \"/\" + name_model + \"_history_loss\")\n", " train_loss += step_loss['train']\n", " val_loss += step_loss['val']" - ], - "metadata": { - "id": "Q8m_WwwjRmGm" - }, - "execution_count": 14, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "print(val_accuracy)" - ], + "execution_count": null, "metadata": { - "id": "n-mFa5eR8AHH", - "outputId": "220c113a-220f-456d-e4de-14dce193b820", - "colab": { - "base_uri": "https://localhost:8080/" - } + "id": "YQH077KAmIaa" }, - "execution_count": 15, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "[0.495588, 0.520588, 0.541544, 0.550919, 0.531985, 0.5518382352941177, 0.55, 0.5588235294117647, 0.5527573529411764, 0.5402573529411765, 0.5525735294117647, 0.5501838235294118, 0.5503676470588236, 0.5518382352941177, 0.5505514705882353, 0.5525735294117647, 0.5527573529411764, 0.5540441176470589, 0.5534926470588235, 0.5527573529411764, 0.5529411764705883, 0.5522058823529412, 0.5525735294117647, 0.5527573529411764, 0.5525735294117647]\n" - ] - } - ] - }, - { - "cell_type": "code", + "outputs": [], "source": [ "# we need to merge them together\n", "for i in range(len(train_accuracy)):\n", - " train_accuracy[i] = round(train_accuracy[i], 6)\n", - " val_accuracy[i] = round(val_accuracy[i], 6)\n", - " val_loss[i] = round(val_loss[i], 6)\n", - " train_loss[i] = round(train_loss[i], 6)" - ], - "metadata": { - "id": "Fc3SEJdNRtDL" - }, - "execution_count": 16, - "outputs": [] + " train_accuracy[i] = round(train_accuracy[i], 2)\n", + " val_accuracy[i] = round(val_accuracy[i], 2)\n", + " val_loss[i] = round(val_loss[i], 2)\n", + " train_loss[i] = round(train_loss[i], 2)" + ] }, { "cell_type": "code", - "source": [ - "# accuracy plot\n", - "plot_graphs(train_accuracy, val_accuracy, 25, labelb=\"Validation Accuracy\", labelr=\"Training Accuracy\", ylabel=\"% Accuracy\", title=\"Accuracy Plot\" )" - ], + "execution_count": null, "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 367 - }, - "id": "IT7XOelQRuyO", - "outputId": "d888114d-aa79-4123-8c88-4b1dc9a6029a" + "id": "yyODLhDeWI5K" }, - "execution_count": 17, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "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lnaiyva7rtGVp4hIXh507QoNGoTXvLyUb+KMM87gggsuYMCAAVx99dW89957/PznP6dfv37sv//+zJ49G4Bp06Zx9NFHAyHwnnXWWQwcOJDddtuNe+65pyS9Fi1alCw/cOBAhg4dSq9evRg+fDjx3rImTZpEr169yMnJ4dJLLy1Jt7xp06bRu3dvLrzwQh599NGS6YsXL+bYY48lOzub7OzskoA9duxY9t57b7KzsznttNNK9u+pp55Kmr+DDjqIwYMHs9deewFwzDHHkJOTQ+/evRkzZkzJOi+++CL9+/cnOzubww8/nOLiYrp3786SJUuAEOT32GOPkvGaVD/+AoiIVFdeHpx3HhQWhvH588M4wPDhKd1UQUEBb731Fg0bNmTVqlW8/vrrNGrUiFdeeYURI0bw9NNPb7bOF198wdSpU1m9ejU9e/bkwgsv3OxRiw8//JBZs2ax6667csABB/Dmm2+Sm5vL+eefz/Tp0+nWrRvDhlX86P2jjz7KsGHDGDJkCCNGjGDjxo00btyYSy+9lEMOOYTx48ezadMm1qxZw6xZs7jlllt46623aN++PcuXV9Z5VvDBBx8wc+bMklquDzzwAG3btmXt2rXss88+HH/88RQXF3PuueeW5Hf58uU0aNCAU089lby8PC677DJeeeUVsrOz6dAhUjO0aaHgKSL138CBm0878US46CK47rrSwBlXWAi/+10InkuXwtChZedPm1atbJxwwgk0bNgQgJUrV3L66afz1VdfYWZs3Lgx6TpHHXUUTZs2pWnTpuy4444sXryYTp06lVlm3333LZnWt29f5s2bR4sWLdhtt91KAtawYcPKXOXFbdiwgUmTJnHnnXfSsmVLBgwYwOTJkzn66KOZMmUKY8eOBaBhw4a0bt2asWPHcsIJJ9C+fXsA2rZtu8X93nfffcs8HnLPPfcwfvx4ABYuXMhXX33FkiVLOPjgg0uWi6d71llnMWTIEC677DIeeOABzjyzdjRGp+ApItu3goLk05ctS/mmmjdvXvL+D3/4A4ceeijjx49n3rx5DEwW4IGmTZuWvG/YsCFFRUXVWqYikydPZsWKFfTp0weAwsJCmjVrVmERb0UaNWpUUtmouLi4TMWoxP2eNm0ar7zyCm+//TaZmZkMHDiw0sdHOnfuzE477cSUKVN47733yEtDkXp16J6niNR/06Zt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\n" - }, - "metadata": { - "needs_background": "light" - } - } + "outputs": [], + "source": [ + "# accuracy plot\n", + "plt.figure(figsize=(16,5))\n", + "plt.subplot(1, 2, 1)\n", + "plot_graphs(train_accuracy, val_accuracy, 'accuracy')\n", + "plt.ylim(0, 1)" ] }, { "cell_type": "code", - "source": [ - "plot_graphs(train_loss, val_loss, 25, limity= 1.5, labelr=\"Training Loss\", labelb=\"Validation Loss\", title=\"Loss Plot\", ylabel=\"% Loss\")" - ], + "execution_count": null, "metadata": { - "id": "dcfEqib6NRH4", - "outputId": "bc564d3f-2003-4837-d616-c75d03ee1563", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 367 - } + "id": "096oMIYnWSMo" }, - "execution_count": 18, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "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IiKpoh6GREREIlLyFBERiUjJU0REJCIlTxERkYiUPEVERCJS8hQREYlIyVNERCQiJU8REZGIlDxFREQiUvIUERGJSMlTREQkIiVPERGRiJQ8RUREIlLyFBERiUjJU0REJCIlTxERkYiUPEVERCJS8hQREYlIyVNERCQiJU8REZGIlDxFREQiUvIUERGJSMlTREQkIiVPERGRiJQ8RUREIlLyFBERiUjJU0REJKK0Jk8zO9zMPjGzeWZ2WZLlF5vZR2Y228xeMbPCdMYjIiKSCmlLnmbWELgd+CWwO3CCme1ebrV3gSJ33xN4AhidrnhERERSpVEa990HmOfuXwCY2URgIPBRfAV3fzVh/beAk6rzQuvXr6e4uJg1a9bUIFypbXl5ebRv357GjRtnOhQRkUjSmTzbAV8lPC8G+lay/hnAC9V5oeLiYlq2bEnHjh0xs+rsQmqZu7N06VKKi4vp1KlTpsMREYkkKxoMmdlJQBHw5wqWDzezmWY2c/HixZstX7NmDa1bt1bizCFmRuvWrVVbICI5KZ3J82ugQ8Lz9rF5mzCzQ4ArgaPcfW2yHbn7WHcvcveitm3bJn0xJc7co89MRHJVOpPnDKCzmXUysybAEGBy4gpm1hO4m5A4v0tjLGm1dOlSevToQY8ePdhhhx1o167dxufr1q2rdNuZM2dywQUXbPE19tlnn5TE+tprrzFgwICU7EtEpL5K2zVPd99gZucBU4GGwH3uPsfMrgVmuvtkQjVtC+DxWClkobsfla6YNho/Hq68EhYuhIICGDUKhg6t9u5at27Ne++9B8A111xDixYt+N3vfrdx+YYNG2jUKPmhLioqoqioaIuv8eabb1Y7PhERSa20XvN09ynuvou7/8TdR8XmXRVLnLj7Ie6+vbv3iE21kziHD4cFC8A9PA4fHuan0LBhwxgxYgR9+/bl0ksv5e2332bvvfemZ8+e7LPPPnzyySfApiXBa665htNPP51+/fqx8847c+utt27cX4sWLTau369fPwYPHsyuu+7K0KFDcXcApkyZwq677krv3r254IILIpUwJ0yYQLdu3ejatSsjR44EoKSkhGHDhtG1a1e6devGzTffDMCtt97K7rvvzp577smQIUNqfrBERHJMOlvbZk6/fpvPO+44OOccuPxyWLVq02WrVsFvfhNKn0uWwODBmy5/7bVqhVFcXMybb75Jw4YNWb58OdOnT6dRo0ZMmzaNK664gieffHKzbebOncurr77KihUr6NKlC2efffZmt3K8++67zJkzh5122ol9992Xf//73xQVFXHWWWfxxhtv0KlTJ0444YQqx/nNN98wcuRIZs2aRatWrTjssMOYNGkSHTp04Ouvv+bDDz8E4McffwTgxhtv5Msvv6Rp06Yb54mI1CdZ0dq2VhUXJ5+/dGnKX+rYY4+lYcOGACxbtoxjjz2Wrl27ctFFFzFnzpyk2/Tv35+mTZvSpk0btttuOxYtWrTZOn369KF9+/Y0aNCAHj16MH/+fObOncvOO++88baPKMlzxowZ9OvXj7Zt29KoUSOGDh3KG2+8wc4778wXX3zB+eefz4svvshWW20FwJ577snQoUMZN25chdXRIiJ1Wd385quspFhQEKpqyyuM9QzYpk21S5rlNW/efOPff/jDHzjooIN4+umnmT9/Pv2SlY6Bpk2bbvy7YcOGbNiwoVrrpEKrVq14//33mTp1KnfddRePPfYY9913H88//zxvvPEGzz77LKNGjeKDDz5QEhWReqX+lTxHjYJmzTad16xZmJ9Gy5Yto127dgA88MADKd9/ly5d+OKLL5g/fz4Ajz76aJW37dOnD6+//jpLliyhpKSECRMmcOCBB7JkyRJKS0s55phjuP7663nnnXcoLS3lq6++4qCDDuKmm25i2bJlrFy5MuXvR0Qkm9W/4kK8VW0KW9tWxaWXXsqpp57K9ddfT//+/VO+//z8fO644w4OP/xwmjdvzl577VXhuq+88grt27ff+Pzxxx/nxhtv5KCDDsLd6d+/PwMHDuT999/ntNNOo7S0FIAbbriBkpISTjrpJJYtW4a7c8EFF7DNNtuk/P2IiGQzi7fUzBVFRUU+c+bMTeZ9/PHH7LbbbhmKKHusXLmSFi1a4O6ce+65dO7cmYsuuijTYVVKn52IZJqZzXL3Ld8zmKD+VdvWYffccw89evRgjz32YNmyZZx11lmZDklEpE6qf9W2ddhFF12U9SVNEZG6QCVPERGRiJQ8RUREIlLyFBERiUjJU0REJCIlzxQ46KCDmDp16ibzbrnlFs4+++wKt+nXrx/xW26OOOKIpH3EXnPNNYwZM6bS1540aRIfffTRxudXXXUV06ZNixJ+Uhq6TESkYvUyeY4fDx07QoMG4bGmA6qccMIJTJw4cZN5EydOrHL/slOmTKl2RwPlk+e1117LIYccUq19iYhI1dS75JmOEckGDx7M888/v3Hg6/nz5/PNN9+w//77c/bZZ1NUVMQee+zB1VdfnXT7jh07smTJEgBGjRrFLrvswn777bdx2DII93DutddedO/enWOOOYZVq1bx5ptvMnnyZC655BJ69OjB559/zrBhw3jiiSeA0JNQz5496datG6effjpr167d+HpXX301vXr1olu3bsydO7fK71VDl4mI1NH7PGt7RLJtt92WPn368MILLzBw4EAmTpzIcccdh5kxatQott12W0pKSjj44IOZPXs2e+65Z9L9zJo1i4kTJ/Lee++xYcMGevXqRe/evQE4+uijOfPMMwH4/e9/zz/+8Q/OP/98jjrqKAYMGMDgckGvWbOGYcOG8corr7DLLrtwyimncOedd3LhhRcC0KZNG9555x3uuOMOxowZw7333lv5m0RDl4mIxNW7kme6RiRLrLpNrLJ97LHH6NWrFz179mTOnDmbVLGWN336dAYNGkSzZs3YaqutOOqosrHBP/zwQ/bff3+6devG+PHjKxzSLO6TTz6hU6dO7LLLLgCceuqpvPHGGxuXH3300QD07t17Y2fyW6Khy0REgjr5jZaJEckGDhzIRRddxDvvvMOqVavo3bs3X375JWPGjGHGjBm0atWKYcOGsWbNmug7B4YNG8akSZPo3r07DzzwAK/VcNi0+LBmqRjSTEOXiUh9U+9KnukakaxFixYcdNBBnH766RtLncuXL6d58+ZsvfXWLFq0iBdeeKHSfRxwwAFMmjSJ1atXs2LFCp599tmNy1asWMGOO+7I+vXrGZ9wgbZly5asWLFis3116dKF+fPnM2/ePAAefvhhDjzwwBq9Rw1dJiIS1LtiQDpHJDvhhBMYNGjQxurb7t2707NnT3bddVc6dOjAvvvuW+n2vXr14vjjj6d79+5st912mwwrdt1119G3b1/atm1L3759NybMIUOGcOaZZ3LrrbdubCgEkJeXx/3338+xxx7Lhg0b2GuvvRgxYkSk96Ohy0REktOQZJJR+uxEJNM0JJmIiEgtUPIUERGJSMlTREQkojqTPHPt2q3oMxOR3FUnkmdeXh5Lly7Vl3EOcXeWLl1KXl5epkMREYmsTtyq0r59e4qLi1m8eHGmQ5EI8vLyNrkVRkQkV6Q1eZrZ4cDfgIbAve5+Y7nlTYGHgN7AUuB4d58f9XUaN25Mp06dah6wiIhIFaSt2tbMGgK3A78EdgdOMLPdy612BvCDu/8UuBm4KV3xiIiIpEo6r3n2Aea5+xfuvg6YCAwst85A4MHY308AB5uZpTEmERGRGktn8mwHfJXwvDg2L+k67r4BWAa0TmNMIiIiNZYTDYbMbDgwPPZ0pZl9Utn69UwbYEmmg6hDdDxTT8c0tXQ8U69L1A3SmTy/BjokPG8fm5dsnWIzawRsTWg4tAl3HwuMTVOcOc3MZkbtk1EqpuOZejqmqaXjmXpmNnPLa20qndW2M4DOZtbJzJoAQ4DJ5daZDJwa+3sw8E/XzZoiIpLl0lbydPcNZnYeMJVwq8p97j7HzK4FZrr7ZOAfwMNmNg/4npBgRUREslpar3m6+xRgSrl5VyX8vQY4Np0x1AOqzk4tHc/U0zFNLR3P1It8THNuPE8REZFMqxN924qIiNQmJc8cZWbzzewDM3uvOi3FBMzsPjP7zsw+TJi3rZm9bGafxR5bZTLGXFPBMb3GzL6OnavvmdkRmYwxl5hZBzN71cw+MrM5Zvab2Hydp9VQyfGMfI6q2jZHmdl8oMjddb9XNZnZAcBK4CF37xqbNxr43t1vNLPLgFbuPjKTceaSCo7pNcBKdx+TydhykZntCOzo7u+YWUtgFvArYBg6TyOr5HgeR8RzVCVPqbfc/Q1CK+9EiV1GPkj4x5IqquCYSjW5+7fu/k7s7xXAx4Se2XSeVkMlxzMyJc/c5cBLZjYr1gOTpMb27v5t7O//AttnMpg65Dwzmx2r1lUVYzWYWUegJ/B/6DytsXLHEyKeo0qeuWs/d+9FGLXm3Fh1maRQrMMOXdeouTuBnwA9gG+Bv2Q2nNxjZi2AJ4EL3X154jKdp9ElOZ6Rz1Elzxzl7l/HHr8DniaMYiM1tyh2XSR+feS7DMeT89x9kbuXuHspcA86VyMxs8aEL/rx7v5UbLbO02pKdjyrc44qeeYgM2seu9iNmTUHDgM+rHwrqaLELiNPBZ7JYCx1QvxLPmYQOlerLDZE4z+Aj939rwmLdJ5WQ0XHszrnqFrb5iAz25lQ2oTQS9Qj7j4qgyHlJDObAPQjjFKxCLgamAQ8BhQAC4Dj3F0NYKqogmPaj1Ad5sB84KyE63VSCTPbD5gOfACUxmZfQbhOp/M0okqO5wlEPEeVPEVERCJSta2IiEhESp4iIiIRKXmKiIhEpOQpIiISkZKniIhIREqeIlnIzEoSRnh4L9b5d6r23TFx1BMRia5RpgMQkaRWu3uPTAchIsmp5CmSQ2LjuI6OjeX6tpn9NDa/o5n9M9ax9StmVhCbv72ZPW1m78emfWK7amhm98TGNHzJzPJj618QG+twtplNzNDbFMl6Sp4i2Sm/XLXt8QnLlrl7N+A24JbYvL8DD7r7nsB44NbY/FuB1929O9ALmBOb3xm43d33AH4EjonNvwzoGdvPiHS9OZFcpx6GRLKQma109xZJ5s8Hfu7uX8Q6uP6vu7c2syWEQX7Xx+Z/6+5tzGwx0N7d1ybsoyPwsrt3jj0fCTR29+vN7EXCYNaTgEnuvjLNb1UkJ6nkKZJ7vIK/o1ib8HcJZe0f+gO3E0qpM8xM7SJEklDyFMk9xyc8/if295vAkNjfQwmdXwO8ApwNYGYNzWzrinZqZg2ADu7+KjAS2BrYrPQrImptK5Kt8s3svYTnL7p7/HaVVmY2m1B6PCE273zgfjO7BFgMnBab/xtgrJmdQShhnk0Y7DeZhsC4WII14FZ3/zFl70ikDtE1T5EcErvmWeTuSzIdi0h9pmpbERGRiFTyFBERiUglTxERkYiUPEVERCJS8hQREYlIyVNERCQiJU8REZGIlDxFREQi+n8qFCXh+PFnEAAAAABJRU5ErkJggg==\n" - }, - "metadata": { - "needs_background": "light" - } - } + "outputs": [], + "source": [ + "# loss plot\n", + "plt.figure(figsize=(16, 5))\n", + "plt.subplot(1, 2, 1)\n", + "plot_graphs(train_loss, val_loss, 'loss')\n", + "plt.ylim(0, None)" ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "vAZuAk2cenyt" + }, + "outputs": [], "source": [ "data_transforms_test = {\n", " 'test': transforms.Compose([\n", @@ -5530,152 +5582,128 @@ "image_datasets_test = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms_test[x]) for x in ['test']}\n", "\n", "# Create training and validation dataloaders\n", - "dataloaders_dict_test = {x: torch.utils.data.DataLoader(image_datasets_test[x], batch_size=batch_size, shuffle=False, num_workers=2,pin_memory=True) for x in [ 'test']}\n" - ], - "metadata": { - "id": "nuT-gUlVRy4w" - }, - "execution_count": 21, - "outputs": [] + "dataloaders_dict_test = {x: torch.utils.data.DataLoader(image_datasets_test[x], batch_size=batch_size, shuffle=False, num_workers=2,pin_memory=True) for x in [ 'test']}" + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "edm2Q7iDWCv3" + }, + "outputs": [], "source": [ - "#setting the path of the model to be imported\n", - "model_path='/content/drive/MyDrive/Models/vfer_sam_10/vfer_sam_10.pth'\n", + "def test_model(model, dataloaders, \n", + " is_loaded = False, load_state_ws=None,\n", + " model_folder=\"\"):\n", + " final_scores = []\n", + " overall_labels = []\n", + " if is_loaded and load_state_ws != None:\n", + " # load the model\n", + " state_dict = torch.load(load_state_ws)\n", + " model.load_state_dict(state_dict)\n", + " model.eval()\n", + " print('Model loaded correctly')\n", + " print(\"Testing phase start...\")\n", + " total = len(dataloaders['test'])\n", + " model = model.eval() # Set model to evaluate mode\n", + " dl = dataloaders['test']\n", + " totalIm=0\n", + " # Iterate over data.\n", + " for inputs, labels in dl:\n", + " totalIm+=len(inputs)\n", + " inputs = inputs.to(device)\n", + " labels = labels.to(device)\n", + " # forward\n", + " # track history if only in train\n", + " with torch.set_grad_enabled(False):\n", + " scores = model(inputs)\n", + " #c oncatenating final scores and label list\n", + " final_scores=[*final_scores,*scores.tolist()]\n", + " overall_labels=[*overall_labels,*labels.tolist()]\n", "\n", - "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", - "print(device)\n", - "# Send the model to GPU\n", - "model = model.to(device)\n", - "scores,labels = test_model(model, dataloaders_dict_test, True, load_state_ws=model_path)" - ], + "\n", + "\n", + " return final_scores,overall_labels" + ] + }, + { + "cell_type": "code", + "execution_count": null, "metadata": { - "id": "M5ZhzgHAR8-e", - "outputId": "fd4c5ec1-bfc7-4d61-b22d-5ae6c7d0bc0e", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "NUzW-2wTZ-D2", + "outputId": "b43557b4-561d-4009-cf7a-71d5a03502ad" }, - "execution_count": 90, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "cuda:0\n", "Model loaded correctly\n", - "Testing phase start...\n" + "Testing phase\n" ] } + ], + "source": [ + "from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\n", + "#setting the path of the model to be imported\n", + "model_path='/content/drive/MyDrive/Models/vfer_grad_25/vfer_grad_25.pth'\n", + "\n", + "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", + "print(device)\n", + "# Send the model to GPU\n", + "model = model.to(device)\n", + "scores,labels = test_model(model, dataloaders_dict_test, True, load_state_ws=model_path) " ] }, { "cell_type": "code", - "source": [ - "y_true = labels\n", - "y_pred= np.argmax(scores,1)\n", - "categories = [\"anger\",\"contempt\",\"disgust\",\"fear\",\"happy\",\"neutral\",\"sadness\",\"surprise\"]\n", - "\n", - "\n", - "#labels = train_ds.features['label'].names\n", - "cm = confusion_matrix(y_true, y_pred)\n", - "disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=categories)\n", - "disp.plot(xticks_rotation=45)" - ], + "execution_count": null, "metadata": { - "id": "BXW3lMs_R_oB", - "outputId": "18681aba-15e0-48ae-c26f-4cc7db2d8bb3", "colab": { "base_uri": "https://localhost:8080/", - "height": 330 - } + "height": 327 + }, + "id": "rHxls9jdjPSF", + "outputId": "b65299c3-bc48-4756-e28e-62c9c2b89fd7" }, - "execution_count": 91, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ - "" + "" ] }, + "execution_count": 33, "metadata": {}, - "execution_count": 91 + "output_type": "execute_result" }, { - "output_type": "display_data", "data": { + "image/png": "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\n", "text/plain": [ "
" - ], - "image/png": "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\n" + ] }, - "metadata": { - "needs_background": "light" - } + "metadata": {}, + "output_type": "display_data" } - ] - }, - { - "cell_type": "code", - "source": [ - "test_accuracy = accuracy_score(y_true, y_pred, normalize=True)\n", - "print('Test Accuracy on AffectNet: {}'.format(test_accuracy))" ], - "metadata": { - "id": "i9wIFDFPHJv5", - "outputId": "28099a26-0a38-4f80-abec-56e8bd74c097", - "colab": { - "base_uri": "https://localhost:8080/" - } - }, - "execution_count": 93, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Test Accuracy on AffectNet: 0.53525\n" - ] - } - ] - }, - { - "cell_type": "code", "source": [ - "print(metrics.classification_report(y_true, y_pred, digits=4, target_names=categories))" - ], - "metadata": { - "id": "5jp-cHE8MTyl", - "outputId": "a421e064-8f05-42ca-e617-d866b5d7483e", - "colab": { - "base_uri": "https://localhost:8080/" - } - }, - "execution_count": 95, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - " precision recall f1-score support\n", - "\n", - " anger 0.4590 0.5600 0.5045 500\n", - " contempt 0.5930 0.3060 0.4037 500\n", - " disgust 0.6389 0.3680 0.4670 500\n", - " fear 0.6280 0.5740 0.5998 500\n", - " happy 0.6045 0.8040 0.6901 500\n", - " neutral 0.4058 0.5340 0.4611 500\n", - " sadness 0.5479 0.5720 0.5597 500\n", - " surprise 0.5203 0.5640 0.5413 500\n", - "\n", - " accuracy 0.5353 4000\n", - " macro avg 0.5497 0.5353 0.5284 4000\n", - "weighted avg 0.5497 0.5353 0.5284 4000\n", - "\n" - ] - } + "y_true = labels\n", + "y_pred= np.argmax(scores,1)\n", + "\n", + "categories = [\"anger\",\"contempt\",\"disgust\",\"fear\",\"happy\",\"neutral\",\"sadness\",\"surprise\"]\n", + "\n", + "\n", + "#labels = train_ds.features['label'].names\n", + "cm = confusion_matrix(y_true, y_pred)\n", + "disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=categories)\n", + "disp.plot(xticks_rotation=45)" ] } ], @@ -5684,17 +5712,19 @@ "colab": { "collapsed_sections": [ "A4NdJRd3L0dY", + "-s6FVgkOL4BI", "h_g6Johu3PIz", - "rJ_FETBdMj33", - "HROJ-iJ_MndC", - "dHHgMcQfN6xk", "vAgvaOcbJeBj", "ClgI0sjPvH5j", "fp75RuDu_GVY", "uMLuH1Ng4GxX", "fiKUpawZS342", + "LPMuS0gLW0jc", "KsT90RRpoB3Y", - "bD8RQf6DLk8T" + "MlUAtTmmoI-M", + "bD8RQf6DLk8T", + "Yrza5UhRTQvn", + "nin-hhWX6wX_" ], "machine_shape": "hm", "name": "ViT_Face_Emotion_Recognition.ipynb",