{"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":"2025-01-16T15:43:31.518776Z","iopub.execute_input":"2025-01-16T15:43:31.518985Z","iopub.status.idle":"2025-01-16T15:43:34.568189Z","shell.execute_reply.started":"2025-01-16T15:43:31.518964Z","shell.execute_reply":"2025-01-16T15:43:34.56739Z"}},"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":"2025-01-16T15:43:43.937109Z","iopub.execute_input":"2025-01-16T15:43:43.937431Z","iopub.status.idle":"2025-01-16T15:43:49.619261Z","shell.execute_reply.started":"2025-01-16T15:43:43.937407Z","shell.execute_reply":"2025-01-16T15:43:49.618588Z"}},"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":"2025-01-16T15:43:49.620316Z","iopub.execute_input":"2025-01-16T15:43:49.620629Z","iopub.status.idle":"2025-01-16T15:43:49.713144Z","shell.execute_reply.started":"2025-01-16T15:43:49.620607Z","shell.execute_reply":"2025-01-16T15:43:49.712385Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"output_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# 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.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-16T15:43:49.714676Z","iopub.execute_input":"2025-01-16T15:43:49.714873Z","iopub.status.idle":"2025-01-16T15:53:05.510258Z","shell.execute_reply.started":"2025-01-16T15:43:49.714856Z","shell.execute_reply":"2025-01-16T15:53:05.509306Z"}},"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":"2025-01-16T15:53:05.511577Z","iopub.execute_input":"2025-01-16T15:53:05.511796Z","iopub.status.idle":"2025-01-16T15:53:06.809074Z","shell.execute_reply.started":"2025-01-16T15:53:05.511778Z","shell.execute_reply":"2025-01-16T15:53:06.808387Z"}},"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 == \"resnet50\":\n        model = models.resnet50(pretrained=True)\n        num_features = model.fc.in_features\n        model.fc = nn.Linear(num_features, 2)\n    else:\n        raise ValueError(f\"Unsupported model: {model_name}\")\n    return model\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-16T15:53:06.809871Z","iopub.execute_input":"2025-01-16T15:53:06.810139Z","iopub.status.idle":"2025-01-16T15:53:08.491637Z","shell.execute_reply.started":"2025-01-16T15:53:06.810094Z","shell.execute_reply":"2025-01-16T15:53:08.490969Z"}},"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":"2025-01-16T15:53:08.492358Z","iopub.execute_input":"2025-01-16T15:53:08.492721Z","iopub.status.idle":"2025-01-16T15:53:08.497048Z","shell.execute_reply.started":"2025-01-16T15:53:08.492698Z","shell.execute_reply":"2025-01-16T15:53:08.496434Z"}},"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":"2025-01-16T15:53:08.497995Z","iopub.execute_input":"2025-01-16T15:53:08.498301Z","iopub.status.idle":"2025-01-16T15:53:08.514668Z","shell.execute_reply.started":"2025-01-16T15:53:08.49827Z","shell.execute_reply":"2025-01-16T15:53:08.513896Z"}},"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":"2025-01-16T15:53:08.516759Z","iopub.execute_input":"2025-01-16T15:53:08.516946Z","iopub.status.idle":"2025-01-16T15:53:08.533244Z","shell.execute_reply.started":"2025-01-16T15:53:08.516929Z","shell.execute_reply":"2025-01-16T15:53:08.53257Z"}},"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":"2025-01-16T15:53:08.534145Z","iopub.execute_input":"2025-01-16T15:53:08.534369Z","iopub.status.idle":"2025-01-16T15:53:08.548069Z","shell.execute_reply.started":"2025-01-16T15:53:08.53435Z","shell.execute_reply":"2025-01-16T15:53:08.547447Z"}},"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":"2025-01-16T15:53:08.548775Z","iopub.execute_input":"2025-01-16T15:53:08.549014Z","iopub.status.idle":"2025-01-16T15:53:08.64913Z","shell.execute_reply.started":"2025-01-16T15:53:08.548994Z","shell.execute_reply":"2025-01-16T15:53:08.648425Z"}},"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":"2025-01-16T15:53:08.649947Z","iopub.execute_input":"2025-01-16T15:53:08.650292Z","iopub.status.idle":"2025-01-16T16:40:28.734978Z","shell.execute_reply.started":"2025-01-16T15:53:08.650258Z","shell.execute_reply":"2025-01-16T16:40:28.734199Z"}},"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":"2025-01-16T16:40:28.73596Z","iopub.execute_input":"2025-01-16T16:40:28.736201Z","iopub.status.idle":"2025-01-16T16:40:28.743217Z","shell.execute_reply.started":"2025-01-16T16:40:28.736178Z","shell.execute_reply":"2025-01-16T16:40:28.74237Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"evaluate2(resnet50,validation_loader)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-16T16:40:28.744104Z","iopub.execute_input":"2025-01-16T16:40:28.744447Z","iopub.status.idle":"2025-01-16T16:40:38.519841Z","shell.execute_reply.started":"2025-01-16T16:40:28.744414Z","shell.execute_reply":"2025-01-16T16:40:38.519135Z"}},"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":"2025-01-16T16:40:38.520538Z","iopub.execute_input":"2025-01-16T16:40:38.520747Z","iopub.status.idle":"2025-01-16T16:40:38.529729Z","shell.execute_reply.started":"2025-01-16T16:40:38.520727Z","shell.execute_reply":"2025-01-16T16:40:38.528869Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"evaluate2(resnet50,test_loader)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-16T16:40:38.530553Z","iopub.execute_input":"2025-01-16T16:40:38.53084Z","iopub.status.idle":"2025-01-16T16:41:07.849852Z","shell.execute_reply.started":"2025-01-16T16:40:38.530811Z","shell.execute_reply":"2025-01-16T16:41:07.849166Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"MODEL_SAVE_PATH = \"/kaggle/working/resnet50_trained_model.pth\"\ntorch.save(resnet50.state_dict(), MODEL_SAVE_PATH)\nprint(f\"Model saved to {MODEL_SAVE_PATH}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-16T16:41:07.850666Z","iopub.execute_input":"2025-01-16T16:41:07.85093Z","iopub.status.idle":"2025-01-16T16:41:07.994729Z","shell.execute_reply.started":"2025-01-16T16:41:07.850906Z","shell.execute_reply":"2025-01-16T16:41:07.993991Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport cv2\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader, Dataset, Subset\nfrom torchvision import transforms, models\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.metrics import accuracy_score, classification_report, confusion_matrix\nfrom tqdm import tqdm\nfrom torch.cuda.amp import autocast, GradScaler\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# Paths\ndataset_path = '/kaggle/input/deepfake-detection-challenge'\ntrain_videos_path = os.path.join(dataset_path, 'train_sample_videos')\n\n# Load Metadata\ntrain_sample_metadata = pd.read_json(os.path.join(train_videos_path, 'metadata.json')).T\ntrain_sample_metadata = train_sample_metadata.reset_index().rename(columns={'index': 'filename'})\n\n# Frame Extraction Function\ndef extract_frames(video_path, output_dir, frame_rate=30):\n    os.makedirs(output_dir, exist_ok=True)\n    cap = cv2.VideoCapture(video_path)\n    frame_count, saved_frames = 0, 0\n    while cap.isOpened():\n        ret, frame = cap.read()\n        if not ret:\n            break\n        if frame_count % frame_rate == 0:\n            frame_name = os.path.join(output_dir, f\"{os.path.basename(video_path).split('.')[0]}_frame_{saved_frames}.jpg\")\n            cv2.imwrite(frame_name, frame)\n            saved_frames += 1\n        frame_count += 1\n    cap.release()\n\n# Extract frames\nframe_dir = '/kaggle/working/frames'\nos.makedirs(frame_dir, exist_ok=True)\nfor idx, row in tqdm(train_sample_metadata.iterrows(), total=train_sample_metadata.shape[0]):\n    video_path = os.path.join(train_videos_path, row['filename'])\n    extract_frames(video_path, frame_dir)\n\n# Dataset Class\nclass DeepfakeDataset(Dataset):\n    def __init__(self, data, frame_dir, transform=None):\n        self.data = data\n        self.frame_dir = frame_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.data)\n\n    def __getitem__(self, idx):\n        video_id = self.data.iloc[idx]['filename'].split('.')[0]\n        frame_path = os.path.join(self.frame_dir, f\"{video_id}_frame_0.jpg\")\n        img = cv2.imread(frame_path)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        label = 1 if self.data.iloc[idx]['label'] == 'FAKE' else 0\n        if self.transform:\n            img = self.transform(img)\n        return img, label\n\n# Transforms\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\nfrom torchvision import models\n\ndef create_model(model_name):\n    if model_name == \"resnet18\":\n        model = models.resnet18(pretrained=True)\n        model.fc = nn.Linear(model.fc.in_features, 2)\n    elif model_name == \"resnet152\":\n        model = models.resnet152(pretrained=True)\n        model.fc = nn.Linear(model.fc.in_features, 2)\n    elif model_name == \"densenet121\":\n        model = models.densenet121(pretrained=True)\n        model.classifier = nn.Linear(model.classifier.in_features, 2)\n    elif model_name == \"densenet201\":\n        model = models.densenet201(pretrained=True)\n        model.classifier = nn.Linear(model.classifier.in_features, 2)\n    elif model_name == \"vgg16\":\n        model = models.vgg16(pretrained=True)\n        model.classifier[6] = nn.Linear(model.classifier[6].in_features, 2)\n    elif model_name == \"vgg19\":\n        model = models.vgg19(pretrained=True)\n        model.classifier[6] = nn.Linear(model.classifier[6].in_features, 2)\n    elif model_name == \"mobilenet_v3_large\":\n        model = models.mobilenet_v3_large(pretrained=True)\n        model.classifier[3] = nn.Linear(model.classifier[3].in_features, 2)\n    elif model_name == \"mobilenet_v3_small\":\n        model = models.mobilenet_v3_small(pretrained=True)\n        model.classifier[3] = nn.Linear(model.classifier[3].in_features, 2)\n    elif model_name == \"efficientnet_b7\":\n        model = models.efficientnet_b7(pretrained=True)\n        model.classifier[1] = nn.Linear(model.classifier[1].in_features, 2)\n    elif model_name == \"regnet_y_400mf\":\n        model = models.regnet_y_400mf(pretrained=True)\n        model.head.fc = nn.Linear(model.head.fc.in_features, 2)\n    elif model_name == \"regnet_y_3_2gf\":\n        model = models.regnet_y_3_2gf(pretrained=True)\n        model.head.fc = nn.Linear(model.head.fc.in_features, 2)\n    elif model_name == \"swin_s\":\n        model = models.swin_transformer_s(pretrained=True)\n        model.head = nn.Linear(model.head.in_features, 2)\n    elif model_name == \"swin_l\":\n        model = models.swin_transformer_l(pretrained=True)\n        model.head = nn.Linear(model.head.in_features, 2)\n    elif model_name == \"vision_transformer\":\n        model = models.vision_transformer(pretrained=True)\n        model.head = nn.Linear(model.head.in_features, 2)\n    else:\n        raise ValueError(f\"Model {model_name} is not recognized.\")\n    \n    return model\n\n\n# Training Function with Early Stopping\ndef train_model(model, train_loader, val_loader, criterion, optimizer, device, epochs=100, patience=5):\n    scaler = GradScaler()\n    best_val_acc = 0\n    no_improve_epochs = 0\n    for epoch in range(epochs):\n        model.train()\n        train_loss, correct, total = 0, 0, 0\n        for images, labels in tqdm(train_loader, desc=f\"Epoch {epoch+1}/{epochs}\"):\n            images, labels = images.to(device), labels.to(device)\n            optimizer.zero_grad()\n            with autocast():\n                outputs = model(images)\n                loss = criterion(outputs, labels)\n            scaler.scale(loss).backward()\n            scaler.step(optimizer)\n            scaler.update()\n            train_loss += loss.item()\n            _, predicted = outputs.max(1)\n            correct += (predicted == labels).sum().item()\n            total += labels.size(0)\n        train_acc = correct / total\n        print(f\"Train Loss: {train_loss:.4f}, Train Accuracy: {train_acc:.4f}\")\n\n        # Validation\n        model.eval()\n        val_loss, correct, total = 0, 0, 0\n        with torch.no_grad():\n            for images, labels in val_loader:\n                images, labels = images.to(device), labels.to(device)\n                outputs = model(images)\n                loss = criterion(outputs, labels)\n                val_loss += loss.item()\n                _, predicted = outputs.max(1)\n                correct += (predicted == labels).sum().item()\n                total += labels.size(0)\n        val_acc = correct / total\n        print(f\"Validation Loss: {val_loss:.4f}, Validation Accuracy: {val_acc:.4f}\")\n\n        # Early Stopping\n        if val_acc > best_val_acc:\n            best_val_acc = val_acc\n            no_improve_epochs = 0\n            torch.save(model.state_dict(), '/kaggle/working/best_model.pth')\n        else:\n            no_improve_epochs += 1\n            if no_improve_epochs >= patience:\n                print(\"Early stopping triggered!\")\n                break\n\n# K-Fold Cross-Validation\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nkfold = StratifiedKFold(n_splits=4, shuffle=True, random_state=42)\nresults = []\n\n# List of model names you want to evaluate\nmodel_names = [\n    \"resnet18\", \"resnet152\", \"densenet121\", \"densenet201\", \n    \"vgg16\", \"vgg19\", \"mobilenet_v3_large\", \"mobilenet_v3_small\",\n    \"efficientnet_b7\", \"regnet_y_400mf\", \"regnet_y_3_2gf\", \n    \"swin_s\", \"swin_l\", \"vision_transformer\"\n]\n\n# Perform K-Fold Cross-Validation for each model\nfor model_name in model_names:\n    print(f\"\\nEvaluating model: {model_name}\")\n    fold_accuracies = []  # Store accuracies for each fold\n    for fold, (train_idx, val_idx) in enumerate(kfold.split(train_sample_metadata, train_sample_metadata['label'])):\n        print(f\"Fold {fold+1}\")\n        train_subset = train_sample_metadata.iloc[train_idx]\n        val_subset = train_sample_metadata.iloc[val_idx]\n\n        train_dataset = DeepfakeDataset(train_subset, frame_dir, transform)\n        val_dataset = DeepfakeDataset(val_subset, frame_dir, transform)\n\n        train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\n        val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)\n\n        model = create_model(model_name).to(device)\n        criterion = nn.CrossEntropyLoss()\n        optimizer = optim.Adam(model.parameters(), lr=1e-4)\n\n        train_model(model, train_loader, val_loader, criterion, optimizer, device, epochs=100)\n\n        # Load best model\n        model.load_state_dict(torch.load('/kaggle/working/best_model.pth'))\n        model.eval()\n\n        # Evaluate on validation set\n        y_true, y_pred = [], []\n        with torch.no_grad():\n            for images, labels in val_loader:\n                images, labels = images.to(device), labels.to(device)\n                outputs = model(images)\n                _, predicted = outputs.max(1)\n                y_true.extend(labels.cpu().numpy())\n                y_pred.extend(predicted.cpu().numpy())\n\n        acc = accuracy_score(y_true, y_pred)\n        print(f\"Fold {fold+1} Accuracy: {acc:.4f}\")\n        print(classification_report(y_true, y_pred))\n        cm = confusion_matrix(y_true, y_pred)\n        sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')\n        plt.show()\n        fold_accuracies.append(acc)\n\n    avg_accuracy = sum(fold_accuracies) / len(fold_accuracies)\n    results.append((model_name, avg_accuracy))\n    print(f\"Average Accuracy for {model_name}: {avg_accuracy:.4f}\")\n\n# Print final results for all models\nprint(\"\\nFinal Results across all models:\")\nfor model_name, avg_acc in results:\n    print(f\"{model_name}: {avg_acc:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T13:35:50.893532Z","iopub.execute_input":"2025-01-18T13:35:50.894001Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}