{"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":10367726,"sourceType":"datasetVersion","datasetId":6421573},{"sourceId":10377254,"sourceType":"datasetVersion","datasetId":6428091},{"sourceId":10377273,"sourceType":"datasetVersion","datasetId":6428106},{"sourceId":10377288,"sourceType":"datasetVersion","datasetId":6428117},{"sourceId":10381877,"sourceType":"datasetVersion","datasetId":6431294}],"dockerImageVersionId":30822,"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 numpy as np\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import roc_auc_score\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications import EfficientNetB0\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout\nfrom tensorflow.keras.optimizers import Adam","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-06T15:59:42.051001Z","iopub.execute_input":"2025-01-06T15:59:42.051494Z","iopub.status.idle":"2025-01-06T15:59:51.532693Z","shell.execute_reply.started":"2025-01-06T15:59:42.051449Z","shell.execute_reply":"2025-01-06T15:59:51.531764Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CustomDataGenerator(tf.keras.utils.Sequence):\n    def __init__(self, image_paths, labels, batch_size=32, img_size=(224, 224), \n                 shuffle=True, augment=False):\n        self.image_paths = image_paths\n        self.labels = labels\n        self.batch_size = batch_size\n        self.img_size = img_size\n        self.shuffle = shuffle\n        self.augment = augment\n        self.n = len(self.image_paths)\n        self.indexes = np.arange(self.n)\n        self.datagen = ImageDataGenerator(\n            rescale=1./255,\n            rotation_range=20,\n            width_shift_range=0.2,\n            height_shift_range=0.2,\n            horizontal_flip=True,\n            fill_mode='nearest'\n        ) if augment else ImageDataGenerator(rescale=1./255)\n        self.on_epoch_end()\n\n    def __len__(self):\n        return int(np.ceil(self.n / self.batch_size))\n\n    def __getitem__(self, idx):\n        indexes = self.indexes[idx * self.batch_size:(idx + 1) * self.batch_size]\n        batch_paths = [self.image_paths[i] for i in indexes]\n        \n        # Initialize batch arrays\n        batch_x = np.zeros((len(indexes), *self.img_size, 3))\n        batch_y = np.array([self.labels[i] for i in indexes])\n        \n        # Load and preprocess images\n        for i, path in enumerate(batch_paths):\n            img = tf.keras.preprocessing.image.load_img(\n                path, target_size=self.img_size\n            )\n            img = tf.keras.preprocessing.image.img_to_array(img)\n            img = self.datagen.standardize(img)\n            batch_x[i] = img\n            \n        return batch_x, batch_y\n\n    def on_epoch_end(self):\n        if self.shuffle:\n            np.random.shuffle(self.indexes)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-06T15:59:51.533926Z","iopub.execute_input":"2025-01-06T15:59:51.534512Z","iopub.status.idle":"2025-01-06T15:59:51.542307Z","shell.execute_reply.started":"2025-01-06T15:59:51.534481Z","shell.execute_reply":"2025-01-06T15:59:51.541450Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def create_model():\n    \"\"\"Create and return the model architecture\"\"\"\n    base_model = EfficientNetB0(\n        weights='imagenet',\n        include_top=False,\n        input_shape=(224, 224, 3)\n    )\n    \n    base_model.trainable = False\n    \n    model = Sequential([\n        base_model,\n        GlobalAveragePooling2D(),\n        Dropout(0.3),\n        Dense(256, activation='relu'),\n        Dropout(0.3),\n        Dense(1, activation='sigmoid')\n    ])\n    \n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-06T15:59:51.543975Z","iopub.execute_input":"2025-01-06T15:59:51.544267Z","iopub.status.idle":"2025-01-06T15:59:51.564788Z","shell.execute_reply.started":"2025-01-06T15:59:51.544246Z","shell.execute_reply":"2025-01-06T15:59:51.563998Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train_model(train_data_path, labels_path, model_save_path='best_model.keras', \n                batch_size=32, epochs=20, validation_split=0.2):\n    \"\"\"Train the model using custom data generator\"\"\"\n    # Read labels\n    df_labels = pd.read_csv(labels_path)\n    print(df_labels.columns)\n    \n    # Create full image paths\n    image_paths = [os.path.join(train_data_path, img) for img in df_labels['image_name']]\n    #labels = df_labels['label'].values\n    labels = df_labels['label'].astype(float).values\n\n    \n    # Split data\n    train_paths, val_paths, train_labels, val_labels = train_test_split(\n        image_paths, labels, test_size=validation_split, random_state=42\n    )\n    \n    # Create data generators\n    train_generator = CustomDataGenerator(\n        train_paths, train_labels, batch_size=batch_size, augment=True\n    )\n    val_generator = CustomDataGenerator(\n        val_paths, val_labels, batch_size=batch_size, augment=False\n    )\n    \n    # Create and compile model\n    model = create_model()\n    model.compile(\n        optimizer=Adam(learning_rate=0.001),\n        loss='binary_crossentropy',\n        metrics=['accuracy']\n    )\n    \n    # Callbacks\n    callbacks = [\n        tf.keras.callbacks.ModelCheckpoint(\n            model_save_path,\n            monitor='val_accuracy',\n            save_best_only=True,\n            mode='max'\n        ),\n        tf.keras.callbacks.EarlyStopping(\n            monitor='val_accuracy',\n            patience=5,\n            restore_best_weights=True\n        )\n    ]\n    \n    # Train the model\n    history = model.fit(\n        train_generator,\n        validation_data=val_generator,\n        epochs=epochs,\n        callbacks=callbacks\n    )\n    \n    return model, history, train_generator, val_generator","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-06T15:59:51.566007Z","iopub.execute_input":"2025-01-06T15:59:51.566262Z","iopub.status.idle":"2025-01-06T15:59:51.583019Z","shell.execute_reply.started":"2025-01-06T15:59:51.566233Z","shell.execute_reply":"2025-01-06T15:59:51.582311Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def fine_tune_model(model, train_generator, val_generator, epochs=10):\n    \"\"\"Fine-tune the model by unfreezing some layers\"\"\"\n    base_model = model.layers[0]\n    base_model.trainable = True\n    \n    for layer in base_model.layers[:-20]:\n        layer.trainable = False\n    \n    model.compile(\n        optimizer=Adam(learning_rate=0.0001),\n        loss='binary_crossentropy',\n        metrics=['accuracy']\n    )\n    \n    history = model.fit(\n        train_generator,\n        epochs=epochs,\n        validation_data=val_generator\n    )\n    \n    return model, history","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-06T15:59:51.583736Z","iopub.execute_input":"2025-01-06T15:59:51.583968Z","iopub.status.idle":"2025-01-06T15:59:51.599778Z","shell.execute_reply.started":"2025-01-06T15:59:51.583949Z","shell.execute_reply":"2025-01-06T15:59:51.599057Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def predict_test_images(model, test_dir, submission_path):\n    \"\"\"Generate predictions for test images\"\"\"\n    test_files = sorted([f for f in os.listdir(test_dir) if f.endswith('.jpg')])\n    test_paths = [os.path.join(test_dir, f) for f in test_files]\n    \n    # Create test generator\n    test_generator = CustomDataGenerator(\n        test_paths,\n        labels=np.zeros(len(test_paths)),  # Dummy labels\n        batch_size=32,\n        shuffle=False,\n        augment=False\n    )\n    \n    # Generate predictions\n    predictions = model.predict(test_generator)\n    \n    # Create submission DataFrame\n    df_submit = pd.DataFrame({\n        'image': test_files,\n        'label': predictions.flatten()\n    })\n    #labels = df_labels['label'].astype(float).values\n\n    \n    # Save submission file\n    df_submit.to_csv(submission_path, index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-06T15:59:51.600601Z","iopub.execute_input":"2025-01-06T15:59:51.600880Z","iopub.status.idle":"2025-01-06T15:59:51.618044Z","shell.execute_reply.started":"2025-01-06T15:59:51.600853Z","shell.execute_reply":"2025-01-06T15:59:51.617245Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\n# Print contents of base input directory\nprint(\"\\nContents of input directory:\")\nprint(os.listdir('../input'))\n\n# Print contents of competition directory (if it exists)\ntry:\n    print(\"\\nContents of competition directory:\")\n    print(os.listdir('../input/cidaut'))\nexcept FileNotFoundError:\n    print(\"\\nCouldn't find the competition directory. Please check the path.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-06T15:59:51.618803Z","iopub.execute_input":"2025-01-06T15:59:51.619065Z","iopub.status.idle":"2025-01-06T15:59:51.638347Z","shell.execute_reply.started":"2025-01-06T15:59:51.619040Z","shell.execute_reply":"2025-01-06T15:59:51.637615Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if __name__ == \"__main__\":\n    # Configuration\n    TRAIN_DIR = \"/kaggle/input/cidaut-ai-fake-scene-classification-2024/Train\"  # Directory containing training images\n    TEST_DIR = \"/kaggle/input/cidaut-ai-fake-scene-classification-2024/Test\"    # Directory containing test images\n    LABELS_PATH = \"/kaggle/input/ttaaaa/train.csv\"  # Path to CSV file with labels\n    BATCH_SIZE = 32\n    INITIAL_EPOCHS = 20\n    FINE_TUNE_EPOCHS = 10\n    #labels = df_labels['label'].astype(float).values\n\n    \n    # Train the model\n    model, history, train_generator, val_generator = train_model(\n        TRAIN_DIR,\n        LABELS_PATH,\n        model_save_path='best_model.keras',\n        batch_size=BATCH_SIZE,\n        epochs=INITIAL_EPOCHS\n    )\n    \n    # Fine-tune the model\n    model, ft_history = fine_tune_model(\n        model,\n        train_generator,\n        val_generator,\n        epochs=FINE_TUNE_EPOCHS\n    )\n    \n    # Generate predictions and submission file\n    predict_test_images(model, TEST_DIR, 'submission.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-06T15:59:51.639857Z","iopub.execute_input":"2025-01-06T15:59:51.640067Z","iopub.status.idle":"2025-01-06T16:02:55.302821Z","shell.execute_reply.started":"2025-01-06T15:59:51.640048Z","shell.execute_reply":"2025-01-06T16:02:55.302127Z"}},"outputs":[],"execution_count":null}]}