{"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":16880,"databundleVersionId":858837,"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\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","trusted":true,"execution":{"iopub.status.busy":"2024-12-29T16:48:03.553038Z","iopub.execute_input":"2024-12-29T16:48:03.554948Z","iopub.status.idle":"2024-12-29T16:48:05.824060Z","shell.execute_reply.started":"2024-12-29T16:48:03.554915Z","shell.execute_reply":"2024-12-29T16:48:05.822981Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport random\nimport shutil\nimport numpy as np\nfrom sklearn.model_selection import train_test_split, KFold\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader, Dataset\nfrom torchvision import transforms, models\nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score,confusion_matrix","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T16:48:05.824892Z","iopub.execute_input":"2024-12-29T16:48:05.825355Z","iopub.status.idle":"2024-12-29T16:48:13.874290Z","shell.execute_reply.started":"2024-12-29T16:48:05.825316Z","shell.execute_reply":"2024-12-29T16:48:13.873618Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dataset_path = '/kaggle/input/deepfake-detection-challenge'\ntrain_videos_path = os.path.join(dataset_path, 'train_sample_videos')\ntest_videos_path = os.path.join(dataset_path, 'test_videos')\n\nprint(f\"train samples: {len(os.listdir(os.path.join(dataset_path, train_videos_path)))}\")\nprint(f\"test samples: {len(os.listdir(os.path.join(dataset_path, test_videos_path)))}\")\n\n\ntrain_sample_metadata = pd.read_json('/kaggle/input/deepfake-detection-challenge/train_sample_videos/metadata.json').T\ntrain_sample_metadata.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T16:48:13.875038Z","iopub.execute_input":"2024-12-29T16:48:13.875494Z","iopub.status.idle":"2024-12-29T16:48:13.977890Z","shell.execute_reply.started":"2024-12-29T16:48:13.875472Z","shell.execute_reply":"2024-12-29T16:48:13.976994Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n\noutput_dir = '/kaggle/working/frames'\nos.makedirs(output_dir, exist_ok=True)\n\nreal_folder = os.path.join(output_dir, 'REAL')\nfake_folder = os.path.join(output_dir, 'Fake')\nos.makedirs(real_folder, exist_ok = True)\nos.makedirs(fake_folder, exist_ok = True)\n\n# Define the dataset path\nVIDEO_DATASET_PATH = \"/kaggle/input/deepfake-detection-challenge/train_sample_videos\"  # Path containing deepfake videos\n\n\n\n\n# Function to extract frames from videos\ndef extract_frames(video_path, output_dir, frame_rate=30):\n    cap = cv2.VideoCapture(video_path)\n    count = 0\n    while cap.isOpened():\n        retrn, frame = cap.read()\n        if not retrn:\n            break\n        if int(cap.get(cv2.CAP_PROP_POS_FRAMES)) % frame_rate == 0:\n            frame_path = os.path.join(output_dir, f\"{os.path.basename(video_path)}_frame_{count}.jpg\")\n            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)\n            cv2.imwrite(frame_path, frame) # saves the frame as an image\n            count += 1\n            # fig = plt.figure(figsize=(4, 4))\n            # ax = fig.add_subplot(111)  \n            # ax.imshow(frame)\n            # plt.show()\n            # count += 1\n            \n    cap.release() # closes the video file, cleans up memory buffer\n\n# Loop through videos and extract frames\nfor video_name, data in train_sample_metadata.iterrows():\n    label = data['label'] # Access the label column\n    video_path = os.path.join(VIDEO_DATASET_PATH, video_name)\n    video_output_dir = real_folder if label == 'REAL' else fake_folder\n\n   \n\n    extract_frames(video_path, video_output_dir)\n\nprint(\"Frame extraction completed.\")\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T16:48:13.979222Z","iopub.execute_input":"2024-12-29T16:48:13.979434Z","iopub.status.idle":"2024-12-29T16:57:44.829902Z","shell.execute_reply.started":"2024-12-29T16:48:13.979416Z","shell.execute_reply":"2024-12-29T16:57:44.829013Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Splitting frames into train, validation, and test sets\ndef split_data(source_dir, train_dir, val_dir, test_dir, train_ratio=0.7, val_ratio=0.1):\n    \"\"\"Split extracted frames into train, validation, and test sets, categorized by REAL and FAKE.\"\"\"\n    for category in [\"REAL\", \"Fake\"]:\n        category_path = os.path.join(source_dir, category)\n        if not os.path.isdir(category_path):\n            continue\n\n        images = [os.path.join(category_path, img) for img in os.listdir(category_path)]\n        train_images, test_images = train_test_split(images, test_size=(1 - train_ratio))\n        train_images, val_images = train_test_split(train_images, test_size=val_ratio / train_ratio)\n\n        # Create output directories\n        for img_set, out_dir in zip([train_images, val_images, test_images], [train_dir, val_dir, test_dir]):\n            category_out_dir = os.path.join(out_dir, category)\n            os.makedirs(category_out_dir, exist_ok=True)\n\n            for img_path in img_set:\n                shutil.copy(img_path, category_out_dir)\n\n# Define directories for splits\nTRAIN_DIR = \"./data/train\"\nVAL_DIR = \"./data/val\"\nTEST_DIR = \"./data/test\"\n\nos.makedirs(TRAIN_DIR, exist_ok=True)\nos.makedirs(VAL_DIR, exist_ok=True)\nos.makedirs(TEST_DIR, exist_ok=True)\n\nFRAME_OUTPUT_PATH = \"/kaggle/working/frames\"\n# Split data\nsplit_data(FRAME_OUTPUT_PATH, TRAIN_DIR, VAL_DIR, TEST_DIR)\n\nprint(\"Data splitting completed.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T16:57:44.833269Z","iopub.execute_input":"2024-12-29T16:57:44.833572Z","iopub.status.idle":"2024-12-29T16:57:46.135376Z","shell.execute_reply.started":"2024-12-29T16:57:44.833542Z","shell.execute_reply":"2024-12-29T16:57:46.134630Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nfrom torch.utils.data import DataLoader, Subset\nfrom sklearn.model_selection import KFold\nfrom torch import nn, optim\nfrom torchvision import models\nfrom torch.cuda.amp import GradScaler, autocast\nimport random\nimport numpy as np\nfrom transformers import ViTForImageClassification\n\n# Define all models for transfer learning\ndef create_model(model_name):\n    if model_name == \"vgg16\":\n        model = models.vgg16(pretrained=True)\n        num_features = model.classifier[-1].in_features\n        model.classifier[-1] = nn.Linear(num_features, 2)\n    elif model_name == \"resnet50\":\n        model = models.resnet50(pretrained=True)\n        num_features = model.fc.in_features\n        model.fc = nn.Linear(num_features, 2)\n    elif model_name == \"densenet121\":\n        model = models.densenet121(pretrained=True)\n        num_features = model.classifier.in_features\n        model.classifier = nn.Linear(num_features, 2)\n    elif model_name == \"mobilenet_v2\":\n        model = models.mobilenet_v2(pretrained=True)\n        num_features = model.last_channel\n        model.classifier[1] = nn.Linear(num_features, 2)\n    elif model_name == \"inception\":\n        model = models.inception_v3(pretrained=True)\n        num_features = model.fc.in_features\n        model.fc = nn.Linear(num_features, 2)\n\n    else:\n        raise ValueError(f\"Unsupported model: {model_name}\")\n    return model\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T16:57:46.136210Z","iopub.execute_input":"2024-12-29T16:57:46.136419Z","iopub.status.idle":"2024-12-29T16:57:49.529903Z","shell.execute_reply.started":"2024-12-29T16:57:46.136401Z","shell.execute_reply":"2024-12-29T16:57:49.529281Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Custom Dataset Class\nclass CustomDataset():\n    def __init__(self, file_paths, labels, transform=None):\n        self.file_paths = file_paths\n        self.labels = labels\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.file_paths)\n\n    def __getitem__(self, idx):\n        image = cv2.imread(self.file_paths[idx])\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        if self.transform:\n            image = self.transform(image)\n        label = self.labels[idx]\n        return image, label\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T16:57:49.530676Z","iopub.execute_input":"2024-12-29T16:57:49.531159Z","iopub.status.idle":"2024-12-29T16:57:49.535853Z","shell.execute_reply.started":"2024-12-29T16:57:49.531135Z","shell.execute_reply":"2024-12-29T16:57:49.535133Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Evaluation Function\ndef evaluate(model, loader):\n    model.eval()\n    all_labels = []\n    all_preds = []\n\n    with torch.no_grad():\n        for images, labels in loader.dataset:\n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            preds = torch.argmax(outputs, dim=1)\n            print(\"Predictions:\", preds.cpu().numpy())\n            print(\"-------------------------------------------------------\")\n            print(\"True Labels:\", labels.cpu().numpy())\n            all_labels.extend(labels.cpu().numpy())\n            all_preds.extend(preds.cpu().numpy())\n\n    accuracy = accuracy_score(all_labels, all_preds)\n    precision = precision_score(all_labels, all_preds, average='macro')\n    recall = recall_score(all_labels, all_preds, average='macro')\n    f1 = f1_score(all_labels, all_preds, average='macro')\n    confusion = confusion_matrix(all_labels,all_preds)\n    print(f\"Accuracy={accuracy}, Precision={precision}, Recall={recall}, F1-Score={f1} \")\n    print(confusion)\n    return accuracy, precision, recall, f1\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T17:17:15.388505Z","iopub.execute_input":"2024-12-29T17:17:15.388787Z","iopub.status.idle":"2024-12-29T17:17:15.394654Z","shell.execute_reply.started":"2024-12-29T17:17:15.388764Z","shell.execute_reply":"2024-12-29T17:17:15.393673Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Evaluation Function\ndef evaluate2(model, loader):\n    model.eval()\n    all_labels = []\n    all_preds = []\n\n    with torch.no_grad():\n        for images, labels in loader:\n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            preds = torch.argmax(outputs, dim=1)\n            print(\"Predictions:\", preds.cpu().numpy())\n            print(\"-------------------------------------------------------\")\n            print(\"True Labels:\", labels.cpu().numpy())\n            all_labels.extend(labels.cpu().numpy())\n            all_preds.extend(preds.cpu().numpy())\n\n    accuracy = accuracy_score(all_labels, all_preds)\n    precision = precision_score(all_labels, all_preds, average='macro')\n    recall = recall_score(all_labels, all_preds, average='macro')\n    f1 = f1_score(all_labels, all_preds, average='macro')\n    confusion = confusion_matrix(all_labels,all_preds)\n    print(f\"Accuracy={accuracy}, Precision={precision}, Recall={recall}, F1-Score={f1} \")\n    print(confusion)\n    return accuracy, precision, recall, f1\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T18:08:39.723845Z","iopub.execute_input":"2024-12-29T18:08:39.724180Z","iopub.status.idle":"2024-12-29T18:08:39.730108Z","shell.execute_reply.started":"2024-12-29T18:08:39.724152Z","shell.execute_reply":"2024-12-29T18:08:39.729318Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# Simulated Annealing for Learning Rate Optimization\ndef simulated_annealing_lr(model, criterion, dataloader, upper_lr=0.001, epochs=5):\n    best_lr = upper_lr\n    best_loss = float('inf')\n    current_lr = random.uniform(1e-5, upper_lr)\n\n    for epoch in range(epochs):\n        optimizer = optim.SGD(model.parameters(), lr=current_lr)\n        model.train()\n        total_loss = 0\n\n        for images, labels in dataloader.dataset:\n            images, labels = images.to(device), labels.to(device)\n            optimizer.zero_grad()\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n            total_loss += loss.item()\n\n        avg_loss = total_loss / len(dataloader)\n        if avg_loss < best_loss:\n            best_loss = avg_loss\n            best_lr = current_lr\n\n        current_lr *= 0.9  # Decrease learning rate\n        print(f\"Iteration {epoch+1} ---------- Best LR = {best_lr} ---------- Loss = {best_loss}\")\n\n    return best_lr\n\n\n# K-Fold Cross-Validation\ndef k_fold_cross_validation(k, model_name, dataset_loader, batch_size=32, epochs=10):\n    kf = KFold(n_splits=k, shuffle=True, random_state=42)\n    fold_metrics = []\n\n    for fold, (train_idx, test_idx) in enumerate(kf.split(dataset_loader.dataset)):\n        print(f\"Starting Fold {fold + 1}\")\n\n        train_subset = torch.utils.data.Subset(dataset_loader, train_idx)\n        test_subset = torch.utils.data.Subset(dataset_loader, test_idx)\n\n       \n\n        model = create_model(model_name)\n        model = model.to(device)\n        criterion = nn.CrossEntropyLoss() \n        \n        best_lr = simulated_annealing_lr(model, criterion, train_subset)\n        optimizer = optim.SGD(model.parameters(), lr=best_lr)\n\n        for epoch in range(epochs):\n            model.train()\n            for images, labels in train_subset.dataset:\n                images, labels = images.to(device), labels.to(device)\n                optimizer.zero_grad()\n                outputs = model(images)\n                loss = criterion(outputs, labels)\n                loss.backward()\n                optimizer.step()\n        metrics = evaluate(model, test_subset)\n        fold_metrics.append(metrics)\n    avg_metrics = np.mean(fold_metrics, axis=0)\n    print(f\"Average Metrics: Accuracy={avg_metrics[0]:.4f}, Precision={avg_metrics[1]:.4f}, Recall={avg_metrics[2]:.4f}, F1-Score={avg_metrics[3]:.4f}\")\n    return model\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T16:57:49.555110Z","iopub.execute_input":"2024-12-29T16:57:49.555314Z","iopub.status.idle":"2024-12-29T16:57:49.578688Z","shell.execute_reply.started":"2024-12-29T16:57:49.555287Z","shell.execute_reply":"2024-12-29T16:57:49.578104Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Device configuration\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# Define transformations\ntransform = transforms.Compose([\n    transforms.ToPILImage(),\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n\n# Prepare dataset\ntrain_files = [os.path.join(TRAIN_DIR, \"REAL\", f) for f in os.listdir(os.path.join(TRAIN_DIR, \"REAL\"))] + \\\n              [os.path.join(TRAIN_DIR, \"Fake\", f) for f in os.listdir(os.path.join(TRAIN_DIR, \"Fake\"))]\ntrain_labels = [0] * len(os.listdir(os.path.join(TRAIN_DIR, \"REAL\"))) + \\\n               [1] * len(os.listdir(os.path.join(TRAIN_DIR, \"Fake\")))\n\ntrain_dataset = CustomDataset(train_files, train_labels, transform=transform)\ntrain_loader = DataLoader(train_dataset , batch_size=32, shuffle=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T16:57:49.580709Z","iopub.execute_input":"2024-12-29T16:57:49.580935Z","iopub.status.idle":"2024-12-29T16:57:49.690429Z","shell.execute_reply.started":"2024-12-29T16:57:49.580916Z","shell.execute_reply":"2024-12-29T16:57:49.689759Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Run k-fold cross-validation\nresnet50 = k_fold_cross_validation(k=3,model_name = \"resnet50\",dataset_loader= train_loader)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T17:17:21.378216Z","iopub.execute_input":"2024-12-29T17:17:21.378509Z","iopub.status.idle":"2024-12-29T18:06:02.419062Z","shell.execute_reply.started":"2024-12-29T17:17:21.378486Z","shell.execute_reply":"2024-12-29T18:06:02.418133Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Prepare dataset\nvalidation_files = [os.path.join(VAL_DIR, \"REAL\", f) for f in os.listdir(os.path.join(VAL_DIR, \"REAL\"))] + \\\n              [os.path.join(VAL_DIR, \"Fake\", f) for f in os.listdir(os.path.join(VAL_DIR, \"Fake\"))]\nvalidation_labels = [0] * len(os.listdir(os.path.join(VAL_DIR, \"REAL\"))) + \\\n               [1] * len(os.listdir(os.path.join(VAL_DIR, \"Fake\")))\n\nvalidation_dataset = CustomDataset(validation_files, validation_labels, transform=transform)\nvalidation_loader = DataLoader(validation_dataset , batch_size=32, shuffle=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T18:06:25.554883Z","iopub.execute_input":"2024-12-29T18:06:25.555219Z","iopub.status.idle":"2024-12-29T18:06:25.561523Z","shell.execute_reply.started":"2024-12-29T18:06:25.555189Z","shell.execute_reply":"2024-12-29T18:06:25.560896Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"evaluate2(resnet50,validation_loader)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T18:08:58.125651Z","iopub.execute_input":"2024-12-29T18:08:58.125925Z","iopub.status.idle":"2024-12-29T18:09:08.109068Z","shell.execute_reply.started":"2024-12-29T18:08:58.125905Z","shell.execute_reply":"2024-12-29T18:09:08.108187Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Prepare dataset\ntest_files = [os.path.join(TEST_DIR, \"REAL\", f) for f in os.listdir(os.path.join(TEST_DIR, \"REAL\"))] + \\\n              [os.path.join(TEST_DIR, \"Fake\", f) for f in os.listdir(os.path.join(TEST_DIR, \"Fake\"))]\ntest_labels = [0] * len(os.listdir(os.path.join(TEST_DIR, \"REAL\"))) + \\\n               [1] * len(os.listdir(os.path.join(TEST_DIR, \"Fake\")))\n\ntest_dataset = CustomDataset(test_files, test_labels, transform=transform)\ntest_loader = DataLoader(test_dataset , batch_size=32, shuffle=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T18:09:25.553540Z","iopub.execute_input":"2024-12-29T18:09:25.553836Z","iopub.status.idle":"2024-12-29T18:09:25.562833Z","shell.execute_reply.started":"2024-12-29T18:09:25.553816Z","shell.execute_reply":"2024-12-29T18:09:25.562042Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"evaluate2(resnet50,test_loader)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T18:09:29.006498Z","iopub.execute_input":"2024-12-29T18:09:29.006807Z","iopub.status.idle":"2024-12-29T18:09:58.701734Z","shell.execute_reply.started":"2024-12-29T18:09:29.006783Z","shell.execute_reply":"2024-12-29T18:09:58.700870Z"}},"outputs":[],"execution_count":null}]}