{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30762,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 1- Import Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport random as rnd\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\nfrom sklearn.model_selection import train_test_split\n\nimport keras\nfrom keras.models import Sequential\nfrom keras.utils import to_categorical\nfrom keras.preprocessing.image import load_img\nfrom keras.layers import Flatten, Dense, Dropout\nfrom keras.layers import Conv2D, MaxPool2D, BatchNormalization, Activation\n\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nprint(os.listdir(\"/kaggle/input/dogs-vs-cats\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:39:41.833849Z","iopub.execute_input":"2024-12-19T14:39:41.834518Z","iopub.status.idle":"2024-12-19T14:39:41.841575Z","shell.execute_reply.started":"2024-12-19T14:39:41.834483Z","shell.execute_reply":"2024-12-19T14:39:41.840696Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 2- Data-Constants","metadata":{}},{"cell_type":"markdown","source":"## Photo Size","metadata":{}},{"cell_type":"code","source":"FAST_RUN = False\nIMAGE_WIDTH=128\nIMAGE_HEIGHT=128\nIMAGE_CHANNELS=3\nIMAGE_SIZE=(IMAGE_WIDTH, IMAGE_HEIGHT)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:39:45.933170Z","iopub.execute_input":"2024-12-19T14:39:45.933560Z","iopub.status.idle":"2024-12-19T14:39:45.937956Z","shell.execute_reply.started":"2024-12-19T14:39:45.933528Z","shell.execute_reply":"2024-12-19T14:39:45.937110Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 3- Load DataSet","metadata":{}},{"cell_type":"code","source":"# import zipfile\n\n# zip_files = ['test1', 'train']\n\n# for zip_file in zip_files:\n#     with zipfile.ZipFile(f\"../input/dogs-vs-cats/{zip_file}.zip\", \"r\") as z:\n#         z.extractall(\".\")\n#         print(f\"{zip_file} unzipped\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> ## Extract Compressed Files","metadata":{}},{"cell_type":"code","source":"import zipfile\n\npath = \"/kaggle/input/dogs-vs-cats\"\nfor zip_file in os.listdir(path)[:2]:\n    zipfile.ZipFile(f\"{path}/{zip_file}\", 'r').extractall(\".\")\n#     print(f\"{path}/{zip_file}\")\n    print(f\"{zip_file} unzipped\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:39:50.407657Z","iopub.execute_input":"2024-12-19T14:39:50.408047Z","iopub.status.idle":"2024-12-19T14:39:59.436389Z","shell.execute_reply.started":"2024-12-19T14:39:50.408010Z","shell.execute_reply":"2024-12-19T14:39:59.435393Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 4- Data Preprocessing","metadata":{}},{"cell_type":"markdown","source":"> ## Label Encoding","metadata":{}},{"cell_type":"markdown","source":"## train_images = cat.num.jpg","metadata":{}},{"cell_type":"code","source":"train_images = os.listdir(\"/kaggle/working/train\")\nCATEGORIES = []\n\nfor image_name in train_images:\n    class_name = image_name.split('.')[0]  # cat.588.jpg\n    CATEGORIES.append(0 if class_name=='cat' else 1)\n\ndf = pd.DataFrame({\"train_images\": train_images, \"CATEGORIES\": CATEGORIES})","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:40:18.709961Z","iopub.execute_input":"2024-12-19T14:40:18.710787Z","iopub.status.idle":"2024-12-19T14:40:18.751539Z","shell.execute_reply.started":"2024-12-19T14:40:18.710739Z","shell.execute_reply":"2024-12-19T14:40:18.750665Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> ## Show DataFrame","metadata":{}},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:40:23.498679Z","iopub.execute_input":"2024-12-19T14:40:23.499049Z","iopub.status.idle":"2024-12-19T14:40:23.507888Z","shell.execute_reply.started":"2024-12-19T14:40:23.499017Z","shell.execute_reply":"2024-12-19T14:40:23.506941Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.tail()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:43:12.649801Z","iopub.execute_input":"2024-12-19T14:43:12.650149Z","iopub.status.idle":"2024-12-19T14:43:12.658361Z","shell.execute_reply.started":"2024-12-19T14:43:12.650119Z","shell.execute_reply":"2024-12-19T14:43:12.657520Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:43:16.070034Z","iopub.execute_input":"2024-12-19T14:43:16.070621Z","iopub.status.idle":"2024-12-19T14:43:16.088820Z","shell.execute_reply.started":"2024-12-19T14:43:16.070584Z","shell.execute_reply":"2024-12-19T14:43:16.088004Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df[\"CATEGORIES\"].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:43:25.131444Z","iopub.execute_input":"2024-12-19T14:43:25.131807Z","iopub.status.idle":"2024-12-19T14:43:25.143773Z","shell.execute_reply.started":"2024-12-19T14:43:25.131775Z","shell.execute_reply":"2024-12-19T14:43:25.142896Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> ## Visualize The Data","metadata":{}},{"cell_type":"code","source":"df[\"CATEGORIES\"].value_counts().plot.bar()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:43:32.613686Z","iopub.execute_input":"2024-12-19T14:43:32.614068Z","iopub.status.idle":"2024-12-19T14:43:32.771707Z","shell.execute_reply.started":"2024-12-19T14:43:32.614035Z","shell.execute_reply":"2024-12-19T14:43:32.770942Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> ## *From our data we have 12500 cats and 12500 dogs*","metadata":{}},{"cell_type":"markdown","source":"> ## Show Dimensions Of Images","metadata":{}},{"cell_type":"code","source":"shapes = []\n\nfor image in df[\"train_images\"]:\n    path = os.path.join(\"/kaggle/working/train\",image)\n    image_array = plt.imread(path)\n    shapes.append(image_array.shape)\n    \nprint(pd.Series(shapes).value_counts())\n\nindex = np.argmin(shapes)\nprint(f\"\\nThe Minimum Dimension is ==> {shapes[index]}\\n\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:44:00.344679Z","iopub.execute_input":"2024-12-19T14:44:00.345406Z","iopub.status.idle":"2024-12-19T14:44:28.680652Z","shell.execute_reply.started":"2024-12-19T14:44:00.345371Z","shell.execute_reply":"2024-12-19T14:44:28.679856Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> ## **See sample image**\n","metadata":{}},{"cell_type":"code","source":"sample = rnd.choice(train_images)\nimage = load_img(os.path.join(\"/kaggle/working/train\", sample))\nprint(type(image))\nplt.imshow(image)\nplt.axis(\"off\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:44:33.412457Z","iopub.execute_input":"2024-12-19T14:44:33.413303Z","iopub.status.idle":"2024-12-19T14:44:33.632569Z","shell.execute_reply.started":"2024-12-19T14:44:33.413262Z","shell.execute_reply":"2024-12-19T14:44:33.631655Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # Prepare data\n> Because we will use image genaretor with class_mode=\"categorical\". We need to convert column category into string. Then imagenerator will convert it one-hot encoding which is good for our classification.\n> So we will convert 1 to dog and 0 to cat","metadata":{}},{"cell_type":"code","source":"df[\"CATEGORIES\"] = df[\"CATEGORIES\"].replace({0: 'cat', 1: 'dog'})","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:44:48.939187Z","iopub.execute_input":"2024-12-19T14:44:48.939550Z","iopub.status.idle":"2024-12-19T14:44:48.948561Z","shell.execute_reply.started":"2024-12-19T14:44:48.939519Z","shell.execute_reply":"2024-12-19T14:44:48.947892Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:45:04.162912Z","iopub.execute_input":"2024-12-19T14:45:04.163232Z","iopub.status.idle":"2024-12-19T14:45:04.171741Z","shell.execute_reply.started":"2024-12-19T14:45:04.163205Z","shell.execute_reply":"2024-12-19T14:45:04.170790Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # Split Data","metadata":{}},{"cell_type":"code","source":"train_df, valid_df = train_test_split(df, test_size=0.20, random_state=42)\n\ntrain_df = train_df.reset_index(drop=True)\nvalid_df = valid_df.reset_index(drop=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:45:12.413893Z","iopub.execute_input":"2024-12-19T14:45:12.414238Z","iopub.status.idle":"2024-12-19T14:45:12.428374Z","shell.execute_reply.started":"2024-12-19T14:45:12.414208Z","shell.execute_reply":"2024-12-19T14:45:12.427315Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # Show tarin DataFrame","metadata":{}},{"cell_type":"code","source":"train_df['CATEGORIES'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:45:19.360345Z","iopub.execute_input":"2024-12-19T14:45:19.360954Z","iopub.status.idle":"2024-12-19T14:45:19.368893Z","shell.execute_reply.started":"2024-12-19T14:45:19.360920Z","shell.execute_reply":"2024-12-19T14:45:19.368019Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df['CATEGORIES'].value_counts().plot.bar()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:45:23.541925Z","iopub.execute_input":"2024-12-19T14:45:23.542518Z","iopub.status.idle":"2024-12-19T14:45:23.672642Z","shell.execute_reply.started":"2024-12-19T14:45:23.542474Z","shell.execute_reply":"2024-12-19T14:45:23.671797Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # Show valid DataFrame","metadata":{}},{"cell_type":"code","source":"valid_df['CATEGORIES'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:45:28.641131Z","iopub.execute_input":"2024-12-19T14:45:28.641479Z","iopub.status.idle":"2024-12-19T14:45:28.648440Z","shell.execute_reply.started":"2024-12-19T14:45:28.641446Z","shell.execute_reply":"2024-12-19T14:45:28.647658Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"valid_df['CATEGORIES'].value_counts().plot.bar()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:45:31.873300Z","iopub.execute_input":"2024-12-19T14:45:31.874166Z","iopub.status.idle":"2024-12-19T14:45:32.063735Z","shell.execute_reply.started":"2024-12-19T14:45:31.874129Z","shell.execute_reply":"2024-12-19T14:45:32.062927Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # Data Augmentation","metadata":{}},{"cell_type":"code","source":"total_train = train_df.shape[0]\ntotal_validate = valid_df.shape[0]\nbatch_size=15","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:45:41.657079Z","iopub.execute_input":"2024-12-19T14:45:41.657762Z","iopub.status.idle":"2024-12-19T14:45:41.661653Z","shell.execute_reply.started":"2024-12-19T14:45:41.657701Z","shell.execute_reply":"2024-12-19T14:45:41.660690Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> ## Train Generator","metadata":{}},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:45:46.387162Z","iopub.execute_input":"2024-12-19T14:45:46.387522Z","iopub.status.idle":"2024-12-19T14:45:46.396511Z","shell.execute_reply.started":"2024-12-19T14:45:46.387485Z","shell.execute_reply":"2024-12-19T14:45:46.395536Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n    rotation_range=15,\n    rescale=1./255,\n    shear_range=0.1,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    width_shift_range=0.1,\n    height_shift_range=0.1\n)\n\ntrain_generator = train_datagen.flow_from_dataframe(\n    train_df, \n    \"/kaggle/working/train\", \n    x_col='train_images',\n    y_col='CATEGORIES',\n    target_size=IMAGE_SIZE,\n    class_mode='categorical',\n    batch_size=batch_size\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:45:54.071381Z","iopub.execute_input":"2024-12-19T14:45:54.072284Z","iopub.status.idle":"2024-12-19T14:45:54.239354Z","shell.execute_reply.started":"2024-12-19T14:45:54.072231Z","shell.execute_reply":"2024-12-19T14:45:54.238709Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"El código crea un generador de datos usando el método `flow_from_dataframe` de `ImageDataGenerator` en Keras. Este generador procesa las imágenes y sus etiquetas de manera eficiente durante el entrenamiento de un modelo, especialmente cuando el conjunto de datos es muy grande.","metadata":{}},{"cell_type":"markdown","source":"> # Valid Generator","metadata":{}},{"cell_type":"code","source":"valid_datagen = ImageDataGenerator(rescale=1./255)\n\nvalid_generator = valid_datagen.flow_from_dataframe(\n    valid_df, \n    \"/kaggle/working/train\", \n    x_col='train_images',\n    y_col='CATEGORIES',\n    target_size=IMAGE_SIZE,\n    class_mode='categorical',\n    batch_size=batch_size\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:46:01.042916Z","iopub.execute_input":"2024-12-19T14:46:01.043608Z","iopub.status.idle":"2024-12-19T14:46:01.091661Z","shell.execute_reply.started":"2024-12-19T14:46:01.043574Z","shell.execute_reply":"2024-12-19T14:46:01.090844Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # See how our generator work","metadata":{}},{"cell_type":"code","source":"example_df = train_df.sample(n=1) # take 1 image-sample\nprint(example_df, \"\\n\")\n\nexample_df= example_df.reset_index(drop=True)\nprint(example_df, \"\\n\")\n\nexample_generator = train_datagen.flow_from_dataframe(\n    example_df, \n    \"/kaggle/working/train\", \n    x_col='train_images',\n    y_col='CATEGORIES',\n    target_size=IMAGE_SIZE,\n    class_mode='categorical'\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:46:20.821357Z","iopub.execute_input":"2024-12-19T14:46:20.821711Z","iopub.status.idle":"2024-12-19T14:46:20.835674Z","shell.execute_reply.started":"2024-12-19T14:46:20.821678Z","shell.execute_reply":"2024-12-19T14:46:20.834796Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # Show Generated Images from One-Image","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(12, 12))\nfor i in range(0, 15):\n    plt.subplot(5, 3, i+1)\n    for X_batch, Y_batch in example_generator:\n        image = X_batch[0]\n        plt.imshow(image)\n        plt.axis('off')\n        break\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:46:26.995172Z","iopub.execute_input":"2024-12-19T14:46:26.995915Z","iopub.status.idle":"2024-12-19T14:46:28.097018Z","shell.execute_reply.started":"2024-12-19T14:46:26.995880Z","shell.execute_reply":"2024-12-19T14:46:28.095829Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 5- Build The Model","metadata":{}},{"cell_type":"markdown","source":"![image](https://i.imgur.com/ebkMGGu.jpg)","metadata":{}},{"cell_type":"markdown","source":"> * **Input Layer**: It represent input image data. It will reshape image into single diminsion array. Example your image is 64x64 = 4096, it will convert to (4096,1) array.\n> * **Conv Layer**: This layer will extract features from image.\n> * **Pooling Layer**: This layerreduce the spatial volume of input image after convolution.\n> * **Fully Connected Layer**: It connect the network from a layer to another layer\n> * **Output Layer**: It is the predicted values layer.","metadata":{}},{"cell_type":"markdown","source":"> # Fit Model","metadata":{}},{"cell_type":"code","source":"model = Sequential([\n    Conv2D(32, (3, 3), activation='relu', input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS)),\n#     BatchNormalization(),\n    MaxPool2D(pool_size=(4,4)),\n    Dropout(rate=0.25),\n    \n    Conv2D(64, (3, 3), activation='relu'),\n    BatchNormalization(),\n    MaxPool2D(pool_size=(4,4)),\n    Dropout(rate=0.25),\n    \n    Conv2D(128, (3, 3), activation='relu'),\n    BatchNormalization(),\n    MaxPool2D(pool_size=(4,4)),\n    Dropout(rate=0.25),\n    \n    Flatten(),\n    \n    Dense(512, activation='relu'),\n    Dropout(rate=0.5),\n\n    Dense(2, activation='softmax') # 2 because we have cat and dog classes\n\n])\n\n# Compile\nmodel.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\n\n# Summary of Model\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:46:42.099482Z","iopub.execute_input":"2024-12-19T14:46:42.099861Z","iopub.status.idle":"2024-12-19T14:46:42.917058Z","shell.execute_reply.started":"2024-12-19T14:46:42.099829Z","shell.execute_reply":"2024-12-19T14:46:42.916191Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Este código define, compila y muestra un resumen de un modelo de red neuronal convolucional (CNN) usando la API de Keras Sequential. El objetivo del modelo parece ser clasificar imágenes de dos clases (por ejemplo, \"gatos\" y \"perros\") utilizando capas convolucionales y densas.\n\n\n## **Capas Convolucionales y de Pooling:**\n1. Primera capa (Conv2D):\n- Crea 32 filtros (o kernels) de tamaño `(3, 3)` que detectan características locales de la imagen, como bordes o texturas.\n- `activation='relu'`: Aplica la función de activación ReLU para eliminar valores negativos, lo que ayuda al modelo a aprender representaciones no lineales.\n- `input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS):` Define el tamaño de entrada de las imágenes (ancho, alto, y número de canales, como RGB).\n\n2. Primera capa de MaxPooling (`MaxPool2D`):\n- Reduce el tamaño de las características extraídas usando un filtro de tamaño `(4,4)`.\n- Esto disminuye la dimensionalidad y ayuda a evitar el sobreajuste.\n\n3. Capa Dropout `(Dropout(rate=0.25))`:\n- Desactiva aleatoriamente el 25% de las neuronas durante el entrenamiento para reducir el sobreajuste.\n\n4. Segunda y tercera capas (`Conv2D`, `MaxPool2D`, `BatchNormalization`):\n- Similar a la primera, pero con un número creciente de filtros (64 y 128) en cada capa convolucional.\n- BatchNormalization: Normaliza la salida de cada capa para acelerar el entrenamiento y mejorar la estabilidad.\n- MaxPooling y Dropout: Continúan reduciendo dimensionalidad y previniendo el sobreajuste.\n\n## **Capas finales (densas):**\n5. Capa `Flatten`:\n- Convierte la salida de las capas convolucionales en un vector plano (1D), que es necesario para conectarla con las capas densas.\n\n6. Primera capa densa (`Dense(512)`):\n- Contiene 512 neuronas completamente conectadas.\n- `activation='relu'`: Ayuda a aprender relaciones no lineales en los datos.\n\n7. Dropout (`Dropout(rate=0.5)`):\n- Desactiva aleatoriamente el 50% de las neuronas de esta capa para evitar el sobreajuste.\n\n8. Capa de salida (`Dense(2)`):\n- Contiene 2 neuronas porque el problema es una clasificación binaria (dos clases: \"gatos\" y \"perros\").\n- `activation='softmax'`: Calcula la probabilidad de cada clase (salida normalizada entre 0 y 1).","metadata":{}},{"cell_type":"markdown","source":"> ## Callbacks","metadata":{}},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ReduceLROnPlateau","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:46:56.764679Z","iopub.execute_input":"2024-12-19T14:46:56.765371Z","iopub.status.idle":"2024-12-19T14:46:56.769158Z","shell.execute_reply.started":"2024-12-19T14:46:56.765333Z","shell.execute_reply":"2024-12-19T14:46:56.768261Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> ### Early Stop\n> To prevent over fitting we will stop the learning after 10 epochs and val_loss value not decreased","metadata":{}},{"cell_type":"code","source":"earlystop = EarlyStopping(patience=5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:46:58.920883Z","iopub.execute_input":"2024-12-19T14:46:58.921755Z","iopub.status.idle":"2024-12-19T14:46:58.925843Z","shell.execute_reply.started":"2024-12-19T14:46:58.921701Z","shell.execute_reply":"2024-12-19T14:46:58.924936Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**EarlyStopping** es una técnica de regularización que se utiliza durante el entrenamiento de modelos de aprendizaje profundo para evitar el sobreajuste y ahorrar tiempo de entrenamiento. El parámetro `patience` define cuántas épocas se espera antes de detener el entrenamiento si no hay mejora en el desempeño del modelo (según una métrica como val_loss).\n\n**Detalles:**\npatience=5 significa que si después de 5 épocas consecutivas no se observa una mejora en la métrica monitoreada (por ejemplo, val_loss), el entrenamiento se detendrá automáticamente.\nAyuda a evitar que el modelo siga entrenándose innecesariamente si ya alcanzó su mejor desempeño.\n","metadata":{}},{"cell_type":"markdown","source":"> ### Learning Rate Reduction\n> We will reduce the learning rate when then accuracy not increase for 2 steps","metadata":{}},{"cell_type":"code","source":"learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', \n                                            patience=2, \n                                            verbose=1, \n                                            factor=0.5, \n                                            min_lr=0.00001)\n\ncallbacks = [earlystop, learning_rate_reduction]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:47:03.099303Z","iopub.execute_input":"2024-12-19T14:47:03.099649Z","iopub.status.idle":"2024-12-19T14:47:03.104081Z","shell.execute_reply.started":"2024-12-19T14:47:03.099618Z","shell.execute_reply":"2024-12-19T14:47:03.103156Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Este código define un `callback` para ajustar dinámicamente la tasa de aprendizaje durante el entrenamiento del modelo utilizando `ReduceLROnPlateau`. Además, se agrupa con otro callback (`earlystop`) en una lista para ser utilizado en el entrenamiento.\n\n## **Cómo funciona durante el entrenamiento:**\n1. ReduceLROnPlateau:\n- Durante el entrenamiento, el modelo supervisa la métrica de validación (val_acc).\n- Si no mejora después de 2 épocas consecutivas, el learning rate se reduce a la mitad.\n- Esto ayuda al modelo a hacer ajustes más finos cuando está cerca de una solución óptima.\n\n2. earlystop:\n- Detiene el entrenamiento si la métrica no mejora después de cierto número de épocas, ahorrando tiempo y recursos.\n\n3. Ambos callbacks trabajan juntos:\n- Primero, se ajusta el learning rate para intentar mejorar el modelo.\n- Si aun así no hay mejoras, earlystop detiene el entrenamiento.\n","metadata":{}},{"cell_type":"code","source":"epochs = 3 if FAST_RUN else 10\n\nhistory = model.fit(train_generator,\n                    epochs=epochs,\n                    validation_data=valid_generator,\n#                     validation_steps=total_validate//batch_size, # 5000//15  = 333\n#                     steps_per_epoch=total_train//batch_size,     # 20000//15 = 1333\n                    callbacks=callbacks)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T14:47:05.882239Z","iopub.execute_input":"2024-12-19T14:47:05.882981Z","iopub.status.idle":"2024-12-19T15:03:06.682802Z","shell.execute_reply.started":"2024-12-19T14:47:05.882942Z","shell.execute_reply":"2024-12-19T15:03:06.681886Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Este código entrena el modelo utilizando el método `model.fit`, especificando datos de entrenamiento y validación, junto con los callbacks que gestionan aspectos como el ajuste de la tasa de aprendizaje y la detención temprana. \n1. Definición de epochs\n```python\n\nepochs = 3 if FAST_RUN else 10\n```\n- Propósito: Define cuántas veces el modelo recorrerá completamente los datos de entrenamiento.\n    - Si FAST_RUN es True (modo rápido), el entrenamiento se ejecuta solo 3 épocas, útil para pruebas rápidas.\n    - Si no, entrena durante 10 épocas.\n\n2. Método `model.fit`\n```python\nhistory = model.fit(train_generator,\n                    epochs=epochs,\n                    validation_data=valid_generator,\n                    callbacks=callbacks)\n```\nEste método entrena el modelo y devuelve un objeto history que contiene los resultados del entrenamiento (pérdida, precisión, etc.).\n\n- Argumentos principales:\n    1. train_generator:\n        - Generador que proporciona datos de entrenamiento por lotes (en este caso, imágenes con etiquetas) para optimizar la memoria y manejar datasets grandes.\n\n    2. epochs=epochs:\n        - Número de veces que el modelo verá todos los datos de entrenamiento.\n\n    3. validation_data=valid_generator:\n    - Generador que proporciona datos de validación. Estos no son usados para ajustar los pesos del modelo, solo para medir el desempeño después de cada época.\n    \n    4. callbacks=callbacks:\n    - Lista de callbacks (como earlystop y learning_rate_reduction) para ajustar el entrenamiento dinámicamente.\n\n","metadata":{}},{"cell_type":"markdown","source":"> # Visualize The Performance","metadata":{}},{"cell_type":"code","source":"accuracy = history.history[\"accuracy\"]\nval_accuracy = history.history[\"val_accuracy\"]\n\nloss = history.history[\"loss\"]\nval_loss = history.history[\"val_loss\"]\n\nepochs = range(len(accuracy))\n\nplt.figure(figsize=(12,6))\n\nplt.subplot(1,2,1)\nplt.plot(epochs, accuracy, 'bo', label=\"Train_Acc\")\nplt.plot(epochs, val_accuracy, 'r', label=\"val_Acc\")\nplt.legend(loc='best', shadow=True)\n\nplt.subplot(1,2,2)\nplt.plot(epochs, loss, 'bo', label=\"Train_Loss\")\nplt.plot(epochs, val_loss, 'r', label=\"val_Loss\")\nplt.legend(loc='best', shadow=True)\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:07:50.566258Z","iopub.execute_input":"2024-12-19T15:07:50.566642Z","iopub.status.idle":"2024-12-19T15:07:50.909413Z","shell.execute_reply.started":"2024-12-19T15:07:50.566609Z","shell.execute_reply":"2024-12-19T15:07:50.908617Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # The Epochs = 10 Only. We Can Increase The number of Epochs to Reach Suitable Accuracy.","metadata":{}},{"cell_type":"markdown","source":"> # Prepare Testing Data","metadata":{}},{"cell_type":"code","source":"test_file_names = os.listdir(\"/kaggle/working/test1\")\ntest_df = pd.DataFrame({'file_name': test_file_names})\n\ntotal_testing = test_df.shape[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:16:20.424621Z","iopub.execute_input":"2024-12-19T15:16:20.425619Z","iopub.status.idle":"2024-12-19T15:16:20.437887Z","shell.execute_reply.started":"2024-12-19T15:16:20.425569Z","shell.execute_reply":"2024-12-19T15:16:20.437204Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # Test The Model","metadata":{}},{"cell_type":"markdown","source":"> # Create Testing Generator","metadata":{}},{"cell_type":"code","source":"test_gen = ImageDataGenerator(rescale=1./255)\ntest_generator = test_gen.flow_from_dataframe(\n    test_df, \n    \"/kaggle/working/test1\", \n    x_col='file_name',\n    y_col=None,\n    class_mode=None,\n    target_size=IMAGE_SIZE,\n    batch_size=batch_size,\n    shuffle=False\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:16:26.916093Z","iopub.execute_input":"2024-12-19T15:16:26.916788Z","iopub.status.idle":"2024-12-19T15:16:27.007175Z","shell.execute_reply.started":"2024-12-19T15:16:26.916751Z","shell.execute_reply":"2024-12-19T15:16:27.006569Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # Predict","metadata":{}},{"cell_type":"code","source":"predictions = model.predict(test_generator)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:16:34.455584Z","iopub.execute_input":"2024-12-19T15:16:34.456237Z","iopub.status.idle":"2024-12-19T15:16:50.778574Z","shell.execute_reply.started":"2024-12-19T15:16:34.456199Z","shell.execute_reply":"2024-12-19T15:16:50.777793Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> For categoral classication the prediction will come with probability of each category. So we will pick the category that have the highest probability with numpy average max","metadata":{}},{"cell_type":"code","source":"test_df[\"CATEGORIES\"] = np.argmax(predictions, axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:17:22.780394Z","iopub.execute_input":"2024-12-19T15:17:22.781055Z","iopub.status.idle":"2024-12-19T15:17:22.786588Z","shell.execute_reply.started":"2024-12-19T15:17:22.781018Z","shell.execute_reply":"2024-12-19T15:17:22.785538Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> We will convert the predict category back into our generator classes by using train_generator.class_indices. It is the classes that image generator map while converting data into computer vision","metadata":{}},{"cell_type":"code","source":"label_map = dict((v,k) for k,v in train_generator.class_indices.items())\ntest_df['CATEGORIES'] = test_df['CATEGORIES'].replace(label_map)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:17:26.819606Z","iopub.execute_input":"2024-12-19T15:17:26.820417Z","iopub.status.idle":"2024-12-19T15:17:26.826830Z","shell.execute_reply.started":"2024-12-19T15:17:26.820381Z","shell.execute_reply":"2024-12-19T15:17:26.825885Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> From our prepare data part. We map data with {1: 'dog', 0: 'cat'}. Now we will map the result back to dog is 1 and cat is 0\n\n","metadata":{}},{"cell_type":"code","source":"test_df['CATEGORIES'] = test_df['CATEGORIES'].replace({ 'dog': 1, 'cat': 0 })","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:17:32.109232Z","iopub.execute_input":"2024-12-19T15:17:32.109574Z","iopub.status.idle":"2024-12-19T15:17:32.120340Z","shell.execute_reply.started":"2024-12-19T15:17:32.109542Z","shell.execute_reply":"2024-12-19T15:17:32.119326Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 6- Visualize The Result","metadata":{}},{"cell_type":"code","source":"test_df[\"CATEGORIES\"].value_counts().plot.bar()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:17:36.040803Z","iopub.execute_input":"2024-12-19T15:17:36.041403Z","iopub.status.idle":"2024-12-19T15:17:36.160642Z","shell.execute_reply.started":"2024-12-19T15:17:36.041367Z","shell.execute_reply":"2024-12-19T15:17:36.159701Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> # Show Predicted Images","metadata":{}},{"cell_type":"code","source":"sample_test = test_df.head(36)\n\nplt.figure(figsize=(15,15))\n\nfor index, row in sample_test.iterrows():\n    file_name = row['file_name']\n    category = row['CATEGORIES']\n    path = os.path.join(\"/kaggle/working/test1\", file_name)\n    img = load_img(path, target_size=IMAGE_SIZE)\n    plt.subplot(6,6,index+1)\n    plt.imshow(img)\n    plt.title(f\"{file_name}\\n is ==> {'cat' if category==0 else 'dog'}\")\n    plt.axis('off')\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:17:44.969468Z","iopub.execute_input":"2024-12-19T15:17:44.969821Z","iopub.status.idle":"2024-12-19T15:17:48.182082Z","shell.execute_reply.started":"2024-12-19T15:17:44.969790Z","shell.execute_reply":"2024-12-19T15:17:48.181017Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 7- Save The Model","metadata":{}},{"cell_type":"code","source":"model.save(\"CNN.h5\")\nmodel.save_weights(\"CNN.weights.h5\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:18:06.870706Z","iopub.execute_input":"2024-12-19T15:18:06.871067Z","iopub.status.idle":"2024-12-19T15:18:06.967023Z","shell.execute_reply.started":"2024-12-19T15:18:06.871037Z","shell.execute_reply":"2024-12-19T15:18:06.966097Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 8- Submission","metadata":{}},{"cell_type":"code","source":"submission_df = test_df.copy()\nsubmission_df['id'] = submission_df['file_name'].str.split('.').str[0]\nsubmission_df['label'] = submission_df['CATEGORIES']\nsubmission_df.drop(['file_name', 'CATEGORIES'], axis=1, inplace=True)\nsubmission_df.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:18:16.951572Z","iopub.execute_input":"2024-12-19T15:18:16.952404Z","iopub.status.idle":"2024-12-19T15:18:16.983508Z","shell.execute_reply.started":"2024-12-19T15:18:16.952366Z","shell.execute_reply":"2024-12-19T15:18:16.982788Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!wget https://wl-genial.cf.tsp.li/resize/728x/jpg/27e/3ac/d457dd54cdbe4443445792ccb8.jpg\nimagen = load_img('d457dd54cdbe4443445792ccb8.jpg', target_size=IMAGE_SIZE)\nimg = np.expand_dims(imagen, 0) # make 'batch' of 1\npred = model.predict(img)\n#pred = labels[\"label_names\"][np.argmax(pred)]\ncategory = np.argmax(pred)\nplt.imshow(imagen)\nplt.title(f\"esa imagen es \\n ==> {'cat' if category==0 else 'dog'}\")\nplt.axis('off')\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:18:19.430516Z","iopub.execute_input":"2024-12-19T15:18:19.431188Z","iopub.status.idle":"2024-12-19T15:18:21.298392Z","shell.execute_reply.started":"2024-12-19T15:18:19.431153Z","shell.execute_reply":"2024-12-19T15:18:21.297188Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!wget https://oglebay.com/wp-content/uploads/2022/06/IMG_5670_M-e1654806092422.jpg\nimagen = load_img('IMG_5670_M-e1654806092422.jpg', target_size=IMAGE_SIZE)\nimg = np.expand_dims(imagen, 0) # make 'batch' of 1\npred = model.predict(img)\n#pred = labels[\"label_names\"][np.argmax(pred)]\ncategory = np.argmax(pred)\nplt.imshow(imagen)\nplt.title(f\"esa imagen es \\n ==> {'cat' if category==0 else 'dog'}\")\nplt.axis('off')\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T15:18:28.891160Z","iopub.execute_input":"2024-12-19T15:18:28.891508Z","iopub.status.idle":"2024-12-19T15:18:30.377279Z","shell.execute_reply.started":"2024-12-19T15:18:28.891479Z","shell.execute_reply":"2024-12-19T15:18:30.375794Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null}]}