{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "0619ff70-ca7a-48d7-bd77-4f02011e980a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# data sets Link:\n",
    "# https://www.kaggle.com/datasets/perkymaster/cats-and-dogs-color\n",
    "# https://www.kaggle.com/datasets/cashutosh/gender-classification-dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "21a2b655-a771-4dcb-8bcb-19506f736d3f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# dowanload image dataset:\n",
    "# https://www.kaggle.com/datasets/perkymaster/cats-and-dogs-color"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "3cddb7bb-dca2-4d6e-87cf-20637685df71",
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.keras import layers, models"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "6c58a962-46a7-4dae-9ae3-15028b82bf6c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# dataset directories\n",
    "\n",
    "base_dir = r'C:\\Users\\mmoghyiri\\Downloads\\cats_dogs'\n",
    "\n",
    "train_dir = base_dir + r'\\train'\n",
    "val_dir   = base_dir + r'\\validation'\n",
    "test_dir  = base_dir + r'\\test'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "5371a85f-11ca-4e63-a411-3f2985b27212",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 2000 files belonging to 2 classes.\n",
      "Found 1000 files belonging to 2 classes.\n",
      "Found 1000 files belonging to 2 classes.\n"
     ]
    }
   ],
   "source": [
    "# Load datasets\n",
    "batch_size = 32\n",
    "img_size = (128, 128)\n",
    "\n",
    "train_ds = tf.keras.preprocessing.image_dataset_from_directory(\n",
    "    train_dir,\n",
    "    image_size=img_size,\n",
    "    batch_size=batch_size\n",
    ")\n",
    "\n",
    "val_ds = tf.keras.preprocessing.image_dataset_from_directory(\n",
    "    val_dir,\n",
    "    image_size=img_size,\n",
    "    batch_size=batch_size\n",
    ")\n",
    "\n",
    "test_ds = tf.keras.preprocessing.image_dataset_from_directory(\n",
    "    test_dir,\n",
    "    image_size=img_size,\n",
    "    batch_size=batch_size\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "e7982575-c996-4a3a-a6bc-708f3d9cd839",
   "metadata": {},
   "outputs": [],
   "source": [
    "# enable performance optimizations\n",
    "AUTOTUNE = tf.data.AUTOTUNE\n",
    "train_ds = train_ds.prefetch(buffer_size=AUTOTUNE)\n",
    "val_ds = val_ds.prefetch(buffer_size=AUTOTUNE)\n",
    "test_ds = test_ds.prefetch(buffer_size=AUTOTUNE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "2b9e4d3c-2393-4fdf-b981-84bb1a5610da",
   "metadata": {},
   "outputs": [],
   "source": [
    "# apply data augmentation\n",
    "data_augmentation = tf.keras.Sequential([\n",
    "    layers.RandomFlip(\"horizontal\"),\n",
    "    layers.RandomRotation(0.1),\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "29dc3491-023e-4ec5-83a7-6e154b0be63f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# model\n",
    "model = models.Sequential([\n",
    "    layers.Input(shape=(*img_size, 3)),\n",
    "    data_augmentation,\n",
    "    layers.Rescaling(1./255),\n",
    "    layers.Conv2D(32, 3, activation='relu'),\n",
    "    layers.MaxPooling2D(),\n",
    "    layers.Conv2D(64, 3, activation='relu'),\n",
    "    layers.MaxPooling2D(),\n",
    "    layers.Conv2D(128, 3, activation='relu'),\n",
    "    layers.MaxPooling2D(),\n",
    "    layers.Flatten(),\n",
    "    layers.Dense(128, activation='relu'),\n",
    "    layers.Dense(1, activation='sigmoid')  # binary classification\n",
    "])\n",
    "\n",
    "model.compile(optimizer='adam',\n",
    "              loss='binary_crossentropy',\n",
    "              metrics=['accuracy'])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "1d453a6a-dbac-4418-b73b-3cff78cfe0f8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/5\n",
      "\u001b[1m63/63\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 129ms/step - accuracy: 0.5073 - loss: 0.7239 - val_accuracy: 0.5560 - val_loss: 0.6883\n",
      "Epoch 2/5\n",
      "\u001b[1m63/63\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m8s\u001b[0m 124ms/step - accuracy: 0.5772 - loss: 0.6772 - val_accuracy: 0.6200 - val_loss: 0.6697\n",
      "Epoch 3/5\n",
      "\u001b[1m63/63\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m8s\u001b[0m 124ms/step - accuracy: 0.6260 - loss: 0.6581 - val_accuracy: 0.6140 - val_loss: 0.6527\n",
      "Epoch 4/5\n",
      "\u001b[1m63/63\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m8s\u001b[0m 124ms/step - accuracy: 0.6665 - loss: 0.6203 - val_accuracy: 0.6260 - val_loss: 0.6472\n",
      "Epoch 5/5\n",
      "\u001b[1m63/63\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m8s\u001b[0m 123ms/step - accuracy: 0.6412 - loss: 0.6345 - val_accuracy: 0.6440 - val_loss: 0.6230\n"
     ]
    }
   ],
   "source": [
    "# train model\n",
    "history = model.fit(\n",
    "    train_ds,\n",
    "    validation_data=val_ds,\n",
    "    epochs=5\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "f7d85485-d6a0-42a0-a471-afefbb481df2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1m32/32\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 37ms/step - accuracy: 0.6476 - loss: 0.6405 \n",
      "\n",
      "test accuracy: 64.30%\n"
     ]
    }
   ],
   "source": [
    "# test model\n",
    "test_loss, test_acc = model.evaluate(test_ds)\n",
    "print(f\"\\ntest accuracy: {test_acc:.2%}\")"
   ]
  }
 ],
 "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
}
