{
  "cells": [
    {
      "cell_type": "code",
      "source": [
        "from google.colab import drive\n",
        "drive.mount('/content/drive')\n"
      ],
      "metadata": {
        "id": "0jig8QEwMYJu",
        "outputId": "466ab000-263b-4180-f829-9e62c10898df",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Mounted at /content/drive\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "train_dir = '/content/drive/MyDrive/Datasets/FER-2013/train'\n",
        "test_dir = '/content/drive/MyDrive/Datasets/FER-2013/test'\n"
      ],
      "metadata": {
        "id": "i-ZDzIJ9T0L8"
      },
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "jaffe_path = '/content/drive/MyDrive/Datasets/jaffe'"
      ],
      "metadata": {
        "id": "KXj5NNfzUOE_"
      },
      "execution_count": 5,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [],
      "metadata": {
        "id": "uLvct8lRTz0k"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n"
      ],
      "metadata": {
        "id": "VJBbniCny0Ul"
      },
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "\n",
        "target = \"/content/drive/MyDrive/Datasets/FER-2013/train/angry\"\n",
        "files = os.listdir(target)\n",
        "supported = [f for f in files if f.lower().endswith(('.jpg', '.jpeg', '.png', '.tif', '.tiff', '.bmp'))]\n",
        "\n",
        "print(\"✅ عدد الصور بصيغ مدعومة في angry:\", len(supported))\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "747Kwk7lUgPe",
        "outputId": "7ad8e979-e02f-4da2-c0a3-2e17086427bf"
      },
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "✅ عدد الصور بصيغ مدعومة في angry: 3995\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from torch.utils.data import Dataset\n",
        "from PIL import Image\n",
        "import os\n",
        "\n",
        "# ترميز المشاعر حسب رمز داخل اسم الملف\n",
        "expression_labels = {\n",
        "    'AN': 0, 'DI': 1, 'FE': 2,\n",
        "    'HA': 3, 'NE': 4, 'SA': 5, 'SU': 6\n",
        "}\n",
        "\n",
        "class JAFEDataset(Dataset):\n",
        "    def __init__(self, root_dir, transform=None):\n",
        "        self.root_dir = root_dir\n",
        "        self.transform = transform\n",
        "        self.images = []\n",
        "        self.labels = []\n",
        "\n",
        "        for file in os.listdir(root_dir):\n",
        "            if file.lower().endswith(('.tiff', '.jpg', '.jpeg', '.png')):\n",
        "                for code in expression_labels:\n",
        "                    if f\".{code}\" in file:\n",
        "                        self.images.append(os.path.join(root_dir, file))\n",
        "                        self.labels.append(expression_labels[code])\n",
        "                        break\n",
        "\n",
        "    def __len__(self):\n",
        "        return len(self.images)\n",
        "\n",
        "    def __getitem__(self, idx):\n",
        "        img = Image.open(self.images[idx]).convert('L')\n",
        "        if self.transform:\n",
        "            img = self.transform(img)\n",
        "        return img, self.labels[idx]\n"
      ],
      "metadata": {
        "id": "Cdkv6by6MXT3"
      },
      "execution_count": 10,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "jaffe_transform = transforms.Compose([\n",
        "    transforms.Resize((48, 48)),\n",
        "    transforms.ToTensor()\n",
        "])\n",
        "\n",
        "jaffe_dataset = JAFEDataset(jaffe_path, transform=jaffe_transform)\n",
        "jaffe_loader = DataLoader(jaffe_dataset, batch_size=16, shuffle=True)\n"
      ],
      "metadata": {
        "id": "yr1ScWrCy5Y8"
      },
      "execution_count": 11,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "\n",
        "from google.colab import drive\n",
        "drive.mount('/content/drive')\n",
        "\n",
        "\n",
        "import os\n",
        "import torch\n",
        "import torchvision.transforms as transforms\n",
        "from torchvision.datasets import ImageFolder\n",
        "from torch.utils.data import DataLoader, Dataset\n",
        "from PIL import Image\n",
        "import torch.nn as nn\n",
        "import torchvision.models as models\n",
        "import torch.optim as optim\n",
        "from sklearn.metrics import accuracy_score\n",
        "\n",
        "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
        "\n",
        "\n",
        "transform = transforms.Compose([\n",
        "    transforms.Grayscale(),\n",
        "    transforms.Resize((48, 48)),\n",
        "    transforms.ToTensor()\n",
        "])"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "bGM7PIqEzHOw",
        "outputId": "9e868125-040b-43cc-f60b-068a542d785b"
      },
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "\n",
        "expression_labels = {\n",
        "    'AN': 0, 'DI': 1, 'FE': 2,\n",
        "    'HA': 3, 'NE': 4, 'SA': 5, 'SU': 6\n",
        "}\n",
        "\n",
        "class JAFEDataset(Dataset):\n",
        "    def __init__(self, root_dir, transform=None):\n",
        "        self.images, self.labels = [], []\n",
        "        self.transform = transform\n",
        "        for file in os.listdir(root_dir):\n",
        "            if file.lower().endswith(('.jpg', '.jpeg', '.png', '.tiff')):\n",
        "                for code in expression_labels:\n",
        "                    if f\".{code}\" in file:\n",
        "                        self.images.append(os.path.join(root_dir, file))\n",
        "                        self.labels.append(expression_labels[code])\n",
        "                        break\n",
        "\n",
        "    def __len__(self):\n",
        "        return len(self.images)\n",
        "\n",
        "    def __getitem__(self, idx):\n",
        "        img = Image.open(self.images[idx]).convert('L')\n",
        "        if self.transform:\n",
        "            img = self.transform(img)\n",
        "        return img, self.labels[idx]\n",
        "\n",
        "\n",
        "jaffe_path = '/content/drive/MyDrive/Datasets/jaffe'\n",
        "jaffe_dataset = JAFEDataset(jaffe_path, transform=transform)\n",
        "jaffe_loader = DataLoader(jaffe_dataset, batch_size=16, shuffle=True)\n"
      ],
      "metadata": {
        "id": "2V6DDYUjzLl8"
      },
      "execution_count": 13,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "\n",
        "def train_model(train_loader, num_classes):\n",
        "    model = models.resnet18(pretrained=True)\n",
        "    model.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)\n",
        "    model.fc = nn.Linear(model.fc.in_features, num_classes)\n",
        "    model = model.to(device)\n",
        "\n",
        "    optimizer = optim.Adam(model.parameters(), lr=0.0001)\n",
        "    criterion = nn.CrossEntropyLoss()\n",
        "\n",
        "    for epoch in range(3):\n",
        "        model.train()\n",
        "        total_loss = 0\n",
        "        for imgs, labels in train_loader:\n",
        "            imgs, labels = imgs.to(device), labels.to(device)\n",
        "            optimizer.zero_grad()\n",
        "            outputs = model(imgs)\n",
        "            loss = criterion(outputs, labels)\n",
        "            loss.backward()\n",
        "            optimizer.step()\n",
        "            total_loss += loss.item()\n",
        "        print(f\"[Epoch {epoch+1}] Loss: {total_loss:.4f}\")\n",
        "    return model\n",
        "\n",
        "\n",
        "def evaluate_model(model, test_loader):\n",
        "    model.eval()\n",
        "    preds, labels = [], []\n",
        "    with torch.no_grad():\n",
        "        for imgs, lbls in test_loader:\n",
        "            imgs = imgs.to(device)\n",
        "            outputs = model(imgs)\n",
        "            _, predicted = torch.max(outputs, 1)\n",
        "            preds.extend(predicted.cpu().numpy())\n",
        "            labels.extend(lbls.numpy())\n",
        "    acc = accuracy_score(labels, preds)\n",
        "    return acc\n"
      ],
      "metadata": {
        "id": "-unP1GJD0E3P"
      },
      "execution_count": 14,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "import os, shutil\n",
        "\n",
        "filtered_train = '/content/filtered_train'\n",
        "filtered_test = '/content/filtered_test'\n",
        "os.makedirs(filtered_train, exist_ok=True)\n",
        "os.makedirs(filtered_test, exist_ok=True)\n",
        "\n",
        "valid_classes = ['sad', 'surprise']\n",
        "\n",
        "for cls in valid_classes:\n",
        "    shutil.copytree(\n",
        "        f'/content/drive/MyDrive/Datasets/FER-2013/train/{cls}',\n",
        "        f'{filtered_train}/{cls}',\n",
        "        dirs_exist_ok=True\n",
        "    )\n",
        "    shutil.copytree(\n",
        "        f'/content/drive/MyDrive/Datasets/FER-2013/test/{cls}',\n",
        "        f'{filtered_test}/{cls}',\n",
        "        dirs_exist_ok=True\n",
        "    )\n"
      ],
      "metadata": {
        "id": "xGomTYdy0RkY"
      },
      "execution_count": 15,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from torchvision.datasets import ImageFolder\n",
        "from torch.utils.data import DataLoader\n",
        "import torchvision.transforms as transforms\n",
        "\n",
        "transform = transforms.Compose([\n",
        "    transforms.Grayscale(),\n",
        "    transforms.Resize((48, 48)),\n",
        "    transforms.ToTensor()\n",
        "])\n",
        "\n",
        "\n",
        "fer_dataset_train = ImageFolder(filtered_train, transform=transform)\n",
        "fer_dataset_test = ImageFolder(filtered_test, transform=transform)\n",
        "\n",
        "fer_loader_train = DataLoader(fer_dataset_train, batch_size=16, shuffle=True)\n",
        "fer_loader_test = DataLoader(fer_dataset_test, batch_size=16, shuffle=False)\n",
        "\n",
        "print(\"✅ عدد الفئات:\", len(fer_dataset_train.classes))\n",
        "print(\"📦 صور تدريب:\", len(fer_dataset_train))\n",
        "print(\"📦 صور اختبار:\", len(fer_dataset_test))\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "fjoVY13Z0q6O",
        "outputId": "94f2dc03-f279-4847-e292-ba58679148bb"
      },
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "✅ عدد الفئات: 2\n",
            "📦 صور تدريب: 4980\n",
            "📦 صور اختبار: 2078\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "print(\"\\n🟦 تدريب على FER (sad + surprise فقط)\")\n",
        "model_fer = train_model(fer_loader_train, num_classes=len(fer_dataset_train.classes))\n",
        "acc_fer = evaluate_model(model_fer, fer_loader_test)\n",
        "print(f\"✅ دقة FER المؤقتة: {acc_fer:.2f}\")\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "3H8-9Kyh3KJn",
        "outputId": "87437510-b121-41d2-a963-54aa06e43605"
      },
      "execution_count": 18,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "🟦 تدريب على FER (sad + surprise فقط)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.11/dist-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.\n",
            "  warnings.warn(\n",
            "/usr/local/lib/python3.11/dist-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=ResNet18_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet18_Weights.DEFAULT` to get the most up-to-date weights.\n",
            "  warnings.warn(msg)\n",
            "Downloading: \"https://download.pytorch.org/models/resnet18-f37072fd.pth\" to /root/.cache/torch/hub/checkpoints/resnet18-f37072fd.pth\n",
            "100%|██████████| 44.7M/44.7M [00:00<00:00, 137MB/s]\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[Epoch 1] Loss: 171.5703\n",
            "[Epoch 2] Loss: 120.5325\n",
            "[Epoch 3] Loss: 89.5785\n",
            "✅ دقة FER المؤقتة: 0.83\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "model_jaffe = train_model(jaffe_loader, num_classes=7)\n",
        "acc_jaffe = evaluate_model(model_jaffe, jaffe_loader)\n",
        "print(f\"✅ دقة JAFFE: {acc_jaffe:.2f}\")\n"
      ],
      "metadata": {
        "id": "Xu5C8jX41Hrg",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "6c605b2b-7af2-4323-8180-a25e7387a08a"
      },
      "execution_count": 19,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.11/dist-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.\n",
            "  warnings.warn(\n",
            "/usr/local/lib/python3.11/dist-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=ResNet18_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet18_Weights.DEFAULT` to get the most up-to-date weights.\n",
            "  warnings.warn(msg)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[Epoch 1] Loss: 30.2210\n",
            "[Epoch 2] Loss: 19.0657\n",
            "[Epoch 3] Loss: 11.7811\n",
            "✅ دقة JAFFE: 0.17\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "print(\"📊 مقارنة النتائج:\")\n",
        "print(f\"✔️ FER (sad + surprise): {acc_fer:.2f}\")\n",
        "print(f\"✔️ JAFFE: {acc_jaffe:.2f}\")\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "aCFtn36Z4hE1",
        "outputId": "ff82b439-e94f-4be9-f1ec-4a75981b76b8"
      },
      "execution_count": 21,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "📊 مقارنة النتائج:\n",
            "✔️ FER (sad + surprise): 0.83\n",
            "✔️ JAFFE: 0.17\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import pandas as pd\n",
        "\n",
        "csv_path = '/content/drive/MyDrive/Datasets/CK+/ckextended.csv'\n",
        "\n",
        "df = pd.read_csv(csv_path)\n",
        "print(df.head())\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "oV7xbFVU48Km",
        "outputId": "3776318a-23cb-43ac-fe0e-6e8d18138c1d"
      },
      "execution_count": 22,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "   emotion                                             pixels     Usage\n",
            "0        6  36 39 35 25 19 11 8 7 3 13 15 9 21 57 75 90 10...  Training\n",
            "1        6  88 74 19 4 5 5 3 12 8 21 15 21 15 18 24 29 32 ...  Training\n",
            "2        6  9 2 4 7 1 1 1 0 7 29 49 76 115 141 156 169 177...  Training\n",
            "3        6  104 106 108 104 95 50 60 61 58 83 126 133 139 ...  Training\n",
            "4        6  68 72 67 67 6 2 1 1 1 1 1 14 24 24 38 65 79 94...  Training\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import numpy as np\n",
        "from torch.utils.data import Dataset\n",
        "from PIL import Image\n",
        "\n",
        "class CKDatasetFromCSV(Dataset):\n",
        "    def __init__(self, csv_path, usage=\"Training\", transform=None):\n",
        "        self.data = pd.read_csv(csv_path)\n",
        "        self.data = self.data[self.data['Usage'] == usage]\n",
        "        self.transform = transform\n",
        "\n",
        "    def __len__(self):\n",
        "        return len(self.data)\n",
        "\n",
        "    def __getitem__(self, idx):\n",
        "        pixels = list(map(int, self.data.iloc[idx]['pixels'].split()))\n",
        "        img = np.array(pixels).reshape(48, 48).astype('uint8')\n",
        "        img = Image.fromarray(img)\n",
        "        label = int(self.data.iloc[idx]['emotion'])\n",
        "\n",
        "        if self.transform:\n",
        "            img = self.transform(img)\n",
        "\n",
        "        return img, label\n"
      ],
      "metadata": {
        "id": "ryMksQR-5Eyi"
      },
      "execution_count": 23,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "transform = transforms.Compose([\n",
        "    transforms.Resize((48, 48)),\n",
        "    transforms.ToTensor()\n",
        "])\n",
        "\n",
        "ck_csv_path = '/content/drive/MyDrive/Datasets/CK+/ckextended.csv'\n",
        "\n",
        "ck_dataset = CKDatasetFromCSV(csv_path=ck_csv_path, usage=\"Training\", transform=transform)\n",
        "ck_loader = DataLoader(ck_dataset, batch_size=16, shuffle=True)\n",
        "\n",
        "print(\"✅ صور CK+: \", len(ck_dataset))\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "G6cxN7_S5VGb",
        "outputId": "e214a07a-979e-454d-d2d7-727cc71cf69b"
      },
      "execution_count": 24,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "✅ صور CK+:  734\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "df = pd.read_csv('/content/drive/MyDrive/Datasets/CK+/ckextended.csv')\n",
        "print(\"الفئات الموجودة:\", sorted(df['emotion'].unique()))\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "f0bsjaJs5YCr",
        "outputId": "14d36574-acca-41da-f35d-ada3386f15d7"
      },
      "execution_count": 25,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "الفئات الموجودة: [np.int64(0), np.int64(1), np.int64(2), np.int64(3), np.int64(4), np.int64(5), np.int64(6), np.int64(7)]\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "model_ck = train_model(ck_loader, num_classes=8)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "eaQDVX3R7Afl",
        "outputId": "145812b5-cf69-44e5-c877-b50a6f8043ad"
      },
      "execution_count": 26,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.11/dist-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.\n",
            "  warnings.warn(\n",
            "/usr/local/lib/python3.11/dist-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=ResNet18_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet18_Weights.DEFAULT` to get the most up-to-date weights.\n",
            "  warnings.warn(msg)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[Epoch 1] Loss: 76.9791\n",
            "[Epoch 2] Loss: 29.1143\n",
            "[Epoch 3] Loss: 16.6405\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "ck_dataset = CKDatasetFromCSV(csv_path=ck_csv_path, usage=\"Training\", transform=transform)\n"
      ],
      "metadata": {
        "id": "g2s0j96M7bFD"
      },
      "execution_count": 27,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "jaffe_dataset = JAFEDataset(jaffe_path, transform=transform)\n"
      ],
      "metadata": {
        "id": "2pq_oa9O7TzB"
      },
      "execution_count": 28,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "fer_train_dir = '/content/drive/MyDrive/Datasets/FER-2013/train'\n",
        "fer_test_dir  = '/content/drive/MyDrive/Datasets/FER-2013/test'\n",
        "\n",
        "jaffe_dir     = '/content/drive/MyDrive/Datasets/jaffe'\n",
        "ck_csv_path   = '/content/drive/MyDrive/Datasets/CK+/ckextended.csv'\n"
      ],
      "metadata": {
        "id": "xQbMgRI79V8P"
      },
      "execution_count": 29,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "from PIL import Image\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "import torch\n",
        "import torch.nn as nn\n",
        "import torch.optim as optim\n",
        "from torch.utils.data import Dataset, DataLoader, ConcatDataset\n",
        "import torchvision.transforms as transforms\n",
        "from torchvision.datasets import ImageFolder\n",
        "import torchvision.models as models\n"
      ],
      "metadata": {
        "id": "YOn-HStz9XYZ"
      },
      "execution_count": 31,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "\n",
        "transform = transforms.Compose([\n",
        "    transforms.Grayscale(num_output_channels=1),\n",
        "    transforms.Resize((48, 48)),\n",
        "    transforms.ToTensor()\n",
        "])\n"
      ],
      "metadata": {
        "id": "Ya1Pmt869w-6"
      },
      "execution_count": 32,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
        "print(\"✅ Running on:\", device)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "-KcjQ6VF_7oa",
        "outputId": "5ede571e-75f8-4eac-abc8-aa540b8a8813"
      },
      "execution_count": 33,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "✅ Running on: cpu\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "target = \"/content/drive/MyDrive/Datasets/FER-2013/train/angry\"\n",
        "files = os.listdir(target)\n",
        "supported = [f for f in files if f.lower().endswith(('.jpg', '.jpeg', '.png', '.tif', '.tiff', '.bmp'))]\n",
        "print(f\"📦 عدد الصور المدعومة في angry: {len(supported)}\")\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "HJ0gz1Rb_-wI",
        "outputId": "bdb30da1-b3d4-4971-b1e2-8200cb98aeb1"
      },
      "execution_count": 34,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "📦 عدد الصور المدعومة في angry: 3995\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import torch.nn as nn\n",
        "import torch.nn.functional as F\n",
        "\n",
        "class DepthwiseSeparableConv(nn.Module):\n",
        "    def __init__(self, in_channels, out_channels):\n",
        "        super().__init__()\n",
        "        self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size=3, padding=1, groups=in_channels, bias=False)\n",
        "        self.pointwise = nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False)\n",
        "        self.bn = nn.BatchNorm2d(out_channels)\n",
        "\n",
        "    def forward(self, x):\n",
        "        x = self.depthwise(x)\n",
        "        x = self.pointwise(x)\n",
        "        x = self.bn(x)\n",
        "        return F.relu(x)\n",
        "\n",
        "class MiniXception(nn.Module):\n",
        "    def __init__(self, num_classes=7):\n",
        "        super().__init__()\n",
        "        self.entry = nn.Sequential(\n",
        "            nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1),\n",
        "            nn.BatchNorm2d(32),\n",
        "            nn.ReLU(),\n",
        "            nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),\n",
        "            nn.BatchNorm2d(64),\n",
        "            nn.ReLU()\n",
        "        )\n",
        "\n",
        "        self.module1 = DepthwiseSeparableConv(64, 128)\n",
        "        self.module2 = DepthwiseSeparableConv(128, 256)\n",
        "        self.module3 = DepthwiseSeparableConv(256, 512)\n",
        "        self.pool = nn.AdaptiveAvgPool2d((1, 1))\n",
        "        self.fc = nn.Linear(512, num_classes)\n",
        "\n",
        "    def forward(self, x):\n",
        "        x = self.entry(x)\n",
        "        x = self.module1(x)\n",
        "        x = self.module2(x)\n",
        "        x = self.module3(x)\n",
        "        x = self.pool(x)\n",
        "        x = x.view(x.size(0), -1)\n",
        "        return self.fc(x)\n"
      ],
      "metadata": {
        "id": "C6oGWXHBADHn"
      },
      "execution_count": 35,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def train_model_minix(model, loader, num_epochs=5, lr=0.001):\n",
        "    model = model.to(device)\n",
        "    optimizer = optim.Adam(model.parameters(), lr=lr)\n",
        "    criterion = nn.CrossEntropyLoss()\n",
        "\n",
        "    for epoch in range(num_epochs):\n",
        "        model.train()\n",
        "        total_loss = 0\n",
        "        for imgs, labels in loader:\n",
        "            imgs, labels = imgs.to(device), labels.to(device)\n",
        "            optimizer.zero_grad()\n",
        "            outputs = model(imgs)\n",
        "            loss = criterion(outputs, labels)\n",
        "            loss.backward()\n",
        "            optimizer.step()\n",
        "            total_loss += loss.item()\n",
        "        print(f\"[Epoch {epoch+1}] Loss: {total_loss:.4f}\")\n",
        "    return model\n"
      ],
      "metadata": {
        "id": "rM1JMEuhAp-f"
      },
      "execution_count": 36,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from sklearn.metrics import accuracy_score\n",
        "\n",
        "def evaluate_model(model, loader):\n",
        "    model.eval()\n",
        "    preds, true = [], []\n",
        "    with torch.no_grad():\n",
        "        for imgs, labels in loader:\n",
        "            imgs = imgs.to(device)\n",
        "            outputs = model(imgs)\n",
        "            _, predicted = torch.max(outputs, 1)\n",
        "            preds.extend(predicted.cpu().numpy())\n",
        "            true.extend(labels.numpy())\n",
        "    acc = accuracy_score(true, preds)\n",
        "    return acc\n"
      ],
      "metadata": {
        "id": "GgEi4ancAuXW"
      },
      "execution_count": 37,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "model = MiniXception(num_classes=7)\n",
        "model = train_model_minix(model, jaffe_loader, num_epochs=5)\n",
        "acc = evaluate_model(model, jaffe_loader)\n",
        "print(f\"✅ دقة Mini-Xception على JAFFE: {acc:.2f}\")\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "fbTtDGGhAxMt",
        "outputId": "6ea1478c-d14d-4d9b-a77e-016b8d860ec1"
      },
      "execution_count": 38,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[Epoch 1] Loss: 28.3883\n",
            "[Epoch 2] Loss: 27.7037\n",
            "[Epoch 3] Loss: 26.6824\n",
            "[Epoch 4] Loss: 26.2634\n",
            "[Epoch 5] Loss: 25.7474\n",
            "✅ دقة Mini-Xception على JAFFE: 0.23\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "class TransferMiniXception(nn.Module):\n",
        "    def __init__(self, num_classes=7):\n",
        "        super().__init__()\n",
        "        self.features = nn.Sequential(\n",
        "            nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1),\n",
        "            nn.BatchNorm2d(32),\n",
        "            nn.ReLU(),\n",
        "            nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),\n",
        "            nn.BatchNorm2d(64),\n",
        "            nn.ReLU(),\n",
        "            DepthwiseSeparableConv(64, 128),\n",
        "            DepthwiseSeparableConv(128, 256),\n",
        "            DepthwiseSeparableConv(256, 512)\n",
        "        )\n",
        "\n",
        "        self.pool = nn.AdaptiveAvgPool2d((1, 1))\n",
        "        self.classifier = nn.Linear(512, num_classes)\n",
        "\n",
        "    def forward(self, x):\n",
        "        x = self.features(x)\n",
        "        x = self.pool(x)\n",
        "        x = x.view(x.size(0), -1)\n",
        "        return self.classifier(x)\n"
      ],
      "metadata": {
        "id": "wUd1-2svAz0f"
      },
      "execution_count": 39,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "model = TransferMiniXception(num_classes=7)\n",
        "\n",
        "for param in model.features.parameters():\n",
        "    param.requires_grad = False\n",
        "\n",
        "model = model.to(device)\n"
      ],
      "metadata": {
        "id": "LvJiJDq_BoXA"
      },
      "execution_count": 41,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def train_transfer(model, loader, num_epochs=5, lr=0.001):\n",
        "    optimizer = optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=lr)\n",
        "    criterion = nn.CrossEntropyLoss()\n",
        "\n",
        "    for epoch in range(num_epochs):\n",
        "        model.train()\n",
        "        total_loss = 0\n",
        "        for imgs, labels in loader:\n",
        "            imgs, labels = imgs.to(device), labels.to(device)\n",
        "            optimizer.zero_grad()\n",
        "            outputs = model(imgs)\n",
        "            loss = criterion(outputs, labels)\n",
        "            loss.backward()\n",
        "            optimizer.step()\n",
        "            total_loss += loss.item()\n",
        "        print(f\"[Epoch {epoch+1}] Loss: {total_loss:.4f}\")\n",
        "    return model\n"
      ],
      "metadata": {
        "id": "qo3KsoCqBsBN"
      },
      "execution_count": 42,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "acc = evaluate_model(model, jaffe_loader)\n",
        "print(f\"✅ دقة Transfer Learning Mini-Xception: {acc:.2f}\")\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "91y2yNU8Bx05",
        "outputId": "2e778e81-9009-46f3-fe07-628726434feb"
      },
      "execution_count": 43,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "✅ دقة Transfer Learning Mini-Xception: 0.14\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from torchvision.models import resnet18, ResNet18_Weights\n",
        "\n",
        "model = resnet18(weights=ResNet18_Weights.DEFAULT)\n",
        "\n",
        "for param in model.parameters():\n",
        "    param.requires_grad = False\n"
      ],
      "metadata": {
        "id": "-sZpKzgqB0-4"
      },
      "execution_count": 44,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "num_classes = 7\n",
        "\n",
        "in_features = model.fc.in_features\n",
        "model.fc = nn.Linear(in_features, num_classes)\n",
        "\n",
        "model = model.to(device)\n"
      ],
      "metadata": {
        "id": "KTWTzY_BCENN"
      },
      "execution_count": 46,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def train_resnet(model, loader, num_epochs=5, lr=0.001):\n",
        "    criterion = nn.CrossEntropyLoss()\n",
        "    optimizer = optim.Adam(model.fc.parameters(), lr=lr)  # فقط طبقة fc\n",
        "\n",
        "    for epoch in range(num_epochs):\n",
        "        model.train()\n",
        "        total_loss = 0\n",
        "        for imgs, labels in loader:\n",
        "            imgs, labels = imgs.to(device), labels.to(device)\n",
        "            optimizer.zero_grad()\n",
        "            outputs = model(imgs)\n",
        "            loss = criterion(outputs, labels)\n",
        "            loss.backward()\n",
        "            optimizer.step()\n",
        "            total_loss += loss.item()\n",
        "        print(f\"[Epoch {epoch+1}] Loss: {total_loss:.4f}\")\n",
        "    return model\n"
      ],
      "metadata": {
        "id": "XNNDnAEDCH4b"
      },
      "execution_count": 47,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "transform = transforms.Compose([\n",
        "    transforms.Resize((48, 48)),\n",
        "    transforms.Grayscale(num_output_channels=3),\n",
        "    transforms.ToTensor(),\n",
        "])\n"
      ],
      "metadata": {
        "id": "ZZaml9fICMOc"
      },
      "execution_count": 49,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "jaffe_dataset = JAFEDataset(jaffe_path, transform=transform)\n",
        "jaffe_loader  = DataLoader(jaffe_dataset, batch_size=16, shuffle=True)\n"
      ],
      "metadata": {
        "id": "VdUnaRnOCPTw"
      },
      "execution_count": 50,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "model = resnet18(weights=ResNet18_Weights.DEFAULT)\n",
        "for param in model.parameters():\n",
        "    param.requires_grad = False\n",
        "\n",
        "model.fc = nn.Linear(model.fc.in_features, 7)\n",
        "model = model.to(device)\n",
        "\n",
        "model = train_resnet(model, jaffe_loader, num_epochs=5)\n",
        "acc = evaluate_model(model, jaffe_loader)\n",
        "print(f\"✅ دقة ResNet18 على JAFFE: {acc:.2f}\")\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "OLt1dKIECg6d",
        "outputId": "1461adf8-3f64-463b-f2d7-e94efd8e885d"
      },
      "execution_count": 51,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[Epoch 1] Loss: 28.6744\n",
            "[Epoch 2] Loss: 25.0066\n",
            "[Epoch 3] Loss: 22.2953\n",
            "[Epoch 4] Loss: 20.3337\n",
            "[Epoch 5] Loss: 19.7773\n",
            "✅ دقة ResNet18 على JAFFE: 0.41\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "transform = transforms.Compose([\n",
        "    transforms.Resize((48, 48)),\n",
        "    transforms.Grayscale(num_output_channels=3),  # ← يحول الصور من 1 إلى 3 قنوات\n",
        "    transforms.ToTensor(),\n",
        "])\n"
      ],
      "metadata": {
        "id": "QFrv8ALNCitl"
      },
      "execution_count": 52,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "jaffe_dataset = JAFEDataset(jaffe_path, transform=transform)\n",
        "jaffe_loader = DataLoader(jaffe_dataset, batch_size=16, shuffle=True)"
      ],
      "metadata": {
        "id": "4WfEMfB6EyUW"
      },
      "execution_count": 53,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def __getitem__(self, idx):\n",
        "    row = self.data.iloc[idx]\n",
        "\n",
        "    # تحويل سلسلة البكسلات إلى صورة NumPy 48x48\n",
        "    pixels = np.fromstring(row['pixels'], dtype=int, sep=' ')\n",
        "    img_array = pixels.reshape(48, 48)  # ← حجم FER وCK+ المعتاد\n",
        "\n",
        "    # تحويل إلى صورة PIL\n",
        "    img = Image.fromarray(img_array.astype(np.uint8)).convert(\"L\")\n",
        "    img = img.convert(\"RGB\")  # ← حتى يعمل ResNet18 (3 قنوات)\n",
        "\n",
        "    if self.transform:\n",
        "        img = self.transform(img)\n",
        "\n",
        "    label = int(row['emotion'])\n",
        "    return img, label\n"
      ],
      "metadata": {
        "id": "0WF3g509E1AA"
      },
      "execution_count": 56,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "fer_path = \"/content/drive/MyDrive/Datasets/FER-2013/train\"  # أو حسب موقعك الفعلي\n"
      ],
      "metadata": {
        "id": "ilp1rZdEFfX0"
      },
      "execution_count": 59,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "\n",
        "fer_path = \"/content/drive/MyDrive/Datasets/FER-2013/train\"\n",
        "\n",
        "for label in os.listdir(fer_path):\n",
        "    folder = os.path.join(fer_path, label)\n",
        "    if os.path.isdir(folder):\n",
        "        images = [f for f in os.listdir(folder) if f.lower().endswith(('.jpg', '.jpeg', '.png'))]\n",
        "        print(f\"{label}: {len(images)} صورة مدعومة\")\n",
        "\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "-eF5q9CvFj-G",
        "outputId": "8040c22e-5a60-4fed-b2a7-e23e2e23cbd7"
      },
      "execution_count": 61,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "surprise: 3171 صورة مدعومة\n",
            "happy: 0 صورة مدعومة\n",
            "fear: 2277 صورة مدعومة\n",
            "sad: 1809 صورة مدعومة\n",
            "neutral: 0 صورة مدعومة\n",
            "angry: 3995 صورة مدعومة\n",
            "disgust: 436 صورة مدعومة\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from torchvision import transforms\n",
        "\n",
        "transform = transforms.Compose([\n",
        "    transforms.Resize((48, 48)),\n",
        "    transforms.RandomHorizontalFlip(p=0.5),\n",
        "    transforms.RandomRotation(10),\n",
        "    transforms.RandomCrop(48, padding=4),\n",
        "    transforms.Grayscale(num_output_channels=3),\n",
        "    transforms.ToTensor(),\n",
        "    transforms.Normalize([0.5]*3, [0.5]*3)\n",
        "])\n"
      ],
      "metadata": {
        "id": "jENwf-NsGY62"
      },
      "execution_count": 62,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from torch.utils.data import DataLoader\n",
        "from torchvision.datasets import ImageFolder\n",
        "\n",
        "train_path = \"/content/drive/MyDrive/Datasets/FER-2013/train\"  # غيّره حسب مسارك\n",
        "\n",
        "transform = transforms.Compose([\n",
        "    transforms.Resize((48, 48)),\n",
        "    transforms.Grayscale(num_output_channels=3),\n",
        "    transforms.RandomHorizontalFlip(),\n",
        "    transforms.ToTensor(),\n",
        "    transforms.Normalize([0.5]*3, [0.5]*3)\n",
        "])\n",
        "\n",
        "train_dataset = ImageFolder(train_path, transform=transform)\n",
        "train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 391
        },
        "id": "3X3qxGXFHI16",
        "outputId": "f756691d-b3a4-4bb6-d2aa-20fd8b0c62ef"
      },
      "execution_count": 67,
      "outputs": [
        {
          "output_type": "error",
          "ename": "FileNotFoundError",
          "evalue": "Found no valid file for the classes happy, neutral. Supported extensions are: .jpg, .jpeg, .png, .ppm, .bmp, .pgm, .tif, .tiff, .webp",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mFileNotFoundError\u001b[0m                         Traceback (most recent call last)",
            "\u001b[0;32m/tmp/ipython-input-67-2083617579.py\u001b[0m in \u001b[0;36m<cell line: 0>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     12\u001b[0m ])\n\u001b[1;32m     13\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 14\u001b[0;31m \u001b[0mtrain_dataset\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mImageFolder\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrain_path\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransform\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtransform\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     15\u001b[0m \u001b[0mtrain_loader\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mDataLoader\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrain_dataset\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbatch_size\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m16\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshuffle\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.11/dist-packages/torchvision/datasets/folder.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, root, transform, target_transform, loader, is_valid_file, allow_empty)\u001b[0m\n\u001b[1;32m    326\u001b[0m         \u001b[0mallow_empty\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mbool\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    327\u001b[0m     ):\n\u001b[0;32m--> 328\u001b[0;31m         super().__init__(\n\u001b[0m\u001b[1;32m    329\u001b[0m             \u001b[0mroot\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    330\u001b[0m             \u001b[0mloader\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.11/dist-packages/torchvision/datasets/folder.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, root, loader, extensions, transform, target_transform, is_valid_file, allow_empty)\u001b[0m\n\u001b[1;32m    148\u001b[0m         \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mroot\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransform\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtransform\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtarget_transform\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtarget_transform\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    149\u001b[0m         \u001b[0mclasses\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclass_to_idx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfind_classes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mroot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 150\u001b[0;31m         samples = self.make_dataset(\n\u001b[0m\u001b[1;32m    151\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mroot\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    152\u001b[0m             \u001b[0mclass_to_idx\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mclass_to_idx\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.11/dist-packages/torchvision/datasets/folder.py\u001b[0m in \u001b[0;36mmake_dataset\u001b[0;34m(directory, class_to_idx, extensions, is_valid_file, allow_empty)\u001b[0m\n\u001b[1;32m    201\u001b[0m             \u001b[0;31m# is potentially overridden and thus could have a different logic.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    202\u001b[0m             \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"The class_to_idx parameter cannot be None.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 203\u001b[0;31m         return make_dataset(\n\u001b[0m\u001b[1;32m    204\u001b[0m             \u001b[0mdirectory\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclass_to_idx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mextensions\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mextensions\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mis_valid_file\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mis_valid_file\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mallow_empty\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mallow_empty\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    205\u001b[0m         )\n",
            "\u001b[0;32m/usr/local/lib/python3.11/dist-packages/torchvision/datasets/folder.py\u001b[0m in \u001b[0;36mmake_dataset\u001b[0;34m(directory, class_to_idx, extensions, is_valid_file, allow_empty)\u001b[0m\n\u001b[1;32m    102\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mextensions\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    103\u001b[0m             \u001b[0mmsg\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;34mf\"Supported extensions are: {extensions if isinstance(extensions, str) else ', '.join(extensions)}\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 104\u001b[0;31m         \u001b[0;32mraise\u001b[0m \u001b[0mFileNotFoundError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    105\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    106\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0minstances\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mFileNotFoundError\u001b[0m: Found no valid file for the classes happy, neutral. Supported extensions are: .jpg, .jpeg, .png, .ppm, .bmp, .pgm, .tif, .tiff, .webp"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "PArhXPRBHLZ1"
      },
      "execution_count": null,
      "outputs": []
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}