{"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":"gpu","dataSources":[{"sourceId":87323,"databundleVersionId":9934427,"sourceType":"competition"}],"dockerImageVersionId":30823,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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 numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\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\n# import os\n# for 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","trusted":true,"execution":{"iopub.status.busy":"2025-02-17T05:42:00.049096Z","iopub.execute_input":"2025-02-17T05:42:00.049388Z","iopub.status.idle":"2025-02-17T05:42:00.054404Z","shell.execute_reply.started":"2025-02-17T05:42:00.049367Z","shell.execute_reply":"2025-02-17T05:42:00.053462Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 1. Load data","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nimport os\nimport pandas as pd\nimport csv\nfrom sklearn.model_selection import train_test_split\n\n# Define paths\nBASE_FOLDER = '/kaggle/input/cidaut-ai-fake-scene-classification-2024'\nTRAIN_PATH = os.path.join(BASE_FOLDER, \"Train\")  # Use os.path.join for path construction\nLABELS_CSV_FILEPATH = os.path.join(BASE_FOLDER, \"train.csv\")  \n\nNUM_IMAGES = 720\nBATCH_SIZE = 8\nIMAGE_WIDTH, IMAGE_HEIGHT = 224, 224\n\n# Function to load labels\ndef load_labels_from_csv_file():\n    with open(LABELS_CSV_FILEPATH) as f:\n        reader = csv.reader(f, delimiter=',')\n        next(reader)  # Skip the header row\n        image_label_pairs = [(row[0], 1 if row[1] == \"real\" else 0) for row in reader]\n        image_label_pairs = sorted(image_label_pairs, key=lambda t: t[0])\n        labels = [t[1] for t in image_label_pairs]\n        return labels\n\n# Function to create DataFrame\ndef create_df_from_csv_and_folder(csv_filepath, folder_path):\n    with open(csv_filepath) as f:\n        reader = csv.reader(f, delimiter=',')\n        next(reader)\n        image_label_pairs = [(row[0], 1 if row[1] == \"real\" else 0) for row in reader]\n\n    df = pd.DataFrame(image_label_pairs, columns=['image', 'label'])\n    df['image'] = df['image'].astype(str)\n    df['filepath'] = df['image'].apply(lambda img: os.path.join(folder_path, img))\n    return df\n\n# Create and split the DataFrame\ntrain_df = create_df_from_csv_and_folder(LABELS_CSV_FILEPATH, TRAIN_PATH)\ntrain_df, val_df = train_test_split(train_df, test_size=0.1, random_state=100)\n\ndef load_and_preprocess_image(image_path, label, augment=False):\n    img = tf.io.read_file(image_path)\n    img = tf.image.decode_jpeg(img, channels=3)  # Or decode_png\n    img = tf.image.resize(img, [IMAGE_WIDTH, IMAGE_HEIGHT])\n    img = tf.cast(img, tf.float32) / 255.0\n\n    if augment:\n        img = tf.image.random_flip_left_right(img)\n        img = tf.image.random_brightness(img, max_delta=0.2)\n        img = tf.image.random_crop(img, size=[224, 224, 3])\n\n    # Normalize (adjust mean and std if needed)\n    mean = tf.constant([0.485, 0.456, 0.406], dtype=tf.float32)\n    std = tf.constant([0.229, 0.224, 0.225], dtype=tf.float32)\n    img = (img - mean) / std\n\n    return img, label\n\n# Create tf.data.Dataset objects\ntrain_dataset = tf.data.Dataset.from_tensor_slices((train_df['filepath'], train_df['label']))\nval_dataset = tf.data.Dataset.from_tensor_slices((val_df['filepath'], val_df['label']))\n\n\n# Map the load_and_preprocess_image function\ntrain_dataset = train_dataset.map(lambda x, y: load_and_preprocess_image(x, y, augment=True), num_parallel_calls=tf.data.AUTOTUNE)\nval_dataset = val_dataset.map(lambda x, y: load_and_preprocess_image(x, y, augment=False), num_parallel_calls=tf.data.AUTOTUNE)\n\n\n# Batch and shuffle\ntrain_dataset = train_dataset.batch(BATCH_SIZE).shuffle(buffer_size=len(train_df))\nval_dataset = val_dataset.batch(BATCH_SIZE)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-17T05:42:00.055666Z","iopub.execute_input":"2025-02-17T05:42:00.055947Z","iopub.status.idle":"2025-02-17T05:42:00.563682Z","shell.execute_reply.started":"2025-02-17T05:42:00.055924Z","shell.execute_reply":"2025-02-17T05:42:00.562976Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Take the first 10 elements from the train_dataset\ndata_to_plot = train_dataset.take(10)  \n\n# Iterate through the elements and plot images with labels\nfig, axes = plt.subplots(2, 5, figsize=(15, 6))  # 2 rows, 5 columns for 10 images\naxes = axes.flatten()  # Flatten the axes array for easier iteration\n\nfor i, (image_batch, label_batch) in enumerate(data_to_plot):\n    # Iterate through images in the batch\n    for j, image in enumerate(image_batch):\n        # Only plot 10 images\n        if i * BATCH_SIZE + j < 10:\n            axes[i * BATCH_SIZE + j].imshow(image)  # Display individual image\n            axes[i * BATCH_SIZE + j].set_title(f\"Label: {label_batch[j].numpy()}\")  # Display the label as the title\n            axes[i * BATCH_SIZE + j].axis(\"off\")  # Turn off axis ticks\n        else:\n            break  # Exit the inner loop if we've plotted 10 images\n\nplt.tight_layout()  # Adjust spacing between subplots\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-17T05:42:00.565537Z","iopub.execute_input":"2025-02-17T05:42:00.565798Z","iopub.status.idle":"2025-02-17T05:42:03.495452Z","shell.execute_reply.started":"2025-02-17T05:42:00.565777Z","shell.execute_reply":"2025-02-17T05:42:03.494505Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 3. Train model","metadata":{}},{"cell_type":"code","source":" import tensorflow as tf\n from tensorflow.keras.applications import EfficientNetV2L\n from tensorflow.keras.models import Model\n from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout\n from tensorflow.keras.optimizers import Adam\n from tensorflow.keras.regularizers import l2\n\n IMAGE_WIDTH, IMAGE_HEIGHT = 224, 224\n # Load pre-trained EfficientNetV2L\n base_model = EfficientNetV2L(weights='imagenet', include_top=False, input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, 3))\n\n # Add custom classification layers\n x = base_model.output\n x = GlobalAveragePooling2D()(x)\n x = Dropout(0.7)(x)\n x = Dense(2, activation='softmax', kernel_regularizer=l2(0.1))(x)  # 2 classes, softmax activation\n\n # Create final model\n model = Model(inputs=base_model.input, outputs=x)\n\n # Create an Adam optimizer\n optimizer = Adam(learning_rate=1e-4)\n\n#l # Compile the model\n model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n# model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-17T05:42:03.496684Z","iopub.execute_input":"2025-02-17T05:42:03.496925Z","iopub.status.idle":"2025-02-17T05:42:10.111496Z","shell.execute_reply.started":"2025-02-17T05:42:03.496905Z","shell.execute_reply":"2025-02-17T05:42:10.110823Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.losses import SparseCategoricalCrossentropy\nfrom tensorflow.keras.callbacks import LearningRateScheduler\nfrom tensorflow.keras.callbacks import LearningRateScheduler, EarlyStopping \nimport time\n\n\nstart_time = time.time()\n# Define the learning rate (lr)\nlr = 1e-4 \ngamma = 0.9 \n\n\n\n# Define loss, optimizer, and scheduler\nloss_fn = SparseCategoricalCrossentropy()\noptimizer = Adam(learning_rate=lr)\n\n# Define the EarlyStopping callback\nearly_stopping = EarlyStopping(\n    monitor='val_loss',  # Monitor validation loss\n    patience=5,           # Number of epochs with no improvement after which to stop\n    restore_best_weights=True  # Restore the weights of the best epoch\n)\n\ndef scheduler(epoch, lr):\n    return lr * gamma\n\nlr_scheduler = LearningRateScheduler(scheduler)\n\nhistory = model.fit(\n    train_dataset,\n    epochs=50,  # Adjust as needed\n    validation_data=val_dataset,\n    callbacks=[lr_scheduler,early_stopping]  # Include the scheduler\n)\n\nend_time = time.time()\nprint(f\"Training time 16: {end_time - start_time} seconds\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-17T05:42:10.112273Z","iopub.execute_input":"2025-02-17T05:42:10.112487Z","iopub.status.idle":"2025-02-17T05:58:04.738870Z","shell.execute_reply.started":"2025-02-17T05:42:10.112468Z","shell.execute_reply":"2025-02-17T05:58:04.737905Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"loss, accuracy = model.evaluate(val_dataset)\nprint('Validation accuracy:', accuracy)\ntrain_accuracy = history.history['accuracy'][-1]  \nprint(f\"Training accuracy: {train_accuracy}\")\nprint(f\"Validation loss: {loss}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-17T05:58:04.739698Z","iopub.execute_input":"2025-02-17T05:58:04.739961Z","iopub.status.idle":"2025-02-17T05:58:05.412831Z","shell.execute_reply.started":"2025-02-17T05:58:04.739925Z","shell.execute_reply":"2025-02-17T05:58:05.411932Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import seaborn as sns\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom sklearn.metrics import confusion_matrix\n\n# ... (your existing code for loading and preprocessing data, model training, etc.) ...\n\n# Get predictions on the validation dataset\ny_pred_probs = model.predict(val_dataset)  # Get predicted probabilities\ny_pred = np.argmax(y_pred_probs, axis=1)  # Convert probabilities to class labels (0 or 1)\n\n# Get true labels from the validation dataset\ny_true = np.concatenate([y for x, y in val_dataset], axis=0)  # Extract true labels\n\n# Generate confusion matrix\ncm = confusion_matrix(y_true, y_pred)\n\n# Display confusion matrix using seaborn heatmap\nplt.figure(figsize=(8, 6))\nsns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\")\nplt.title(\"Confusion Matrix\")\nplt.xlabel(\"Predicted Label\")\nplt.ylabel(\"True Label\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-17T05:58:05.413652Z","iopub.execute_input":"2025-02-17T05:58:05.413884Z","iopub.status.idle":"2025-02-17T05:58:23.883617Z","shell.execute_reply.started":"2025-02-17T05:58:05.413864Z","shell.execute_reply":"2025-02-17T05:58:23.882527Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array\ntest_image_folder = \"/kaggle/input/cidaut-ai-fake-scene-classification-2024/Test\" \ntest_images = os.listdir(test_image_folder)\n\nsubmission = []\n\n\nfor test_image in test_images:\n    img_path = os.path.join(test_image_folder, test_image)\n    img = load_img(img_path, target_size=(224, 224)) \n    img_array = img_to_array(img) / 255.0           \n    img_array = np.expand_dims(img_array, axis=0)    \n    \n\n    prediction = model.predict(img_array)\n    label = 1 if prediction[0][0] > 0.5 else 0 \n    \n\n    submission.append({\"image\": test_image, \"label\": label})\n\n\nsubmission_df = pd.DataFrame(submission)\n\n# save to CSV\nsubmission_csv_path = \"submission.csv\"\nsubmission_df.to_csv(submission_csv_path, index=False)\n\nprint(f\"Submission file saved to {submission_csv_path}\")\nsubmission_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-17T05:58:23.884494Z","iopub.execute_input":"2025-02-17T05:58:23.885020Z","iopub.status.idle":"2025-02-17T05:58:58.639599Z","shell.execute_reply.started":"2025-02-17T05:58:23.884995Z","shell.execute_reply":"2025-02-17T05:58:58.638661Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}