{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":87323,"databundleVersionId":9934427,"sourceType":"competition"},{"sourceId":10483128,"sourceType":"datasetVersion","datasetId":6490712}],"dockerImageVersionId":30840,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nimport tensorflow as tf\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\n\n# Ruta de las imágenes y archivo CSV\ntrain_dir = \"/kaggle/input/cidaut-ai-fake-scene-classification-2024/Train\"\ncsv_file = \"/kaggle/input/1data-refinado/data_refinado.csv\"\n\n# Leer el archivo CSV\ndata = pd.read_csv(csv_file)\n\n# Agregar ruta completa de las imágenes\ndata['image_path'] = data['image'].apply(lambda x: os.path.join(train_dir, x))\n\n# Dividir datos en entrenamiento y validación\ntrain_data, val_data = train_test_split(data, test_size=0.2, random_state=42)\n\n# Parámetros del modelo\nIMG_SIZE = (224, 224)\nBATCH_SIZE = 32\nEPOCHS = 10\n\n# Función para preprocesar imágenes\ndef preprocess_image(image_path, label):\n    img = tf.io.read_file(image_path)\n    img = tf.image.decode_jpeg(img, channels=3)\n    img = tf.image.resize(img, IMG_SIZE)\n    img = img / 255.0  # Normalizar entre 0 y 1\n    return img, label\n\n# Crear datasets de TensorFlow\ntrain_dataset = tf.data.Dataset.from_tensor_slices((train_data['image_path'].values, train_data['label'].values))\ntrain_dataset = train_dataset.map(preprocess_image).batch(BATCH_SIZE).shuffle(100)\n\nval_dataset = tf.data.Dataset.from_tensor_slices((val_data['image_path'].values, val_data['label'].values))\nval_dataset = val_dataset.map(preprocess_image).batch(BATCH_SIZE)\n\n# Visualización de datos\ndef visualize_batch(dataset):\n    for images, labels in dataset.take(1):  # Tomar un batch\n        plt.figure(figsize=(10, 10))\n        for i in range(9):  # Mostrar 9 imágenes\n            ax = plt.subplot(3, 3, i + 1)\n            plt.imshow(images[i].numpy())\n            plt.title(f\"Etiqueta: {labels[i].numpy()}\")\n            plt.axis(\"off\")\n        plt.show()\n\nvisualize_batch(train_dataset)\n\n# Construcción del modelo\ndef create_model():\n    base_model = tf.keras.applications.MobileNetV2(input_shape=(224, 224, 3), include_top=False, weights='imagenet')\n    base_model.trainable = False  # Congelar capas preentrenadas\n\n    model = tf.keras.Sequential([\n        base_model,\n        tf.keras.layers.GlobalAveragePooling2D(),\n        tf.keras.layers.Dense(128, activation='relu'),\n        tf.keras.layers.Dropout(0.3),\n        tf.keras.layers.Dense(1, activation='sigmoid')  # Clasificación binaria\n    ])\n    return model\n\nmodel = create_model()\n\n# Compilación del modelo\nmodel.compile(optimizer=tf.keras.optimizers.Adam(),\n              loss='binary_crossentropy',\n              metrics=['accuracy', tf.keras.metrics.AUC(name=\"auc\")])\n\n# Entrenamiento del modelo\nhistory = model.fit(train_dataset, validation_data=val_dataset, epochs=EPOCHS)\n\n# Guardar el modelo entrenado\nmodel.save(\"scene_classifier_model.h5\")\n\n# Evaluar el modelo en el conjunto de validación\nval_loss, val_accuracy, val_auc = model.evaluate(val_dataset)\nprint(f\"Loss: {val_loss}, Accuracy: {val_accuracy}, AUC: {val_auc}\")\n\n# Visualización de la curva de entrenamiento\ndef plot_training(history):\n    acc = history.history['accuracy']\n    val_acc = history.history['val_accuracy']\n    loss = history.history['loss']\n    val_loss = history.history['val_loss']\n    \n    plt.figure(figsize=(12, 4))\n    plt.subplot(1, 2, 1)\n    plt.plot(acc, label='Entrenamiento')\n    plt.plot(val_acc, label='Validación')\n    plt.title('Precisión')\n    plt.legend()\n    \n    plt.subplot(1, 2, 2)\n    plt.plot(loss, label='Entrenamiento')\n    plt.plot(val_loss, label='Validación')\n    plt.title('Pérdida')\n    plt.legend()\n    plt.show()\n\nplot_training(history)\n\n# Preparar conjunto de prueba (sin etiquetas)\ntest_images = [os.path.join(\"Test\", img) for img in os.listdir(\"Test\")]\ntest_dataset = tf.data.Dataset.from_tensor_slices(test_images)\ntest_dataset = test_dataset.map(lambda x: preprocess_image(x, 0)).batch(BATCH_SIZE)\n\n# Generar predicciones\npredictions = model.predict(test_dataset)\n\n# Crear archivo de salida para predicciones\nsample_submission = pd.DataFrame({\n    \"image\": [os.path.basename(img) for img in test_images],\n    \"label\": predictions.flatten()\n})\nsample_submission.to_csv(\"submission.csv\", index=False)\n\nprint(\"Predicciones guardadas en 'submission.csv'.\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-01-16T04:53:51.704754Z","iopub.status.idle":"2025-01-16T04:53:51.705002Z","shell.execute_reply":"2025-01-16T04:53:51.704901Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport tensorflow as tf\nfrom tensorflow.keras.applications import EfficientNetB4\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout, BatchNormalization\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\nfrom sklearn.model_selection import StratifiedKFold\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau\nfrom tensorflow.keras.regularizers import l2\nfrom tensorflow.keras.applications.efficientnet import preprocess_input\nfrom sklearn.utils.class_weight import compute_class_weight\nimport numpy as np\n\n# Ruta de las imágenes y archivo CSV\ntrain_dir = \"/kaggle/input/cidaut-ai-fake-scene-classification-2024/Train\"\ncsv_file = \"/kaggle/input/1data-refinado/data_refinado.csv\"\n\n# Leer datos y preparar paths\ndata = pd.read_csv(csv_file)\ndata['label'] = data['label'].astype(int)\ndata['image_path'] = data['image'].apply(lambda x: os.path.join(train_dir, x))\n\n# Configuraciones globales\nIMG_SIZE = (720, 1280)\nnum_gpus = tf.config.experimental.list_physical_devices('GPU')\nBATCH_SIZE = 4 * len(num_gpus)  # Asegura que sea múltiplo de GPUs disponibles\nEPOCHS = 20\nFINE_TUNE_EPOCHS = 10\nAUGMENTATION_PROB = 0.7\n\ndef preprocess_and_augment(image_path, label):\n    img = tf.io.read_file(image_path)\n    img = tf.image.decode_jpeg(img, channels=3)\n    img = tf.image.resize(img, IMG_SIZE)\n    img = preprocess_input(img)\n\n    if tf.random.uniform(()) < AUGMENTATION_PROB:\n        img = tf.image.random_flip_left_right(img)\n        img = tf.image.random_flip_up_down(img)\n        img = tf.image.adjust_brightness(img, delta=0.2)\n        img = tf.image.adjust_contrast(img, contrast_factor=1.5)\n    return img, label\n\ndef preprocess_image(image_path, label):\n    img = tf.io.read_file(image_path)\n    img = tf.image.decode_jpeg(img, channels=3)\n    img = tf.image.resize(img, IMG_SIZE)\n    img = preprocess_input(img)\n    return img, label\n\ndef create_datasets(train_data, val_data):\n    train_dataset = tf.data.Dataset.from_tensor_slices((train_data['image_path'].values, train_data['label'].values))\n    train_dataset = (train_dataset\n                     .map(preprocess_and_augment, num_parallel_calls=tf.data.AUTOTUNE)\n                     .shuffle(500)\n                     .batch(BATCH_SIZE)\n                     .prefetch(tf.data.AUTOTUNE))\n\n    val_dataset = tf.data.Dataset.from_tensor_slices((val_data['image_path'].values, val_data['label'].values))\n    val_dataset = (val_dataset\n                   .map(preprocess_image, num_parallel_calls=tf.data.AUTOTUNE)\n                   .batch(BATCH_SIZE)\n                   .prefetch(tf.data.AUTOTUNE))\n    return train_dataset, val_dataset\n\ndef create_model():\n    base_model = EfficientNetB4(weights='imagenet', include_top=False, input_shape=(IMG_SIZE[0], IMG_SIZE[1], 3))\n    base_model.trainable = False\n\n    inputs = tf.keras.Input(shape=(IMG_SIZE[0], IMG_SIZE[1], 3))\n    x = base_model(inputs, training=False)\n    x = GlobalAveragePooling2D()(x)\n    x = BatchNormalization()(x)\n    x = Dense(512, activation='relu', kernel_regularizer=l2(0.01))(x)\n    x = Dropout(0.5)(x)\n    outputs = Dense(1, activation='sigmoid')(x)\n\n    model = Model(inputs, outputs)\n    model.compile(optimizer=Adam(learning_rate=0.001),\n                  loss=tf.keras.losses.BinaryFocalCrossentropy(),\n                  metrics=['accuracy', tf.keras.metrics.AUC(name='auc'),\n                           tf.keras.metrics.Precision(name='precision'),\n                           tf.keras.metrics.Recall(name='recall')])\n    return model, base_model\n\ndef fine_tune_model(model, base_model):\n    base_model.trainable = True\n    for layer in base_model.layers[:150]:\n        layer.trainable = False\n\n    model.compile(optimizer=Adam(learning_rate=1e-5),\n                  loss=tf.keras.losses.BinaryFocalCrossentropy(),\n                  metrics=['accuracy', tf.keras.metrics.AUC(name='auc'),\n                           tf.keras.metrics.Precision(name='precision'),\n                           tf.keras.metrics.Recall(name='recall')])\n    return model\n\nkf = StratifiedKFold(n_splits=3, shuffle=True, random_state=42)\nfold_results = []\n\nfor fold, (train_idx, val_idx) in enumerate(kf.split(data['image_path'], data['label'])):\n    train_data = data.iloc[train_idx]\n    val_data = data.iloc[val_idx]\n\n    train_dataset, val_dataset = create_datasets(train_data, val_data)\n\n    class_weights = compute_class_weight('balanced', classes=np.unique(train_data['label']), y=train_data['label'])\n    class_weights = {i: class_weights[i] for i in range(len(class_weights))}\n\n    strategy = tf.distribute.MirroredStrategy()\n    with strategy.scope():\n        model, base_model = create_model()\n\n        callbacks = [\n            EarlyStopping(monitor='precision', patience=3, restore_best_weights=True),\n            ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=2, min_lr=1e-6),\n            ModelCheckpoint(f'best_model_fold_{fold + 1}.keras', monitor='val_auc', save_best_only=True, mode='max')\n        ]\n\n        model.fit(train_dataset, validation_data=val_dataset, epochs=EPOCHS,\n                  callbacks=callbacks, class_weight=class_weights)\n\n        model = fine_tune_model(model, base_model)\n        model.fit(train_dataset, validation_data=val_dataset, epochs=FINE_TUNE_EPOCHS,\n                  callbacks=callbacks, class_weight=class_weights)\n\n    val_loss, val_accuracy, val_auc, val_precision, val_recall = model.evaluate(val_dataset)\n    fold_results.append((val_loss, val_accuracy, val_auc, val_precision, val_recall))\n\n    del train_dataset, val_dataset\n    tf.keras.backend.clear_session()\n\navg_results = np.mean(fold_results, axis=0)\nprint(f\"Promedio de resultados: Loss: {avg_results[0]:.4f}, Accuracy: {avg_results[1]:.4f}, AUC: {avg_results[2]:.4f}, \"\n      f\"Precision: {avg_results[3]:.4f}, Recall: {avg_results[4]:.4f}\")\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T04:12:28.079871Z","iopub.execute_input":"2025-01-17T04:12:28.080253Z","execution_failed":"2025-01-17T04:33:54.959Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom tensorflow.keras.models import load_model\n\n# Ruta del modelo y carpeta de test\nmodel_path = '/kaggle/working/best_model_fold_1.keras'\ntest_dir = \"/kaggle/input/cidaut-ai-fake-scene-classification-2024/Train\"\ncsv_path = \"/kaggle/input/1data-refinado/data_refinado.csv\"\n\n\n# Cargar el modelo entrenado\nmodel = load_model(model_path, compile=False)  # No compilar para evitar errores de versiones de TensorFlow\n\n# Leer el archivo CSV y crear un diccionario de etiquetas\ndf = pd.read_csv(csv_path)\nlabels_dict = dict(zip(df['image'], df['label']))\n\n# Configuración del tamaño de imagen\nIMG_SIZE = (720, 1280)  # Tamaño recomendado para EfficientNetB4\n\n# Función para preprocesar la imagen\ndef preprocess_image(image_path):\n    img = tf.io.read_file(image_path)\n    img = tf.image.decode_jpeg(img, channels=3)\n    img = tf.image.resize(img, IMG_SIZE)\n    img = tf.keras.applications.efficientnet.preprocess_input(img)\n    return tf.expand_dims(img, axis=0)  # Añadir la dimensión del batch\n\n# Función para mostrar la clasificación de la imagen\ndef show_classification(image_path, predicted_class, real_label):\n    img = plt.imread(image_path)\n    plt.imshow(img)\n    pred_label = 'Real' if predicted_class == 1 else 'Falsa'\n    real_label_text = 'Real' if real_label == 1 else 'Falsa'\n    plt.title(f\"Predicción: {pred_label} (Esperado: {real_label_text})\")\n    plt.axis('off')\n    plt.show()\n\n# Contadores para predicciones correctas e incorrectas\ncorrect_predictions = 0\nincorrect_predictions = 0\n\n# Iterar sobre las imágenes en la carpeta de test\nfor image_name in os.listdir(test_dir):\n    image_path = os.path.join(test_dir, image_name)\n\n    # Preprocesar la imagen\n    img = preprocess_image(image_path)\n    \n    # Realizar la predicción\n    prediction = model.predict(img)\n    predicted_class = int(prediction[0][0] > 0.5)  # Clasificación binaria\n    \n    # Obtener la etiqueta real desde el diccionario\n    real_label = labels_dict.get(image_name, 0)  # Si no se encuentra, asumimos 0 (Falsa)\n    \n    # Evaluar la predicción\n    if predicted_class == real_label:\n        correct_predictions += 1\n        print(f\"{image_name} - Correcta (Esperado: {real_label}, Predicción: {predicted_class})\")\n    else:\n        incorrect_predictions += 1\n        print(f\"{image_name} - Incorrecta (Esperado: {real_label}, Predicción: {predicted_class})\")\n    \n    # Mostrar la imagen con su predicción (opcional, comenta si no deseas visualizar)\n    # show_classification(image_path, predicted_class, real_label)\n\n# Resumen de las predicciones\ntotal_images = correct_predictions + incorrect_predictions\nprint(f\"\\nTotal de imágenes evaluadas: {total_images}\")\nprint(f\"Correctamente clasificadas: {correct_predictions}\")\nprint(f\"Incorrectamente clasificadas: {incorrect_predictions}\")\naccuracy = (correct_predictions / total_images) * 100\nprint(f\"Precisión total: {accuracy:.2f}%\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T04:08:29.774172Z","iopub.execute_input":"2025-01-17T04:08:29.774492Z","iopub.status.idle":"2025-01-17T04:08:29.795653Z","shell.execute_reply.started":"2025-01-17T04:08:29.77447Z","shell.execute_reply":"2025-01-17T04:08:29.794461Z"}},"outputs":[],"execution_count":null}]}