{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "8d79b30e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Keras version:  3.10.0\n",
      "\n",
      "TensorFlow version:  2.19.0\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf\n",
    "from tensorflow import keras\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense,Dropout,BatchNormalization\n",
    "from tensorflow.keras import regularizers\n",
    "from tensorflow.keras.optimizers import Adam, RMSprop, SGD\n",
    "\n",
    "print('Keras version: ',keras.__version__)\n",
    "print()\n",
    "print('TensorFlow version: ',tf.__version__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "65762078",
   "metadata": {},
   "outputs": [
    {
     "ename": "FileNotFoundError",
     "evalue": "[WinError 3] The system cannot find the path specified: './dataset/train'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mFileNotFoundError\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[2], line 9\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mtensorflow\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mkeras\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mpreprocessing\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mimage\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m ImageDataGenerator, load_img\n\u001b[0;32m      5\u001b[0m train_datagen \u001b[38;5;241m=\u001b[39m ImageDataGenerator(rescale\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1.\u001b[39m\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m255\u001b[39m,\n\u001b[0;32m      6\u001b[0m                                    zoom_range\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0.3\u001b[39m,\n\u001b[0;32m      7\u001b[0m                                    horizontal_flip\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[1;32m----> 9\u001b[0m training_set \u001b[38;5;241m=\u001b[39m train_datagen\u001b[38;5;241m.\u001b[39mflow_from_directory(train_dir,\n\u001b[0;32m     10\u001b[0m                                                 batch_size\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m64\u001b[39m,\n\u001b[0;32m     11\u001b[0m                                                 target_size\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m48\u001b[39m,\u001b[38;5;241m48\u001b[39m),\n\u001b[0;32m     12\u001b[0m                                                 shuffle\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m,\n\u001b[0;32m     13\u001b[0m                                                 color_mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mgrayscale\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[0;32m     14\u001b[0m                                                 class_mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcategorical\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m     16\u001b[0m validation_datagen \u001b[38;5;241m=\u001b[39m ImageDataGenerator(rescale\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1.\u001b[39m\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m255\u001b[39m)\n\u001b[0;32m     17\u001b[0m validation_set \u001b[38;5;241m=\u001b[39m validation_datagen\u001b[38;5;241m.\u001b[39mflow_from_directory(test_dir,\n\u001b[0;32m     18\u001b[0m                                                 batch_size\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m64\u001b[39m,\n\u001b[0;32m     19\u001b[0m                                                 target_size\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m48\u001b[39m,\u001b[38;5;241m48\u001b[39m),\n\u001b[0;32m     20\u001b[0m                                                 shuffle\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m,\n\u001b[0;32m     21\u001b[0m                                                 color_mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mgrayscale\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[0;32m     22\u001b[0m                                                 class_mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcategorical\u001b[39m\u001b[38;5;124m'\u001b[39m)\n",
      "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python312\\site-packages\\keras\\src\\legacy\\preprocessing\\image.py:1138\u001b[0m, in \u001b[0;36mImageDataGenerator.flow_from_directory\u001b[1;34m(self, directory, target_size, color_mode, classes, class_mode, batch_size, shuffle, seed, save_to_dir, save_prefix, save_format, follow_links, subset, interpolation, keep_aspect_ratio)\u001b[0m\n\u001b[0;32m   1120\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mflow_from_directory\u001b[39m(\n\u001b[0;32m   1121\u001b[0m     \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m   1122\u001b[0m     directory,\n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m   1136\u001b[0m     keep_aspect_ratio\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[0;32m   1137\u001b[0m ):\n\u001b[1;32m-> 1138\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m DirectoryIterator(\n\u001b[0;32m   1139\u001b[0m         directory,\n\u001b[0;32m   1140\u001b[0m         \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m   1141\u001b[0m         target_size\u001b[38;5;241m=\u001b[39mtarget_size,\n\u001b[0;32m   1142\u001b[0m         color_mode\u001b[38;5;241m=\u001b[39mcolor_mode,\n\u001b[0;32m   1143\u001b[0m         keep_aspect_ratio\u001b[38;5;241m=\u001b[39mkeep_aspect_ratio,\n\u001b[0;32m   1144\u001b[0m         classes\u001b[38;5;241m=\u001b[39mclasses,\n\u001b[0;32m   1145\u001b[0m         class_mode\u001b[38;5;241m=\u001b[39mclass_mode,\n\u001b[0;32m   1146\u001b[0m         data_format\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata_format,\n\u001b[0;32m   1147\u001b[0m         batch_size\u001b[38;5;241m=\u001b[39mbatch_size,\n\u001b[0;32m   1148\u001b[0m         shuffle\u001b[38;5;241m=\u001b[39mshuffle,\n\u001b[0;32m   1149\u001b[0m         seed\u001b[38;5;241m=\u001b[39mseed,\n\u001b[0;32m   1150\u001b[0m         save_to_dir\u001b[38;5;241m=\u001b[39msave_to_dir,\n\u001b[0;32m   1151\u001b[0m         save_prefix\u001b[38;5;241m=\u001b[39msave_prefix,\n\u001b[0;32m   1152\u001b[0m         save_format\u001b[38;5;241m=\u001b[39msave_format,\n\u001b[0;32m   1153\u001b[0m         follow_links\u001b[38;5;241m=\u001b[39mfollow_links,\n\u001b[0;32m   1154\u001b[0m         subset\u001b[38;5;241m=\u001b[39msubset,\n\u001b[0;32m   1155\u001b[0m         interpolation\u001b[38;5;241m=\u001b[39minterpolation,\n\u001b[0;32m   1156\u001b[0m         dtype\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdtype,\n\u001b[0;32m   1157\u001b[0m     )\n",
      "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python312\\site-packages\\keras\\src\\legacy\\preprocessing\\image.py:453\u001b[0m, in \u001b[0;36mDirectoryIterator.__init__\u001b[1;34m(self, directory, image_data_generator, target_size, color_mode, classes, class_mode, batch_size, shuffle, seed, data_format, save_to_dir, save_prefix, save_format, follow_links, subset, interpolation, keep_aspect_ratio, dtype)\u001b[0m\n\u001b[0;32m    451\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m classes:\n\u001b[0;32m    452\u001b[0m     classes \u001b[38;5;241m=\u001b[39m []\n\u001b[1;32m--> 453\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m subdir \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28msorted\u001b[39m(os\u001b[38;5;241m.\u001b[39mlistdir(directory)):\n\u001b[0;32m    454\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39misdir(os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mjoin(directory, subdir)):\n\u001b[0;32m    455\u001b[0m             classes\u001b[38;5;241m.\u001b[39mappend(subdir)\n",
      "\u001b[1;31mFileNotFoundError\u001b[0m: [WinError 3] The system cannot find the path specified: './dataset/train'"
     ]
    }
   ],
   "source": [
    "train_dir = \"./dataset/train\" \n",
    "test_dir = \"./dataset/test\" \n",
    "\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img\n",
    "train_datagen = ImageDataGenerator(rescale=1./255,\n",
    "                                   zoom_range=0.3,\n",
    "                                   horizontal_flip=True)\n",
    "\n",
    "training_set = train_datagen.flow_from_directory(train_dir,\n",
    "                                                batch_size=64,\n",
    "                                                target_size=(48,48),\n",
    "                                                shuffle=True,\n",
    "                                                color_mode='grayscale',\n",
    "                                                class_mode='categorical')\n",
    "\n",
    "validation_datagen = ImageDataGenerator(rescale=1./255)\n",
    "validation_set = validation_datagen.flow_from_directory(test_dir,\n",
    "                                                batch_size=64,\n",
    "                                                target_size=(48,48),\n",
    "                                                shuffle=True,\n",
    "                                                color_mode='grayscale',\n",
    "                                                class_mode='categorical')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "90f718a2",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = Sequential([\n",
    "    Conv2D(32, (3, 3), activation='tanh', input_shape=(48, 48,1)),\n",
    "    MaxPooling2D(pool_size=(2, 2)),\n",
    "    Flatten(),\n",
    "    Dense(7, activation='softmax')\n",
    "])\n",
    "\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "29ad3559",
   "metadata": {},
   "outputs": [],
   "source": [
    "model.compile(optimizer=Adam(learning_rate=0.0001), \n",
    "                  loss='categorical_crossentropy', \n",
    "                  metrics=['accuracy'])\n",
    "    \n",
    "#model.compile(optimizer=keras.optimizers.SGD(lr=0.001),\n",
    "#              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n",
    "#              metrics=['accuracy'])\n",
    "\n",
    "#model.compile(loss='sparse_categorical_crossentropy',optimizer='sgd',metrics=[\"accuracy\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "de9144a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "root_logdir = os.path.join(os.curdir,\"my_newlogs2\")\n",
    "def get_run_logdir():\n",
    "    import time\n",
    "    run_id=time.strftime(\"run_%Y_%m_%d_%H_%M_%S\")\n",
    "    return os.path.join(root_logdir,run_id)\n",
    "logdir=get_run_logdir()\n",
    "logdir"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f8cafcab",
   "metadata": {},
   "outputs": [],
   "source": [
    "#create a tensorboard callback function that makes use of folder logger\n",
    "tensorboard_cb=keras.callbacks.TensorBoard(logdir)\n",
    "\n",
    "#create checkpoint callback that saves every epoch\n",
    "checkpoint_cb = keras.callbacks.ModelCheckpoint(\"MLP_model.h5\",\n",
    "    save_best_only=True, verbose=1,mode='min', moniter='val_loss')\n",
    "\n",
    "#create early stopping callback\n",
    "\n",
    "early_stopping_cb = keras.callbacks.EarlyStopping(monitor='val_loss', \n",
    "                          min_delta=0, \n",
    "                          patience=3, \n",
    "                          verbose=1,\n",
    "                          restore_best_weights=True)\n",
    "\n",
    "steps_per_epoch = training_set.n // training_set.batch_size\n",
    "validation_steps = validation_set.n // validation_set.batch_size\n",
    "\n",
    "history = model.fit(x=training_set,\n",
    "                 validation_data=validation_set,\n",
    "                 epochs= 60,\n",
    "                 callbacks=[tensorboard_cb,\n",
    "            checkpoint_cb, early_stopping_cb],\n",
    "                 steps_per_epoch=steps_per_epoch,\n",
    "                 validation_steps=validation_steps)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b52c7cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_history(history):\n",
    "    acc = history.history[\"accuracy\"]\n",
    "    loss = history.history[\"loss\"]\n",
    "    val_loss = history.history[\"val_loss\"]\n",
    "    val_accuracy = history.history[\"val_accuracy\"]\n",
    "    \n",
    "    x = range(1, len(acc) + 1)\n",
    "    \n",
    "    plt.figure(figsize=(12,5))\n",
    "    plt.subplot(1, 2, 1)\n",
    "    plt.plot(x, acc, \"b\", label=\"traning_acc\")\n",
    "    plt.plot(x, val_accuracy, \"r\", label=\"traning_acc\")\n",
    "    plt.title(\"Accuracy\")\n",
    "    \n",
    "    plt.subplot(1, 2, 2)\n",
    "    plt.plot(x, loss, \"b\", label=\"traning_acc\")\n",
    "    plt.plot(x, val_loss, \"r\", label=\"traning_acc\")\n",
    "    plt.title(\"Loss\")\n",
    "    \n",
    "plot_history(history)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aec6b30a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
