{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:13:27.556231Z","iopub.execute_input":"2024-09-19T17:13:27.556563Z","iopub.status.idle":"2024-09-19T17:13:40.907239Z","shell.execute_reply.started":"2024-09-19T17:13:27.556526Z","shell.execute_reply":"2024-09-19T17:13:40.906265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2- Data-Constants","metadata":{}},{"cell_type":"code","source":"FAST_RUN = False\nFAST_RUN = False\nIMAGE_WIDTH=128\nIMAGE_HEIGHT=128\nIMAGE_CHANNELS=3\nIMAGE_SIZE=(IMAGE_WIDTH, IMAGE_HEIGHT)","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:13:40.908715Z","iopub.execute_input":"2024-09-19T17:13:40.909271Z","iopub.status.idle":"2024-09-19T17:13:40.913919Z","shell.execute_reply.started":"2024-09-19T17:13:40.909232Z","shell.execute_reply":"2024-09-19T17:13:40.912787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"algunas configuraciones relacionadas con el procesamiento de imágenes. ","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:13:40.915498Z","iopub.execute_input":"2024-09-19T17:13:40.915922Z","iopub.status.idle":"2024-09-19T17:13:40.956669Z","shell.execute_reply.started":"2024-09-19T17:13:40.915875Z","shell.execute_reply":"2024-09-19T17:13:40.955791Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:13:40.958845Z","iopub.execute_input":"2024-09-19T17:13:40.959156Z","iopub.status.idle":"2024-09-19T17:13:55.676564Z","shell.execute_reply.started":"2024-09-19T17:13:40.959124Z","shell.execute_reply":"2024-09-19T17:13:55.675653Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"estamos trabajando con archivos ZIP en Python. El código está diseñado para descomprimir los dos primeros archivos ZIP que se encuentran en la ruta especificada (\n/kaggle/input/dogs-vs-cats","metadata":{}},{"cell_type":"markdown","source":"# 4- Data Preprocessing","metadata":{}},{"cell_type":"markdown","source":"> ## Label Encoding","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":{"execution":{"iopub.status.busy":"2024-09-19T17:13:55.677836Z","iopub.execute_input":"2024-09-19T17:13:55.678214Z","iopub.status.idle":"2024-09-19T17:13:55.728497Z","shell.execute_reply.started":"2024-09-19T17:13:55.678178Z","shell.execute_reply":"2024-09-19T17:13:55.727734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"aquí se esta listando las imágenes de un directorio y asignando una categoría a cada imagen basada en su nombre. En la parte de:\n Clasificación: Para cada nombre de imagen, separas el nombre del archivo de su extensión (por ejemplo, 'cat.588.jpg' se convierte en 'cat') y asignas un valor de 0 si es un gato y 1 si es un perro.\n y en la linea de df: creas un DataFrame de pandas que contiene los nombres de las imágenes y sus respectivas categorías.","metadata":{}},{"cell_type":"markdown","source":"> ## Show DataFrame","metadata":{}},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:13:55.730078Z","iopub.execute_input":"2024-09-19T17:13:55.730466Z","iopub.status.idle":"2024-09-19T17:13:55.751004Z","shell.execute_reply.started":"2024-09-19T17:13:55.730423Z","shell.execute_reply":"2024-09-19T17:13:55.750040Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"se utiliza en phyton especificamente con la biblioteca pandas para mostrar las primeras 5 lineas de un dataframe","metadata":{}},{"cell_type":"code","source":"df.tail()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:13:55.752086Z","iopub.execute_input":"2024-09-19T17:13:55.752373Z","iopub.status.idle":"2024-09-19T17:13:55.760919Z","shell.execute_reply.started":"2024-09-19T17:13:55.752331Z","shell.execute_reply":"2024-09-19T17:13:55.760004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.describe()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:13:55.762054Z","iopub.execute_input":"2024-09-19T17:13:55.762423Z","iopub.status.idle":"2024-09-19T17:13:55.786905Z","shell.execute_reply.started":"2024-09-19T17:13:55.762391Z","shell.execute_reply":"2024-09-19T17:13:55.786007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[\"CATEGORIES\"].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:13:55.787922Z","iopub.execute_input":"2024-09-19T17:13:55.788227Z","iopub.status.idle":"2024-09-19T17:13:55.799962Z","shell.execute_reply.started":"2024-09-19T17:13:55.788181Z","shell.execute_reply":"2024-09-19T17:13:55.798806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> ## Visualize The Data","metadata":{}},{"cell_type":"code","source":"df[\"CATEGORIES\"].value_counts().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:13:55.804021Z","iopub.execute_input":"2024-09-19T17:13:55.804330Z","iopub.status.idle":"2024-09-19T17:13:56.059756Z","shell.execute_reply.started":"2024-09-19T17:13:55.804299Z","shell.execute_reply":"2024-09-19T17:13:56.058790Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"este codigo crea un gráfico de barras que muestre la cantidad de ocurrencias de cada categoría en la columna \"CATEGORIES\" cuenta cuántas veces aparece cada categoría y luego lo visualiza en un gráfico de barras.","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:13:56.061024Z","iopub.execute_input":"2024-09-19T17:13:56.061343Z","iopub.status.idle":"2024-09-19T17:14:26.210125Z","shell.execute_reply.started":"2024-09-19T17:13:56.061307Z","shell.execute_reply":"2024-09-19T17:14:26.209261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"esto sirve para analizar las dimensiones del conjunto de datos","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:26.211446Z","iopub.execute_input":"2024-09-19T17:14:26.211833Z","iopub.status.idle":"2024-09-19T17:14:26.496391Z","shell.execute_reply.started":"2024-09-19T17:14:26.211793Z","shell.execute_reply":"2024-09-19T17:14:26.495517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"El código selecciona una imagen aleatoria de un conjunto de imágenes de entrenamiento y la muestra utilizando Matplotlib.","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:26.497540Z","iopub.execute_input":"2024-09-19T17:14:26.497860Z","iopub.status.idle":"2024-09-19T17:14:26.506648Z","shell.execute_reply.started":"2024-09-19T17:14:26.497828Z","shell.execute_reply":"2024-09-19T17:14:26.505533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":" El código está reemplazando los valores en la columna \"CATEGORIES\" de un DataFrame llamado\ndf\n. Específicamente, está cambiando los valores 0 por 'cat' y 1 por 'dog'","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:26.507950Z","iopub.execute_input":"2024-09-19T17:14:26.508315Z","iopub.status.idle":"2024-09-19T17:14:26.523209Z","shell.execute_reply.started":"2024-09-19T17:14:26.508280Z","shell.execute_reply":"2024-09-19T17:14:26.522320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"aquí se esta utilizando la función\ntrain_test_split\npara dividirlo en conjuntos de entrenamiento y validación. En el código, esta separando el 20% de los datos para validación y el 80% restante para entrenamiento. ","metadata":{}},{"cell_type":"markdown","source":"> # Show tarin DataFrame","metadata":{}},{"cell_type":"code","source":"train_df['CATEGORIES'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:14:26.524487Z","iopub.execute_input":"2024-09-19T17:14:26.525120Z","iopub.status.idle":"2024-09-19T17:14:26.535744Z","shell.execute_reply.started":"2024-09-19T17:14:26.525078Z","shell.execute_reply":"2024-09-19T17:14:26.534923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Esto dará una serie con el número de veces que aparece cada categoría, lo que puede ser muy útil para entender la distribución de los datos.","metadata":{}},{"cell_type":"code","source":"train_df['CATEGORIES'].value_counts().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:14:26.536900Z","iopub.execute_input":"2024-09-19T17:14:26.537254Z","iopub.status.idle":"2024-09-19T17:14:26.701898Z","shell.execute_reply.started":"2024-09-19T17:14:26.537224Z","shell.execute_reply":"2024-09-19T17:14:26.701010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> # Show valid DataFrame","metadata":{}},{"cell_type":"code","source":"valid_df['CATEGORIES'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:14:26.703517Z","iopub.execute_input":"2024-09-19T17:14:26.704338Z","iopub.status.idle":"2024-09-19T17:14:26.713393Z","shell.execute_reply.started":"2024-09-19T17:14:26.704294Z","shell.execute_reply":"2024-09-19T17:14:26.712542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"sirve para contar las ocurrencias de diferentes categorías en un DataFrame","metadata":{}},{"cell_type":"code","source":"valid_df['CATEGORIES'].value_counts().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:14:26.714650Z","iopub.execute_input":"2024-09-19T17:14:26.715033Z","iopub.status.idle":"2024-09-19T17:14:26.889518Z","shell.execute_reply.started":"2024-09-19T17:14:26.714993Z","shell.execute_reply":"2024-09-19T17:14:26.888577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:26.890830Z","iopub.execute_input":"2024-09-19T17:14:26.891212Z","iopub.status.idle":"2024-09-19T17:14:26.895954Z","shell.execute_reply.started":"2024-09-19T17:14:26.891167Z","shell.execute_reply":"2024-09-19T17:14:26.894951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"el batch_size\nestá configurado en 15, lo que significa que procesarás 15 muestras a la vez durante el entrenamiento.\n","metadata":{}},{"cell_type":"markdown","source":"> ## Train Generator","metadata":{}},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:14:26.896878Z","iopub.execute_input":"2024-09-19T17:14:26.897168Z","iopub.status.idle":"2024-09-19T17:14:26.911298Z","shell.execute_reply.started":"2024-09-19T17:14:26.897135Z","shell.execute_reply":"2024-09-19T17:14:26.910450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:26.912948Z","iopub.execute_input":"2024-09-19T17:14:26.913253Z","iopub.status.idle":"2024-09-19T17:14:27.160614Z","shell.execute_reply.started":"2024-09-19T17:14:26.913219Z","shell.execute_reply":"2024-09-19T17:14:27.159917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"este codigo crea un objeto\nImageDataGenerator\nque aplica varias transformaciones a las imágenes de entrenamiento, como rotaciones, escalado, corte, zoom y desplazamientos horizontales y verticales. Esto es genial para aumentar la diversidad del conjunto de datos y ayudar al modelo a generalizar mejor.","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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:27.161635Z","iopub.execute_input":"2024-09-19T17:14:27.161922Z","iopub.status.idle":"2024-09-19T17:14:27.230330Z","shell.execute_reply.started":"2024-09-19T17:14:27.161890Z","shell.execute_reply":"2024-09-19T17:14:27.229463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"aqui se esta configurando un generador de datos para tu conjunto de validación que permitirá cargar y preprocesar las imágenes de validación de manera eficiente ","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:27.231464Z","iopub.execute_input":"2024-09-19T17:14:27.231768Z","iopub.status.idle":"2024-09-19T17:14:27.243542Z","shell.execute_reply.started":"2024-09-19T17:14:27.231724Z","shell.execute_reply":"2024-09-19T17:14:27.242538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:27.244583Z","iopub.execute_input":"2024-09-19T17:14:27.244891Z","iopub.status.idle":"2024-09-19T17:14:28.498052Z","shell.execute_reply.started":"2024-09-19T17:14:27.244861Z","shell.execute_reply":"2024-09-19T17:14:28.496979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":" aquí se utiliza Matplotlib para mostrar imágenes en un conjunto de subgráficas.","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:28.499259Z","iopub.execute_input":"2024-09-19T17:14:28.499569Z","iopub.status.idle":"2024-09-19T17:14:29.288150Z","shell.execute_reply.started":"2024-09-19T17:14:28.499534Z","shell.execute_reply":"2024-09-19T17:14:29.287243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Esta arquitectura incluye varias capas convolucionales, capas de normalización por lotes, capas de agrupamiento máximo y capas de abandono, lo que es util para prevenir el sobreajuste y mejorar la generalización del modelo. Además, al final, se utiliza una capa densa con activación softmax, lo que es perfecto para una tarea de clasificación binaria como esta.","metadata":{}},{"cell_type":"markdown","source":"> ## Callbacks","metadata":{}},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ReduceLROnPlateau","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:14:29.289166Z","iopub.execute_input":"2024-09-19T17:14:29.289448Z","iopub.status.idle":"2024-09-19T17:14:29.294359Z","shell.execute_reply.started":"2024-09-19T17:14:29.289417Z","shell.execute_reply":"2024-09-19T17:14:29.293392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:29.295560Z","iopub.execute_input":"2024-09-19T17:14:29.295867Z","iopub.status.idle":"2024-09-19T17:14:29.303803Z","shell.execute_reply.started":"2024-09-19T17:14:29.295836Z","shell.execute_reply":"2024-09-19T17:14:29.302968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:14:29.309141Z","iopub.execute_input":"2024-09-19T17:14:29.309421Z","iopub.status.idle":"2024-09-19T17:14:29.314630Z","shell.execute_reply.started":"2024-09-19T17:14:29.309391Z","shell.execute_reply":"2024-09-19T17:14:29.313717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-09-19T19:20:45.449802Z","iopub.execute_input":"2024-09-19T19:20:45.450469Z","iopub.status.idle":"2024-09-19T19:37:53.866690Z","shell.execute_reply.started":"2024-09-19T19:20:45.450410Z","shell.execute_reply":"2024-09-19T19:37:53.865918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":" este código entrena un modelo para clasificar imágenes de perros y gatos, ajustando el número de épochs según una condición y utilizando generadores de datos para manejar las imágenes.","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":{"execution":{"iopub.status.busy":"2024-09-19T17:31:49.998427Z","iopub.execute_input":"2024-09-19T17:31:49.998763Z","iopub.status.idle":"2024-09-19T17:31:50.417366Z","shell.execute_reply.started":"2024-09-19T17:31:49.998706Z","shell.execute_reply":"2024-09-19T17:31:50.416523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"este código genera dos gráficos que te permiten visualizar cómo ha mejorado la precisión y cómo ha disminuido la pérdida del modelo a lo largo de las épocas de entrenamiento,","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:31:50.418788Z","iopub.execute_input":"2024-09-19T17:31:50.419451Z","iopub.status.idle":"2024-09-19T17:31:50.432633Z","shell.execute_reply.started":"2024-09-19T17:31:50.419407Z","shell.execute_reply":"2024-09-19T17:31:50.431782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"este código prepara una lista de nombres de archivos de imágenes de prueba y cuenta cuántas imágenes hay para su posterior procesamiento. ","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:31:50.433817Z","iopub.execute_input":"2024-09-19T17:31:50.434099Z","iopub.status.idle":"2024-09-19T17:31:50.566561Z","shell.execute_reply.started":"2024-09-19T17:31:50.434068Z","shell.execute_reply":"2024-09-19T17:31:50.565898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"este codigo crea un generador de datos que normaliza las imágenes (escalándolas entre 0 y 1) y las carga desde un DataFrame. ","metadata":{}},{"cell_type":"markdown","source":"> # Predict","metadata":{}},{"cell_type":"code","source":"predictions = model.predict(test_generator)","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:31:50.567439Z","iopub.execute_input":"2024-09-19T17:31:50.567713Z","iopub.status.idle":"2024-09-19T17:32:07.755812Z","shell.execute_reply.started":"2024-09-19T17:31:50.567683Z","shell.execute_reply":"2024-09-19T17:32:07.754982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:32:07.757069Z","iopub.execute_input":"2024-09-19T17:32:07.757385Z","iopub.status.idle":"2024-09-19T17:32:07.763859Z","shell.execute_reply.started":"2024-09-19T17:32:07.757351Z","shell.execute_reply":"2024-09-19T17:32:07.763022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:32:07.764829Z","iopub.execute_input":"2024-09-19T17:32:07.765109Z","iopub.status.idle":"2024-09-19T17:32:07.774412Z","shell.execute_reply.started":"2024-09-19T17:32:07.765062Z","shell.execute_reply":"2024-09-19T17:32:07.773616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:32:07.775389Z","iopub.execute_input":"2024-09-19T17:32:07.775672Z","iopub.status.idle":"2024-09-19T17:32:07.791747Z","shell.execute_reply.started":"2024-09-19T17:32:07.775629Z","shell.execute_reply":"2024-09-19T17:32:07.790704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"este codigo está reemplazando los valores en la columna 'CATEGORIES' del DataFrame\ntest_df\n. Específicamente, está cambiando las categorías 'dog' por 1 y 'cat' por 0.","metadata":{}},{"cell_type":"markdown","source":"# 6- Visualize The Result","metadata":{}},{"cell_type":"code","source":"test_df[\"CATEGORIES\"].value_counts().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:32:07.792830Z","iopub.execute_input":"2024-09-19T17:32:07.793167Z","iopub.status.idle":"2024-09-19T17:32:08.014183Z","shell.execute_reply.started":"2024-09-19T17:32:07.793127Z","shell.execute_reply":"2024-09-19T17:32:08.013312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"crea un gráfico de barras para visualizar la cantidad de categorías en el DataFrame","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:32:08.015877Z","iopub.execute_input":"2024-09-19T17:32:08.016316Z","iopub.status.idle":"2024-09-19T17:32:11.832631Z","shell.execute_reply.started":"2024-09-19T17:32:08.016257Z","shell.execute_reply":"2024-09-19T17:32:11.831260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"El código está diseñado para mostrar las primeras 36 imágenes de un DataFrame llamado\ntest_df\n, donde cada imagen se clasifica como \"gato\" o \"perro\" según la columna","metadata":{}},{"cell_type":"markdown","source":"# 7- Save The Model","metadata":{}},{"cell_type":"code","source":"model.save(\"CNN.h5\")\nmodel.save_weights(\"CNN.weights.h5\")","metadata":{"execution":{"iopub.status.busy":"2024-09-19T17:32:11.834723Z","iopub.execute_input":"2024-09-19T17:32:11.835055Z","iopub.status.idle":"2024-09-19T17:32:11.942470Z","shell.execute_reply.started":"2024-09-19T17:32:11.835022Z","shell.execute_reply":"2024-09-19T17:32:11.941698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"se esta guardando el modelo cnn y sus pesos en archivos","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-09-19T17:32:11.943459Z","iopub.execute_input":"2024-09-19T17:32:11.943740Z","iopub.status.idle":"2024-09-19T17:32:11.986284Z","shell.execute_reply.started":"2024-09-19T17:32:11.943698Z","shell.execute_reply":"2024-09-19T17:32:11.985556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"aqui se crea un nuevo DataFrame llamado submission_df a partir de test_df, Luego, estás extrayendo el ID de los nombres de archivo y asignándolo a una nueva columna llamada id. También está copiando las categorías a una columna llamada label, Finalmente, elimina las columnas originales file_name y CATEGORIES, y guarda el resultado en un archivo CSV llamado \"submission.csv\".\n","metadata":{}}]}