{"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":"none","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30761,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport os              # Permite interactuar con el sistema de archivos.\nimport numpy as np      # Trabaja con arrays y operaciones matemáticas eficientes.\nimport pandas as pd     # Maneja y analiza grandes conjuntos de datos estructurados.\nimport random as rnd    # Genera números aleatorios para simulaciones o muestreo.\nimport matplotlib.pyplot as plt  # Crea gráficos y visualizaciones de datos.\n%matplotlib inline\nfrom sklearn.model_selection import train_test_split\n\nimport keras                          # Biblioteca para construir redes neuronales.\nfrom keras.models import Sequential   # Construye modelos de redes neuronales secuenciales.\nfrom keras.utils import to_categorical  # Convierte etiquetas a formato categórico.\nfrom keras.preprocessing.image import load_img  # Carga imágenes para su procesamiento.\nfrom keras.layers import Flatten, Dense, Dropout  # Define capas de redes neuronales.\nfrom keras.layers import Conv2D, MaxPool2D, BatchNormalization, Activation  # Capas para redes neuronales convolucionales.\n\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator  # Aumenta y prepara imágenes para el entrenamiento.\n\nprint(os.listdir(\"/kaggle/input/dogs-vs-cats\"))  # Muestra los archivos en la carpeta especificada.\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-09-12T14:40:04.002206Z","iopub.execute_input":"2024-09-12T14:40:04.002683Z","iopub.status.idle":"2024-09-12T14:40:04.020193Z","shell.execute_reply.started":"2024-09-12T14:40:04.002640Z","shell.execute_reply":"2024-09-12T14:40:04.018763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FAST_RUN = True  # Opción para entrenar más rápido o más completo (se usa mas tarde).\nIMAGE_WIDTH = 128  # El ancho de cada imagen que vamos a usar.\nIMAGE_HEIGHT = 128  # La altura de cada imagen que vamos a usar.\nIMAGE_CHANNELS = 3  # Indica que las imágenes son a color (3 colores: rojo, verde, azul).\nIMAGE_SIZE = (IMAGE_WIDTH, IMAGE_HEIGHT)  # Establece el tamaño final de las imágenes que usaremos.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:04.022687Z","iopub.execute_input":"2024-09-12T14:40:04.023816Z","iopub.status.idle":"2024-09-12T14:40:04.036791Z","shell.execute_reply.started":"2024-09-12T14:40:04.023758Z","shell.execute_reply":"2024-09-12T14:40:04.035574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import zipfile  # Sirve para abrir y descomprimir archivos comprimidos (.zip)\n\npath = \"/kaggle/input/dogs-vs-cats\"  # Ubicación de los archivos comprimidos.(es un dataset disponible en kaggle)\nfor zip_file in os.listdir(path)[:2]:  # Recorre los primeros 2 archivos en esa ubicación.\n    zipfile.ZipFile(f\"{path}/{zip_file}\", 'r').extractall(\".\")  # Abre y descomprime los archivos.\n#     print(f\"{path}/{zip_file}\")  # (opcional) Muestra la ruta completa de cada archivo.\n    print(f\"{zip_file} unzipped\")  # Muestra que el archivo ha sido descomprimido.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:04.039457Z","iopub.execute_input":"2024-09-12T14:40:04.040592Z","iopub.status.idle":"2024-09-12T14:40:16.285949Z","shell.execute_reply.started":"2024-09-12T14:40:04.040545Z","shell.execute_reply":"2024-09-12T14:40:16.284713Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_images = os.listdir(\"/kaggle/working/train\")  # Lista los nombres de las imágenes en la carpeta \"train\".\nCATEGORIES = []  # Aquí guardaremos las categorías (0 o 1) de cada imagen.\n\nfor image_name in train_images:  # Recorre cada imagen en la carpeta \"train\".\n    class_name = image_name.split('.')[0]  # Toma el nombre antes del punto, por ejemplo: \"cat\" de \"cat.588.jpg\".\n    CATEGORIES.append(0 if class_name == 'cat' else 1)  # Si es \"cat\", asigna 0; si no, asigna 1.\n\ndf = pd.DataFrame({\"train_images\": train_images, \"CATEGORIES\": CATEGORIES})  # Crea una tabla con las imágenes y sus categorías.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:16.287499Z","iopub.execute_input":"2024-09-12T14:40:16.287945Z","iopub.status.idle":"2024-09-12T14:40:16.345969Z","shell.execute_reply.started":"2024-09-12T14:40:16.287904Z","shell.execute_reply":"2024-09-12T14:40:16.344811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head() #nos muestra las primeras filas del dataframe categorizado\ndf.describe()  # Genera un resumen estadístico de los datos numéricos.\ndf[\"CATEGORIES\"].value_counts() #cuenta todos los resultados de cada categoría, tendremos 12500 gatos (0) y 12500 perros (1) en nuestra data\ndf[\"CATEGORIES\"].value_counts().plot.bar() #muestra el gráfico\n# Cambiamos las etiquetas del eje x, así sale cats/dogs en lugar de solo 0 y 1\nplt.xticks([0, 1], ['cats (0)', 'dogs (1)'])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:16.348713Z","iopub.execute_input":"2024-09-12T14:40:16.349105Z","iopub.status.idle":"2024-09-12T14:40:16.539353Z","shell.execute_reply.started":"2024-09-12T14:40:16.349065Z","shell.execute_reply":"2024-09-12T14:40:16.537928Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"shapes = []  # Lista para almacenar las dimensiones de cada imagen.\n\nfor image in df[\"train_images\"]:  # Recorre cada imagen en el DataFrame.\n    path = os.path.join(\"/kaggle/working/train\", image)  # Crea la ruta completa para cada imagen.\n    image_array = plt.imread(path)  # Lee la imagen y la convierte a un formato que el programa pueda entender.\n    shapes.append(image_array.shape)  # Guarda las dimensiones (alto, ancho, canales) de la imagen.\n\n# Muestra cuántas imágenes tienen las mismas dimensiones.\nprint(pd.Series(shapes).value_counts())  \n\n# Encuentra el índice de la imagen con la dimensión más pequeña.\nindex = np.argmin(shapes)  \nprint(f\"\\nThe Minimum Dimension is ==> {shapes[index]}\\n\")  # Muestra las dimensiones más pequeñas encontradas.\nprint(\"*El número 3 al final representa los canales (R,G,B)\")","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:16.540810Z","iopub.execute_input":"2024-09-12T14:40:16.541204Z","iopub.status.idle":"2024-09-12T14:40:53.110064Z","shell.execute_reply.started":"2024-09-12T14:40:16.541163Z","shell.execute_reply":"2024-09-12T14:40:53.108984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\n# Ruta a la carpeta que contiene tus imágenes\nruta_carpeta = \"/kaggle/working/train\"\n\n# Obtener una lista de todos los archivos en la carpeta\nlista_archivos = os.listdir(ruta_carpeta)\n\n# Calcular el número de archivos para el conjunto de entrenamiento\nnum_archivos_entrenamiento = int(0.7 * len(lista_archivos))\n\n# Mezclar aleatoriamente la lista de archivos\nrandom.shuffle(lista_archivos)\n\n# Separar la lista en entrenamiento y validación\ntrain_images = lista_archivos[:num_archivos_entrenamiento]\ntest_images = lista_archivos[num_archivos_entrenamiento:]","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:53.111355Z","iopub.execute_input":"2024-09-12T14:40:53.111700Z","iopub.status.idle":"2024-09-12T14:40:53.166041Z","shell.execute_reply.started":"2024-09-12T14:40:53.111664Z","shell.execute_reply":"2024-09-12T14:40:53.164845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample = rnd.choice(train_images)  # Selecciona una imagen al azar de la lista \"train_images\".\nimage = load_img(os.path.join(\"/kaggle/working/train\", sample))  # Carga la imagen seleccionada desde su ubicación.\nprint(type(image))  # Muestra el tipo de objeto de la imagen (normalmente, será una imagen en formato PIL).\n\nplt.imshow(image)  # Muestra la imagen seleccionada en pantalla.\nplt.axis(\"off\")  # Oculta los ejes de la imagen (no queremos ver números alrededor).\nplt.show()  # Muestra la imagen final sin ejes.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:53.167980Z","iopub.execute_input":"2024-09-12T14:40:53.168496Z","iopub.status.idle":"2024-09-12T14:40:53.441985Z","shell.execute_reply.started":"2024-09-12T14:40:53.168440Z","shell.execute_reply":"2024-09-12T14:40:53.440783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[\"CATEGORIES\"] = df[\"CATEGORIES\"].replace({0: 'cat', 1: 'dog'})  # Reemplaza 0 por \"cat\" y 1 por \"dog\" en la columna CATEGORIES. (igual que hemos hecho antes con el gráfico)","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:53.443296Z","iopub.execute_input":"2024-09-12T14:40:53.443658Z","iopub.status.idle":"2024-09-12T14:40:53.453550Z","shell.execute_reply.started":"2024-09-12T14:40:53.443619Z","shell.execute_reply":"2024-09-12T14:40:53.452357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df, valid_df = train_test_split(df, test_size=0.20, random_state=42) \n# Divide los datos en dos partes: 80% para entrenar y 20% para validar. train_test_split proviene de la librería sklearn.\n\ntrain_df = train_df.reset_index(drop=True)  \n# Resetea los índices del conjunto de entrenamiento, eliminando los números originales.\nvalid_df = valid_df.reset_index(drop=True)  \n# Resetea los índices del conjunto de validación, eliminando los números originales.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:53.457702Z","iopub.execute_input":"2024-09-12T14:40:53.458155Z","iopub.status.idle":"2024-09-12T14:40:53.473983Z","shell.execute_reply.started":"2024-09-12T14:40:53.458092Z","shell.execute_reply":"2024-09-12T14:40:53.472672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['CATEGORIES'].value_counts()\ntrain_df['CATEGORIES'].value_counts().plot.bar()\nvalid_df['CATEGORIES'].value_counts()\nvalid_df['CATEGORIES'].value_counts().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:53.475137Z","iopub.execute_input":"2024-09-12T14:40:53.475521Z","iopub.status.idle":"2024-09-12T14:40:53.743917Z","shell.execute_reply.started":"2024-09-12T14:40:53.475480Z","shell.execute_reply":"2024-09-12T14:40:53.742620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_train = train_df.shape[0]  # Cuenta el número total de imágenes en el conjunto de entrenamiento.\ntotal_validate = valid_df.shape[0]  # Cuenta el número total de imágenes en el conjunto de validación.\nbatch_size = 10  # Define el número de imágenes que procesamos a la vez durante el entrenamiento.\n\nprint(f'TOTAL TRAIN: {total_train}')\nprint(f'TOTAL VALIDATE: {total_validate}')","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:53.745571Z","iopub.execute_input":"2024-09-12T14:40:53.745937Z","iopub.status.idle":"2024-09-12T14:40:53.753181Z","shell.execute_reply.started":"2024-09-12T14:40:53.745897Z","shell.execute_reply":"2024-09-12T14:40:53.751876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:53.754697Z","iopub.execute_input":"2024-09-12T14:40:53.755083Z","iopub.status.idle":"2024-09-12T14:40:53.772490Z","shell.execute_reply.started":"2024-09-12T14:40:53.755045Z","shell.execute_reply":"2024-09-12T14:40:53.771125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(  # Crea un generador que transforma las imágenes de varias maneras.\n    rotation_range=15,  # Gira las imágenes hasta 15 grados al azar.\n    rescale=1./255,  # Normaliza los valores de los píxeles para que estén entre 0 y 1.\n    shear_range=0.1,  # Aplica un efecto de corte o \"cisallamiento\" en las imágenes.\n    zoom_range=0.2,  # Realiza un zoom al azar en las imágenes hasta un 20%.\n    horizontal_flip=True,  # Gira las imágenes horizontalmente (de izquierda a derecha).\n    width_shift_range=0.1,  # Desplaza las imágenes horizontalmente hasta un 10%.\n    height_shift_range=0.1  # Desplaza las imágenes verticalmente hasta un 10%.\n)\n\ntrain_generator = train_datagen.flow_from_dataframe(  # Genera imágenes modificadas a partir del DataFrame.\n    train_df,  # Usa el conjunto de entrenamiento.\n    \"/kaggle/working/train\",  # Ruta donde están almacenadas las imágenes.\n    x_col='train_images',  # Columna que contiene los nombres de las imágenes.\n    y_col='CATEGORIES',  # Columna que contiene las categorías (gato o perro).\n    target_size=IMAGE_SIZE,  # Tamaño al que se redimensionarán las imágenes.\n    class_mode='categorical',  # Las etiquetas de las imágenes estarán en formato categórico (una para gato, otra para perro).\n    batch_size=batch_size  # Número de imágenes procesadas juntas en cada lote.\n)","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:53.774140Z","iopub.execute_input":"2024-09-12T14:40:53.774639Z","iopub.status.idle":"2024-09-12T14:40:54.076594Z","shell.execute_reply.started":"2024-09-12T14:40:53.774587Z","shell.execute_reply":"2024-09-12T14:40:54.075255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_datagen = ImageDataGenerator(rescale=1./255)  \n# Normaliza los valores de los píxeles de las imágenes de validación, convirtiéndolos en un rango de 0 a 1.\n\nvalid_generator = valid_datagen.flow_from_dataframe(  \n    valid_df,  # Utiliza el conjunto de datos de validación.\n    \"/kaggle/working/train\",  # Ruta donde están almacenadas las imágenes.\n    x_col='train_images',  # Columna que contiene los nombres de las imágenes.\n    y_col='CATEGORIES',  # Columna que contiene las categorías (gato o perro).\n    target_size=IMAGE_SIZE,  # Redimensiona las imágenes al tamaño especificado.\n    class_mode='categorical',  # Las etiquetas están en formato categórico (gato/perro).\n    batch_size=batch_size  # Procesa las imágenes en lotes pequeños, de tamaño batch_size.\n)","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:54.077922Z","iopub.execute_input":"2024-09-12T14:40:54.078316Z","iopub.status.idle":"2024-09-12T14:40:54.165223Z","shell.execute_reply.started":"2024-09-12T14:40:54.078249Z","shell.execute_reply":"2024-09-12T14:40:54.163910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"example_df = train_df.sample(n=1)  # Toma una muestra aleatoria de 1 imagen del conjunto de entrenamiento.\nprint(example_df, \"\\n\")  # Muestra la información de esa imagen seleccionada.\n\nexample_df = example_df.reset_index(drop=True)  # Reinicia los índices de la muestra seleccionada para que empiece desde 0.\nprint(example_df, \"\\n\")  # Muestra la información con el nuevo índice.\n\nexample_generator = train_datagen.flow_from_dataframe(\n    example_df,  # Utiliza la muestra de 1 imagen que seleccionamos.\n    \"/kaggle/working/train\",  # Ruta donde están las imágenes.\n    x_col='train_images',  # Columna con los nombres de las imágenes.\n    y_col='CATEGORIES',  # Columna con las categorías (gato o perro).\n    target_size=IMAGE_SIZE,  # Redimensiona la imagen al tamaño deseado.\n    class_mode='categorical'  # Define que las categorías son en formato categórico (gato o perro).\n)","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:54.166743Z","iopub.execute_input":"2024-09-12T14:40:54.167120Z","iopub.status.idle":"2024-09-12T14:40:54.182797Z","shell.execute_reply.started":"2024-09-12T14:40:54.167081Z","shell.execute_reply":"2024-09-12T14:40:54.181539Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(12, 12))  # Crea una figura de tamaño 12x12 para mostrar varias imágenes.\nfor i in range(0, 15):  # Repite el proceso 15 veces para mostrar 15 imágenes.\n    plt.subplot(5, 3, i+1)  # Divide el área de la figura en una cuadrícula de 5 filas y 3 columnas.\n    for X_batch, Y_batch in example_generator:  # Obtiene un lote de imágenes y sus categorías del generador.\n        image = X_batch[0]  # Toma la primera imagen del lote.\n        plt.imshow(image)  # Muestra la imagen.\n        plt.axis('off')  # Oculta los ejes alrededor de la imagen.\n        break  # Sale del bucle después de mostrar la imagen para evitar mostrar el mismo lote varias veces.\nplt.tight_layout()  # Ajusta el diseño para que las imágenes no se superpongan.\nplt.show()  # Muestra la figura con todas las imágenes.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:54.184849Z","iopub.execute_input":"2024-09-12T14:40:54.185603Z","iopub.status.idle":"2024-09-12T14:40:55.642286Z","shell.execute_reply.started":"2024-09-12T14:40:54.185548Z","shell.execute_reply":"2024-09-12T14:40:55.640963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Sequential([  # Creamos un modelo secuencial, donde las capas se apilan una tras otra.\n    Conv2D(32, (3, 3), activation='relu', input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS)),  \n    # Capa convolucional que aplica 32 filtros de tamaño 3x3 a las imágenes. Ayuda a detectar patrones como bordes.\n    \n    MaxPool2D(pool_size=(4,4)),  # Reduce el tamaño de la imagen, manteniendo solo la información importante.\n    Dropout(rate=0.15),  # Apaga aleatoriamente el 25% de las neuronas para evitar sobreajuste.\n\n    Conv2D(64, (3, 3), activation='relu'),  # Segunda capa convolucional con 64 filtros.\n    BatchNormalization(),  # Normaliza los valores de salida para mejorar la estabilidad y acelerar el entrenamiento.\n    MaxPool2D(pool_size=(4,4)),  # Segunda reducción del tamaño de la imagen.\n    Dropout(rate=0.15),  # Apaga el 25% de las neuronas.\n\n    Conv2D(128, (3, 3), activation='relu'),  # Tercera capa convolucional con 128 filtros.\n    BatchNormalization(),  # Normaliza las salidas.\n    MaxPool2D(pool_size=(4,4)),  # Tercera reducción de tamaño de la imagen.\n    Dropout(rate=0.15),  # Apaga el 25% de las neuronas.\nFlatten(),  # Aplana la imagen en un vector para que pueda ser usada en las capas densas.\n\n    Dense(512, activation='relu'),  # Capa densa totalmente conectada con 512 neuronas.\n    Dropout(rate=0.5),  # Apaga el 50% de las neuronas para evitar sobreajuste.\n\n    Dense(2, activation='softmax')  # Capa de salida con 2 neuronas (gato o perro) usando softmax para clasificación.\n])\n\n# Compilación del modelo\nmodel.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])  \n# Configura el modelo con la función de pérdida, el optimizador y la métrica que mediremos (exactitud).\n\n# Resumen del Modelo\nmodel.summary()  # Muestra un resumen de las capas y parámetros del modelo.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:55.643833Z","iopub.execute_input":"2024-09-12T14:40:55.644295Z","iopub.status.idle":"2024-09-12T14:40:55.788621Z","shell.execute_reply.started":"2024-09-12T14:40:55.644211Z","shell.execute_reply":"2024-09-12T14:40:55.787487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ReduceLROnPlateau\nearlystop = EarlyStopping(patience=7)","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:55.789955Z","iopub.execute_input":"2024-09-12T14:40:55.790350Z","iopub.status.idle":"2024-09-12T14:40:55.796150Z","shell.execute_reply.started":"2024-09-12T14:40:55.790305Z","shell.execute_reply":"2024-09-12T14:40:55.794769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc',  # Monitorea la exactitud en los datos de validación.\n                                            patience=5,  # Si no mejora en 2 épocas, reduce la tasa de aprendizaje.\n                                            verbose=1,  # Muestra mensajes sobre el cambio de la tasa de aprendizaje.\n                                            factor=0.25,  # Reduce la tasa de aprendizaje a la mitad.\n                                            min_lr=0.001)  # Define la tasa de aprendizaje mínima.\n\ncallbacks = [earlystop, learning_rate_reduction]  # Lista de funciones especiales que ejecutamos durante el entrenamiento.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:55.797740Z","iopub.execute_input":"2024-09-12T14:40:55.798234Z","iopub.status.idle":"2024-09-12T14:40:55.808376Z","shell.execute_reply.started":"2024-09-12T14:40:55.798194Z","shell.execute_reply":"2024-09-12T14:40:55.807236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 10  # Si FAST_RUN es True, entrenamos por 3 épocas; de lo contrario, 10 épocas.\n\nhistory = model.fit(train_generator,  # Utiliza el conjunto de imágenes de entrenamiento.\n                    epochs=epochs,  # Entrena por 3 o 10 repeticiones, según FAST_RUN.\n                    validation_data=valid_generator,  # Usa el conjunto de validación para evaluar el rendimiento.\n#                     validation_steps=10, # Opcional: número de pasos en validación.\n#                     steps_per_epoch=200,     # Opcional: número de pasos por época.\n                   )  # Usa las funciones especiales (como reducción de tasa de aprendizaje y early stopping).","metadata":{"execution":{"iopub.status.busy":"2024-09-12T14:40:55.809544Z","iopub.execute_input":"2024-09-12T14:40:55.809970Z","iopub.status.idle":"2024-09-12T15:17:11.059817Z","shell.execute_reply.started":"2024-09-12T14:40:55.809914Z","shell.execute_reply":"2024-09-12T15:17:11.058573Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"accuracy = history.history[\"accuracy\"]  # Guarda los valores de precisión del entrenamiento.\nval_accuracy = history.history[\"val_accuracy\"]  # Guarda los valores de precisión en los datos de validación.\n\nloss = history.history[\"loss\"]  # Guarda los valores de pérdida del entrenamiento.\nval_loss = history.history[\"val_loss\"]  # Guarda los valores de pérdida en los datos de validación.\n\nepochs = range(len(accuracy))  # Crea una lista de números de épocas (ciclos de entrenamiento).\n\nplt.figure(figsize=(12,6))  # Crea un gráfico de tamaño 12x6 pulgadas.\n\nplt.subplot(1,2,1)  # Crea el primer gráfico en una cuadrícula de 1 fila y 2 columnas.\nplt.plot(epochs, accuracy, 'bo', label=\"Train_Acc\")  # Grafica la precisión de entrenamiento.\nplt.plot(epochs, val_accuracy, 'r', label=\"val_Acc\")  # Grafica la precisión de validación.\nplt.legend(loc='best', shadow=True)  # Muestra una leyenda explicando qué es cada línea.\n\nplt.subplot(1,2,2)  # Crea el segundo gráfico.\nplt.plot(epochs, loss, 'bo', label=\"Train_Loss\")  # Grafica la pérdida de entrenamiento.\nplt.plot(epochs, val_loss, 'r', label=\"val_Loss\")  # Grafica la pérdida de validación.\nplt.legend(loc='best', shadow=True)  # Muestra una leyenda explicando qué es cada línea.\n\nplt.show()  # Muestra los dos gráficos.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T16:10:44.452596Z","iopub.execute_input":"2024-09-12T16:10:44.453060Z","iopub.status.idle":"2024-09-12T16:10:44.495368Z","shell.execute_reply.started":"2024-09-12T16:10:44.453016Z","shell.execute_reply":"2024-09-12T16:10:44.493599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_file_names = os.listdir(\"/kaggle/working/test1\")  # Lista los nombres de los archivos de prueba en la carpeta \"test1\".\ntest_df = pd.DataFrame({'file_name': test_file_names})  # Crea un DataFrame con los nombres de los archivos de prueba.\n\ntotal_testing = test_df.shape[0]  # Cuenta el número total de archivos de prueba.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T16:10:47.602299Z","iopub.execute_input":"2024-09-12T16:10:47.602742Z","iopub.status.idle":"2024-09-12T16:10:47.636932Z","shell.execute_reply.started":"2024-09-12T16:10:47.602697Z","shell.execute_reply":"2024-09-12T16:10:47.635305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_gen = ImageDataGenerator(rescale=1./255)  # Normaliza los valores de los píxeles de las imágenes de prueba.\n\ntest_generator = test_gen.flow_from_dataframe(\n    test_df,  # Utiliza el DataFrame que contiene los nombres de los archivos de prueba.\n    \"/kaggle/working/test1\",  # Ruta donde están las imágenes de prueba.\n    x_col='file_name',  # Columna que contiene los nombres de las imágenes.\n    y_col=None,  # No tenemos etiquetas (categorías) porque son imágenes para probar.\n    class_mode=None,  # No se necesitan etiquetas ya que solo queremos hacer predicciones.\n    target_size=IMAGE_SIZE,  # Redimensiona las imágenes al tamaño deseado.\n    batch_size=batch_size,  # Procesa las imágenes en lotes pequeños.\n    shuffle=False  # No mezclamos las imágenes para que las predicciones sigan el mismo orden que los nombres.\n)","metadata":{"execution":{"iopub.status.busy":"2024-09-12T16:10:49.433769Z","iopub.execute_input":"2024-09-12T16:10:49.434171Z","iopub.status.idle":"2024-09-12T16:10:49.470406Z","shell.execute_reply.started":"2024-09-12T16:10:49.434133Z","shell.execute_reply":"2024-09-12T16:10:49.468556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = model.predict(test_generator)  # Utiliza el modelo entrenado para hacer predicciones en las imágenes de prueba.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T15:17:11.766074Z","iopub.execute_input":"2024-09-12T15:17:11.766759Z","iopub.status.idle":"2024-09-12T15:17:45.868261Z","shell.execute_reply.started":"2024-09-12T15:17:11.766683Z","shell.execute_reply":"2024-09-12T15:17:45.867102Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df[\"CATEGORIES\"] = np.argmax(predictions, axis=1)  # Asigna la categoría (gato o perro) con la mayor probabilidad a cada imagen.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T15:17:45.869867Z","iopub.execute_input":"2024-09-12T15:17:45.870308Z","iopub.status.idle":"2024-09-12T15:17:45.877784Z","shell.execute_reply.started":"2024-09-12T15:17:45.870241Z","shell.execute_reply":"2024-09-12T15:17:45.876467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_map = dict((v,k) for k,v in train_generator.class_indices.items())  # Crea un diccionario para mapear 0 a \"cat\" y 1 a \"dog\".\ntest_df['CATEGORIES'] = test_df['CATEGORIES'].replace(label_map)  # Reemplaza los valores 0 y 1 en la columna CATEGORIES con \"cat\" o \"dog\".","metadata":{"execution":{"iopub.status.busy":"2024-09-12T15:17:45.879367Z","iopub.execute_input":"2024-09-12T15:17:45.879741Z","iopub.status.idle":"2024-09-12T15:17:45.893668Z","shell.execute_reply.started":"2024-09-12T15:17:45.879695Z","shell.execute_reply":"2024-09-12T15:17:45.892442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df['CATEGORIES'] = test_df['CATEGORIES'].replace({ 'dog': 1, 'cat': 0 })  # Reemplaza las etiquetas de texto \"dog\" por 1 y \"cat\" por 0.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T15:17:45.895074Z","iopub.execute_input":"2024-09-12T15:17:45.895540Z","iopub.status.idle":"2024-09-12T15:17:45.917426Z","shell.execute_reply.started":"2024-09-12T15:17:45.895456Z","shell.execute_reply":"2024-09-12T15:17:45.916288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df[\"CATEGORIES\"].value_counts().plot.bar()  # Cuenta cuántas veces aparece cada categoría y crea un gráfico de barras.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T15:17:45.919055Z","iopub.execute_input":"2024-09-12T15:17:45.919462Z","iopub.status.idle":"2024-09-12T15:17:46.187508Z","shell.execute_reply.started":"2024-09-12T15:17:45.919420Z","shell.execute_reply":"2024-09-12T15:17:46.186283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_test = test_df.head(36)  # Selecciona las primeras 36 imágenes del DataFrame de prueba.\n\nplt.figure(figsize=(15,15))  # Crea una figura de 15x15 pulgadas para mostrar las imágenes.\n\nfor index, row in sample_test.iterrows():  # Recorre cada fila (imagen) en la muestra de prueba.\n    file_name = row['file_name']  # Obtiene el nombre del archivo de la imagen.\n    category = row['CATEGORIES']  # Obtiene la categoría predicha (0 para gato, 1 para perro).\n    path = os.path.join(\"/kaggle/working/test1\", file_name)  # Crea la ruta completa a la imagen.\n    img = load_img(path, target_size=IMAGE_SIZE)  # Carga la imagen y la redimensiona al tamaño especificado.\n    \n    plt.subplot(6, 6, index + 1)  # Crea un área de visualización de 6 filas por 6 columnas.\n    plt.imshow(img)  # Muestra la imagen.\n    plt.title(f\"{file_name}\\n is ==> {'cat' if category==0 else 'dog'}\")  # Establece el título, indicando si es un gato o un perro.\n    plt.axis('off')  # Oculta los ejes para una visualización más limpia.\n\nplt.tight_layout()  # Ajusta el espacio entre las imágenes para evitar que se superpongan.\nplt.show()  # Muestra todas las imágenes en la cuadrícula.","metadata":{"execution":{"iopub.status.busy":"2024-09-12T15:17:46.189237Z","iopub.execute_input":"2024-09-12T15:17:46.189657Z","iopub.status.idle":"2024-09-12T15:17:51.604727Z","shell.execute_reply.started":"2024-09-12T15:17:46.189617Z","shell.execute_reply":"2024-09-12T15:17:51.602807Z"},"trusted":true},"execution_count":null,"outputs":[]}]}