{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":16880,"databundleVersionId":858837,"sourceType":"competition"},{"sourceId":10217571,"sourceType":"datasetVersion","datasetId":6315886}],"dockerImageVersionId":29845,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"#!python --version","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:20:16.186575Z","iopub.execute_input":"2025-01-12T21:20:16.186862Z","iopub.status.idle":"2025-01-12T21:20:16.191764Z","shell.execute_reply.started":"2025-01-12T21:20:16.186799Z","shell.execute_reply":"2025-01-12T21:20:16.191032Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!conda create -n myenv python=3.8 -y","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:20:16.193685Z","iopub.execute_input":"2025-01-12T21:20:16.193954Z","iopub.status.idle":"2025-01-12T21:20:42.183624Z","shell.execute_reply.started":"2025-01-12T21:20:16.193903Z","shell.execute_reply":"2025-01-12T21:20:42.182530Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#!pip install typing-extensions","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:20:42.185724Z","iopub.execute_input":"2025-01-12T21:20:42.186058Z","iopub.status.idle":"2025-01-12T21:20:42.190010Z","shell.execute_reply.started":"2025-01-12T21:20:42.185993Z","shell.execute_reply":"2025-01-12T21:20:42.189064Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install --upgrade transformers timm\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:20:42.191041Z","iopub.execute_input":"2025-01-12T21:20:42.191263Z","iopub.status.idle":"2025-01-12T21:22:03.226242Z","shell.execute_reply.started":"2025-01-12T21:20:42.191213Z","shell.execute_reply":"2025-01-12T21:22:03.225368Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"try:\n    from typing import Literal\nexcept ImportError:\n    from typing_extensions import Literal\"\"\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:22:03.227806Z","iopub.execute_input":"2025-01-12T21:22:03.228070Z","iopub.status.idle":"2025-01-12T21:22:03.234794Z","shell.execute_reply.started":"2025-01-12T21:22:03.228019Z","shell.execute_reply":"2025-01-12T21:22:03.234090Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install --upgrade transformers\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:22:03.235987Z","iopub.execute_input":"2025-01-12T21:22:03.236167Z","iopub.status.idle":"2025-01-12T21:22:09.253832Z","shell.execute_reply.started":"2025-01-12T21:22:03.236135Z","shell.execute_reply":"2025-01-12T21:22:09.253080Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"try:\n    from transformers import ViTForImageClassification, ViTFeatureExtractor\nexcept ModuleNotFoundError:\n    !pip install transformers\n    from transformers import ViTForImageClassification, ViTFeatureExtractor\nimport random\"\"\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:22:09.255301Z","iopub.execute_input":"2025-01-12T21:22:09.255841Z","iopub.status.idle":"2025-01-12T21:22:09.260213Z","shell.execute_reply.started":"2025-01-12T21:22:09.255784Z","shell.execute_reply":"2025-01-12T21:22:09.259644Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#!pip install --upgrade transformers\n\n# Gerekli kütüphaneleri yükleyelim\nimport torch\nfrom torch import nn, optim\nfrom torch.utils.data import DataLoader, Dataset\nimport os\nimport cv2\nfrom torchvision import transforms\nfrom transformers import ViTForImageClassification, ViTFeatureExtractor\nimport random\nfrom sklearn.metrics import confusion_matrix, accuracy_score, f1_score, roc_auc_score, precision_score, recall_score\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:22:09.261351Z","iopub.execute_input":"2025-01-12T21:22:09.261655Z","iopub.status.idle":"2025-01-12T21:22:18.605767Z","shell.execute_reply.started":"2025-01-12T21:22:09.261597Z","shell.execute_reply":"2025-01-12T21:22:18.605030Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os \n# Metadata ve veri yolları\nmetadata_path = '/kaggle/input/dfdc-48/dfdc_train_part_48/metadata.json'\ninput_dir = '/kaggle/input/dfdc-48/dfdc_train_part_48'\n\n# Ana veri klasörleri\nbase_dir = '/kaggle/working/dataset'\ntrain_dir = os.path.join(base_dir, 'train')\nval_dir = os.path.join(base_dir, 'validation')\ntest_dir = os.path.join(base_dir, 'test')\n\n# Alt klasörler için fonksiyon\ndef create_split_subdirs(split_dir):\n    real_dir = os.path.join(split_dir, 'real')\n    fake_dir = os.path.join(split_dir, 'fake')\n    real_frame_dir = os.path.join(split_dir, 'real_frame')\n    fake_frame_dir = os.path.join(split_dir, 'fake_frame')\n    \n    os.makedirs(real_dir, exist_ok=True)\n    os.makedirs(fake_dir, exist_ok=True)\n    os.makedirs(real_frame_dir, exist_ok=True)\n    os.makedirs(fake_frame_dir, exist_ok=True)\n    \n    return real_dir, fake_dir, real_frame_dir, fake_frame_dir","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:22:18.608988Z","iopub.execute_input":"2025-01-12T21:22:18.609200Z","iopub.status.idle":"2025-01-12T21:22:18.615606Z","shell.execute_reply.started":"2025-01-12T21:22:18.609163Z","shell.execute_reply":"2025-01-12T21:22:18.614924Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Tüm klasörleri oluştur\nfor split_dir in [train_dir, val_dir, test_dir]:\n    os.makedirs(split_dir, exist_ok=True)\n    create_split_subdirs(split_dir)\n\n# Metadata dosyasını yükle\nimport json\nwith open(metadata_path, 'r') as f:\n    metadata = json.load(f)\n\n# Videoların bulunduğu input klasörü\ninput_dir = '/kaggle/input/dfdc-48/dfdc_train_part_48'\n\n# Video Düzeyinde Veri Bölme\nimport random\nfrom sklearn.model_selection import train_test_split","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:22:18.618554Z","iopub.execute_input":"2025-01-12T21:22:18.618849Z","iopub.status.idle":"2025-01-12T21:22:18.659463Z","shell.execute_reply.started":"2025-01-12T21:22:18.618792Z","shell.execute_reply":"2025-01-12T21:22:18.658920Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def split_videos(sample_size=10):\n    with open(metadata_path, 'r') as f:\n        metadata = json.load(f)\n\n    real_videos, fake_videos = [], []\n\n    for video_name, data in metadata.items():\n        video_path = os.path.join(input_dir, video_name)\n        if os.path.exists(video_path):\n            if data['label'] == 'REAL':\n                real_videos.append((video_path, 'real'))\n            elif data['label'] == 'FAKE':\n                fake_videos.append((video_path, 'fake'))\n\n    real_videos = random.sample(real_videos, min(len(real_videos), sample_size))\n    fake_videos = random.sample(fake_videos, min(len(fake_videos), sample_size))\n\n    all_videos = real_videos + fake_videos\n    labels = [1 if v[1] == 'real' else 0 for v in all_videos]\n\n    train_videos, temp_videos, train_labels, temp_labels = train_test_split(\n        all_videos, labels, test_size=0.3, stratify=labels, random_state=42)\n    val_videos, test_videos, val_labels, test_labels = train_test_split(\n        temp_videos, temp_labels, test_size=0.5, stratify=temp_labels, random_state=42)\n    \n    return train_videos, val_videos, test_videos\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:22:18.660789Z","iopub.execute_input":"2025-01-12T21:22:18.661067Z","iopub.status.idle":"2025-01-12T21:22:18.669726Z","shell.execute_reply.started":"2025-01-12T21:22:18.661014Z","shell.execute_reply":"2025-01-12T21:22:18.669069Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Videoları kopyalama fonksiyonu\nimport shutil\ndef copy_videos_to_split_dirs(videos, split_dir):\n    real_dir, fake_dir, _, _ = create_split_subdirs(split_dir)\n    \n    for video_path, label in videos:\n        target_dir = real_dir if label == 'real' else fake_dir\n        video_name = os.path.basename(video_path)\n        shutil.copy(video_path, os.path.join(target_dir, video_name))\n        print(f\"Copied {video_name} to {target_dir}\")\n\ntrain_videos, val_videos, test_videos = split_videos()\ncopy_videos_to_split_dirs(train_videos, train_dir)\ncopy_videos_to_split_dirs(val_videos, val_dir)\ncopy_videos_to_split_dirs(test_videos, test_dir)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:22:18.670853Z","iopub.execute_input":"2025-01-12T21:22:18.671123Z","iopub.status.idle":"2025-01-12T21:22:26.417494Z","shell.execute_reply.started":"2025-01-12T21:22:18.671071Z","shell.execute_reply":"2025-01-12T21:22:26.416835Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Videodan yüzleri çıkarmak ve kare atlama ile çerçeve işleme süresini azaltmak\ndef extract_faces_from_videos(split_dir, frame_skip=10):\n    real_dir, fake_dir, real_frame_dir, fake_frame_dir = create_split_subdirs(split_dir)\n    \n    # Gerçek videolardan frame çıkar\n    for video_name in os.listdir(real_dir):\n        video_path = os.path.join(real_dir, video_name)\n        if os.path.isfile(video_path):\n            extract_faces_from_video(video_path, real_frame_dir, frame_skip)\n    \n    # Sahte videolardan frame çıkar\n    for video_name in os.listdir(fake_dir):\n        video_path = os.path.join(fake_dir, video_name)\n        if os.path.isfile(video_path):\n            extract_faces_from_video(video_path, fake_frame_dir, frame_skip)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:22:26.418775Z","iopub.execute_input":"2025-01-12T21:22:26.419082Z","iopub.status.idle":"2025-01-12T21:22:26.424308Z","shell.execute_reply.started":"2025-01-12T21:22:26.419022Z","shell.execute_reply":"2025-01-12T21:22:26.423632Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"\n!pip install mtcnn\n!pip install facenet-pytorch==2.5.0\n!pip install torch torchvision torchaudio\nfrom facenet_pytorch import MTCNN\n# MTCNN yüz algılama modeli\nmtcnn = MTCNN(device='cuda' if torch.cuda.is_available() else 'cpu')\n\ndef extract_faces_from_video(video_path, output_dir, frame_skip):\n    cap = cv2.VideoCapture(video_path)\n    frame_count = 0\n    \n    while cap.isOpened():\n        ret, frame = cap.read()\n        if not ret:\n            break\n        \n        frame_count += 1\n        if frame_count % frame_skip != 0:\n            continue\n            \n        # Frame'i işle\n        gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n        equalized_frame = cv2.equalizeHist(gray_frame)\n        frame_rgb = cv2.cvtColor(equalized_frame, cv2.COLOR_GRAY2RGB)\n        boxes, _ = mtcnn.detect(frame_rgb)\n        \n        if boxes is not None:\n            for i, box in enumerate(boxes):\n                x1, y1, x2, y2 = map(int, box)\n                face = frame[y1:y2, x1:x2]\n                \n                if face.size == 0:\n                    continue\n                \n                try:\n                    face_resized = cv2.resize(face, (224, 224))\n                    output_path = os.path.join(output_dir, f\"{os.path.basename(video_path)}_frame{frame_count}_face{i}.jpg\")\n                    cv2.imwrite(output_path, face_resized)\n                except cv2.error as e:\n                    print(f\"[Resize Error] Video: {os.path.basename(video_path)}, Frame: {frame_count}, Face: {i}, Error: {e}\")\n                    continue\n    \n    cap.release()\n    print(f\"Processed {os.path.basename(video_path)}\")\"\"\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:22:42.387855Z","iopub.execute_input":"2025-01-12T21:22:42.388242Z","iopub.status.idle":"2025-01-12T21:22:45.503329Z","shell.execute_reply.started":"2025-01-12T21:22:42.388157Z","shell.execute_reply":"2025-01-12T21:22:45.502752Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#OPENCV\n\n# Yüz çıkarma fonksiyonu\ndef extract_faces_from_video(video_path, output_dir, frame_skip=10):\n    import cv2\n    cap = cv2.VideoCapture(video_path)\n    frame_count = 0\n    face_count = 0\n\n    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')\n\n    while cap.isOpened():\n        ret, frame = cap.read()\n        if not ret:\n            break\n\n        frame_count += 1\n        if frame_count % frame_skip != 0:\n            continue\n\n        gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n        faces = face_cascade.detectMultiScale(gray_frame, 1.1, 4)\n\n        for i, (x, y, w, h) in enumerate(faces):\n            face = frame[y:y+h, x:x+w]\n            face_resized = cv2.resize(face, (224, 224))\n            output_path = os.path.join(output_dir, f\"{os.path.basename(video_path)}_frame{frame_count}_face{i}.jpg\")\n            cv2.imwrite(output_path, face_resized)\n            face_count += 1\n    cap.release()\n    print(f\"{video_path}: {face_count} faces extracted.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:24:42.582572Z","iopub.execute_input":"2025-01-12T21:24:42.582902Z","iopub.status.idle":"2025-01-12T21:24:42.590770Z","shell.execute_reply.started":"2025-01-12T21:24:42.582846Z","shell.execute_reply":"2025-01-12T21:24:42.590083Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":" # 3. Her set için frame çıkar\n    print(\"\\nExtracting frames from training set...\")\n    extract_faces_from_videos(train_dir)\n    print(\"\\nExtracting frames from validation set...\")\n    extract_faces_from_videos(val_dir)\n    print(\"\\nExtracting frames from test set...\")\n    extract_faces_from_videos(test_dir)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:25:14.796498Z","iopub.execute_input":"2025-01-12T21:25:14.796774Z","iopub.status.idle":"2025-01-12T21:28:41.150780Z","shell.execute_reply.started":"2025-01-12T21:25:14.796735Z","shell.execute_reply":"2025-01-12T21:28:41.149780Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from PIL import Image\nimport os\n# Görüntüleri normalize etme\ndef normalize_images(input_dir, output_dir, image_size=224):\n    os.makedirs(output_dir, exist_ok=True)\n    \n    for img_name in os.listdir(input_dir):\n        try:\n            img_path = os.path.join(input_dir, img_name)\n            img = Image.open(img_path).convert('RGB')  # Renk formatını RGB'ye dönüştür\n            img = img.resize((image_size, image_size))  # Boyutlandır\n            img.save(os.path.join(output_dir, img_name))  # Normalleştirilmiş görüntüyü kaydet\n        except Exception as e:\n            print(f\"Hata oluştu: {img_name} - {e}\")\n\n\nnormalize_images(train_dir+\"/fake_frame\",\"norm_train_dir/fake\")\nnormalize_images(train_dir+\"/real_frame\",\"norm_train_dir/real\")\nnormalize_images(test_dir+\"/fake_frame\",\"norm_test_dir/fake\")\nnormalize_images(test_dir+\"/real_frame\",\"norm_test_dir/real\")\nnormalize_images(val_dir+\"/fake_frame\",\"norm_val_dir/fake\")\nnormalize_images(val_dir+\"/real_frame\",\"norm_val_dir/real\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:30:29.728848Z","iopub.execute_input":"2025-01-12T21:30:29.729178Z","iopub.status.idle":"2025-01-12T21:30:32.698273Z","shell.execute_reply.started":"2025-01-12T21:30:29.729125Z","shell.execute_reply":"2025-01-12T21:30:32.697638Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Veri Dönüşümleri\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),\n     transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(10),\n    transforms.ColorJitter(brightness=0.2, contrast=0.2),\n    transforms.ToTensor(),\n    transforms.Normalize([0.5], [0.5])\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:30:32.700039Z","iopub.execute_input":"2025-01-12T21:30:32.700362Z","iopub.status.idle":"2025-01-12T21:30:32.710350Z","shell.execute_reply.started":"2025-01-12T21:30:32.700305Z","shell.execute_reply":"2025-01-12T21:30:32.709646Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom PIL import Image\n\nclass FaceDataset(Dataset):\n    def __init__(self, norm_dir, transform=None):\n        self.data = []\n        self.labels = []\n        self.transform = transform\n        \n        real_dir = os.path.join(norm_dir, 'real')\n        fake_dir = os.path.join(norm_dir, 'fake')\n        \n        # Real verileri oku\n        if os.path.exists(real_dir):\n            for img_name in os.listdir(real_dir):\n                img_path = os.path.join(real_dir, img_name)\n                if os.path.isfile(img_path) and img_name.lower().endswith(('.png', '.jpg', '.jpeg')):\n                    self.data.append(img_path)\n                    self.labels.append(0)  \n        \n        # Fake verileri oku\n        if os.path.exists(fake_dir):\n            for img_name in os.listdir(fake_dir):\n                img_path = os.path.join(fake_dir, img_name)\n                if os.path.isfile(img_path) and img_name.lower().endswith(('.png', '.jpg', '.jpeg')):\n                    self.data.append(img_path)\n                    self.labels.append(1)  \n\n        # Veri seti boşsa uyarı ver\n        if len(self.data) == 0:\n            print(f\"Uyarı: {norm_dir} dizininde veri bulunamadı!\")\n\n    def __len__(self):\n        return len(self.data)\n\n    def __getitem__(self, idx):\n        img_path = self.data[idx]\n        label = self.labels[idx]\n        \n        try:\n            img = Image.open(img_path).convert('RGB')\n        except Exception as e:\n            print(f\"Error loading image {img_path}: {str(e)}\")\n            img = Image.new('RGB', (224, 224))\n\n        if self.transform:\n            img = self.transform(img)\n\n        return img, label\n\n# ViT için veri dönüşümleri\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n])\n\n#Dataset'leri tekrar oluştur ve veri kontrolü yap\ntrain_dataset = FaceDataset(\"norm_train_dir\", transform=transform)\ntest_dataset = FaceDataset(\"norm_test_dir\", transform=transform)\nval_dataset = FaceDataset(\"norm_val_dir\", transform=transform)\n\n#Veri kontrolü ekle\nprint(f\"Train veri sayısı: {len(train_dataset)}\")\nprint(f\"Test veri sayısı: {len(test_dataset)}\")\nprint(f\"Validation veri sayısı: {len(val_dataset)}\")\n\n#Eğer veri yoksa hata verecektir\nif len(train_dataset) == 0 or len(test_dataset) == 0 or len(val_dataset) == 0:\n    raise ValueError(\"Veri seti boş. Lütfen veri yollarını kontrol edin.\")\n\n# DataLoader'ları oluştur\ntrain_loader = DataLoader(train_dataset, batch_size=16, shuffle=True, num_workers=2)\ntest_loader = DataLoader(test_dataset, batch_size=16, shuffle=False, num_workers=2)\nval_loader = DataLoader(val_dataset, batch_size=16, shuffle=False, num_workers=2)\n\nprint(\"Veri yükleyiciler başarıyla oluşturuldu.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:30:33.544799Z","iopub.execute_input":"2025-01-12T21:30:33.545062Z","iopub.status.idle":"2025-01-12T21:30:33.573105Z","shell.execute_reply.started":"2025-01-12T21:30:33.545023Z","shell.execute_reply":"2025-01-12T21:30:33.572330Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Model Yükleme ve Eğitimi\nimport timm\nimport torch\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nvit_model = timm.create_model('vit_base_patch16_224', pretrained=True)\nvit_model.head = torch.nn.Sequential(\n    torch.nn.Dropout(0.3),\n    torch.nn.Linear(in_features=768, out_features=2)\n)\nvit_model.to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:30:37.554631Z","iopub.execute_input":"2025-01-12T21:30:37.554889Z","iopub.status.idle":"2025-01-12T21:30:53.967822Z","shell.execute_reply.started":"2025-01-12T21:30:37.554852Z","shell.execute_reply":"2025-01-12T21:30:53.967098Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train_model(model, train_loader, val_loader, criterion, optimizer, num_epochs):\n    \"\"\"\n    Modeli eğitir ve validasyon performansını izler.\n    Args:\n        model: Eğitilecek model\n        train_loader: Eğitim veri yükleyicisi\n        val_loader: Doğrulama veri yükleyicisi\n        criterion: Kayıp fonksiyonu\n        optimizer: Optimizer\n        num_epochs: Epoch sayısı\n    \"\"\"\n    # Metrik takibi için listeler\n    train_losses = []\n    train_accuracies = []\n    val_losses = []\n    val_accuracies = []\n    \n    for epoch in range(num_epochs):\n        # Eğitim Modu\n        model.train()\n        \n        running_loss = 0.0\n        correct_predictions = 0\n        total_samples = 0\n        \n        for images, labels in train_loader:\n            images, labels = images.to(device), labels.to(device)\n            \n            # Sıfırlama\n            optimizer.zero_grad()\n            \n            # Öngörü\n            outputs = model(images)\n            \n            # Kaybı hesapla\n            loss = criterion(outputs, labels)\n            \n            # Geriye yayılım\n            loss.backward()\n            optimizer.step()\n            \n            running_loss += loss.item()\n            \n            # Doğru tahmin sayısını hesapla\n            _, predicted = torch.max(outputs, 1)\n            correct_predictions += (predicted == labels).sum().item()\n            total_samples += labels.size(0)\n        \n        # Eğitim kaybı ve doğruluğu\n        train_loss = running_loss / len(train_loader)\n        train_accuracy = correct_predictions / total_samples\n        \n        # Metrikleri listelere ekle\n        train_losses.append(train_loss)\n        train_accuracies.append(train_accuracy)\n        \n        # Doğrulama Performansı\n        val_loss, val_accuracy = evaluate_model(model, val_loader, criterion)\n        val_losses.append(val_loss)\n        val_accuracies.append(val_accuracy)\n        \n        print(f\"Epoch [{epoch+1}/{num_epochs}] | \"\n              f\"Train Loss: {train_loss:.4f}, Train Accuracy: {train_accuracy:.4f} | \"\n              f\"Validation Loss: {val_loss:.4f}, Validation Accuracy: {val_accuracy:.4f}\")\n    \n    # Eğitim geçmişini döndür\n    history = {\n        'train_loss': train_losses,\n        'train_accuracy': train_accuracies,\n        'val_loss': val_losses,\n        'val_accuracy': val_accuracies\n    }\n    \n    return history\n\ndef evaluate_model(model, loader, criterion):\n    \"\"\"\n    Modeli değerlendirir ve kayıp ile doğruluk değerlerini döndürür.\n    Args:\n        model: Değerlendirilecek model\n        loader: Değerlendirme için veri yükleyicisi\n        criterion: Kayıp fonksiyonu\n    Returns:\n        avg_loss: Ortalama kayıp\n        accuracy: Doğruluk oranı\n    \"\"\"\n    model.eval()\n    correct_predictions = 0\n    total_samples = 0\n    total_loss = 0.0\n\n    with torch.no_grad():\n        for images, labels in loader:\n            images, labels = images.to(device), labels.to(device)\n            \n            # Öngörü\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            total_loss += loss.item()\n            \n            # Doğru tahmin sayısını hesapla\n            _, predicted = torch.max(outputs, 1)\n            correct_predictions += (predicted == labels).sum().item()\n            total_samples += labels.size(0)\n    \n    avg_loss = total_loss / len(loader)\n    accuracy = correct_predictions / total_samples\n    return avg_loss, accuracy","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:30:53.970019Z","iopub.execute_input":"2025-01-12T21:30:53.970342Z","iopub.status.idle":"2025-01-12T21:30:53.982803Z","shell.execute_reply.started":"2025-01-12T21:30:53.970280Z","shell.execute_reply":"2025-01-12T21:30:53.982068Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Test için yardımcı fonksiyon\ndef test_model(model, test_loader, criterion):\n    \"\"\"\n    Modeli test seti üzerinde değerlendirir.\n    Args:\n        model: Test edilecek model\n        test_loader: Test veri yükleyicisi\n        criterion: Kayıp fonksiyonu\n    Returns:\n        test_loss: Test kaybı\n        test_accuracy: Test doğruluğu\n    \"\"\"\n    print(\"\\nTest seti üzerinde değerlendiriliyor...\")\n    test_loss, test_accuracy = evaluate_model(model, test_loader, criterion)\n    print(f\"Test Loss: {test_loss:.4f}, Test Accuracy: {test_accuracy:.4f}\")\n    return test_loss, test_accuracy\n    \ndef evaluate_train_data(model, train_loader):\n    model.eval()  # Modeli eval moduna al\n    correct_predictions = 0\n    total_samples = 0\n    criterion = nn.CrossEntropyLoss()\n    total_loss = 0.0\n\n    with torch.no_grad():\n        for images, labels in train_loader:\n            images, labels = images.to(device), labels.to(device)\n            \n            # Öngörü\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            total_loss += loss.item()\n            \n            # Doğru tahmin sayısını hesapla\n            _, predicted = torch.max(outputs, 1)\n            correct_predictions += (predicted == labels).sum().item()\n            total_samples += labels.size(0)\n    \n    # Ortalama eğitim kaybı ve doğruluğu\n    avg_loss = total_loss / len(train_loader)\n    accuracy = correct_predictions / total_samples\n    print(f\"Train Loss: {avg_loss:.4f}, Train Accuracy: {accuracy:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:30:53.984129Z","iopub.execute_input":"2025-01-12T21:30:53.984359Z","iopub.status.idle":"2025-01-12T21:30:53.997863Z","shell.execute_reply.started":"2025-01-12T21:30:53.984313Z","shell.execute_reply":"2025-01-12T21:30:53.997320Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Modeli kaydet\ndef save_model(model, file_path):\n    torch.save(model.state_dict(), file_path)\n    print(f\"Model {file_path} konumuna kaydedildi.\")\n\n# Modeli yükle\ndef load_model(file_path, model):\n    model.load_state_dict(torch.load(file_path))\n    model = model.to(device)\n    model.eval()\n    print(f\"Model {file_path} konumundan yüklendi.\")\n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:30:53.998818Z","iopub.execute_input":"2025-01-12T21:30:53.999039Z","iopub.status.idle":"2025-01-12T21:30:54.015210Z","shell.execute_reply.started":"2025-01-12T21:30:53.998995Z","shell.execute_reply":"2025-01-12T21:30:54.014574Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Learning Rate Scheduler\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau\n\n# ReduceLROnPlateau kullanımı: validation loss'u izler ve iyileşme olmazsa learning rate'i azaltır\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:30:54.016917Z","iopub.execute_input":"2025-01-12T21:30:54.017154Z","iopub.status.idle":"2025-01-12T21:30:54.025100Z","shell.execute_reply.started":"2025-01-12T21:30:54.017103Z","shell.execute_reply":"2025-01-12T21:30:54.024495Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Early Stopping sınıfı\nclass EarlyStopping:\n    def __init__(self, patience=5, verbose=False):\n        \"\"\"\n        Args:\n            patience (int): İyileşme olmadan beklenebilecek epoch sayısı.\n            verbose (bool): Early stopping ile ilgili mesajları yazdır.\n        \"\"\"\n        self.patience = patience\n        self.verbose = verbose\n        self.best_loss = None\n        self.counter = 0\n        self.early_stop = False\n\n    def __call__(self, val_loss):\n        if self.best_loss is None:\n            self.best_loss = val_loss\n        elif val_loss > self.best_loss:\n            self.counter += 1\n            if self.verbose:\n                print(f\"EarlyStopping counter: {self.counter}/{self.patience}\")\n            if self.counter >= self.patience:\n                self.early_stop = True\n        else:\n            self.best_loss = val_loss\n            self.counter = 0\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:30:54.026312Z","iopub.execute_input":"2025-01-12T21:30:54.026700Z","iopub.status.idle":"2025-01-12T21:30:54.037665Z","shell.execute_reply.started":"2025-01-12T21:30:54.026501Z","shell.execute_reply":"2025-01-12T21:30:54.037027Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%time\n# Optimizasyon ve kayıp fonksiyonu\ncriterion = torch.nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(vit_model.parameters(), lr=5e-5)\nscheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=3, verbose=True)\n\n# Modeli doğru cihaza taşı\nvit_model = vit_model.to(device)\n\n# Early Stopping oluştur\nearly_stopping = EarlyStopping(patience=40, verbose=True)\n\n# Modeli eğit\nhistory = []\n\nnum_epochs = 10\nfor epoch in range(num_epochs):\n    vit_model.train()\n    running_loss = 0.0\n    correct_predictions = 0\n    total_samples = 0\n    \n    for images, labels in train_loader:\n        images, labels = images.to(device), labels.to(device)\n        optimizer.zero_grad()\n        outputs = vit_model(images)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n        _, predicted = outputs.max(1)\n        correct_predictions += predicted.eq(labels).sum().item()\n        total_samples += labels.size(0)\n\n    \"\"\"epoch_loss = running_loss / len(train_loader)\n    epoch_accuracy = 100 * correct / total\n    print(f\"Epoch [{epoch+1}/{num_epochs}], Loss: {epoch_loss:.4f}, Accuracy: {epoch_accuracy:.2f}%\")\"\"\"\n\n    # Eğitim istatistikleri\n    train_loss = running_loss / len(train_loader)\n    train_accuracy = correct_predictions / total_samples\n\n    # Validation performansı\n    val_loss, val_accuracy = evaluate_model(vit_model, val_loader, criterion)\n\n    # Learning rate scheduler\n    scheduler.step(val_loss)\n\n    # Early stopping kontrolü\n    early_stopping(val_loss)\n    if early_stopping.early_stop:\n        print(\"Early stopping triggered\")\n        break\n\n    # Epoch sonuçları\n    history.append({\n        'epoch': epoch + 1,\n        'train_loss': train_loss,\n        'train_accuracy': train_accuracy,\n        'val_loss': val_loss,\n        'val_accuracy': val_accuracy\n    })\n\n    print(f\"Epoch [{epoch+1}/10] | \"\n          f\"Train Loss: {train_loss:.4f}, Train Accuracy: {train_accuracy:.4f} | \"\n          f\"Validation Loss: {val_loss:.4f}, Validation Accuracy: {val_accuracy:.4f}\")\n\nprint(\"Model başarıyla eğitildi!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:30:54.038948Z","iopub.execute_input":"2025-01-12T21:30:54.039195Z","iopub.status.idle":"2025-01-12T21:34:23.011091Z","shell.execute_reply.started":"2025-01-12T21:30:54.039148Z","shell.execute_reply":"2025-01-12T21:34:23.010176Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Modeli test et\n\ntest_loss, test_accuracy = test_model(vit_model, test_loader, criterion)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:23.013298Z","iopub.execute_input":"2025-01-12T21:34:23.013573Z","iopub.status.idle":"2025-01-12T21:34:24.113086Z","shell.execute_reply.started":"2025-01-12T21:34:23.013496Z","shell.execute_reply":"2025-01-12T21:34:24.112274Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Modeli kaydet\nsave_model(vit_model, '/kaggle/working/vit_deepfake.pth')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:24.116233Z","iopub.execute_input":"2025-01-12T21:34:24.116670Z","iopub.status.idle":"2025-01-12T21:34:24.617918Z","shell.execute_reply.started":"2025-01-12T21:34:24.116505Z","shell.execute_reply":"2025-01-12T21:34:24.617081Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Performans Değerlendirme\nvit_model.eval()\ny_true = []\ny_pred = []\nfor images, labels in train_loader:\n    images, labels = images.to(device), labels.to(device)\n    with torch.no_grad():\n        outputs = vit_model(images)\n        _, predicted = outputs.max(1)\n        y_true.extend(labels.cpu().numpy())\n        y_pred.extend(predicted.cpu().numpy())\n\ncm = confusion_matrix(y_true, y_pred)\nsns.heatmap(cm, annot=True, fmt='d')\nplt.title('Confusion Matrix')\nplt.show()\n\nprint(f\"Accuracy: {accuracy_score(y_true, y_pred):.2f}\")\nprint(f\"F1 Score: {f1_score(y_true, y_pred):.2f}\")\nprint(f\"AUC: {roc_auc_score(y_true, y_pred):.2f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:24.619165Z","iopub.execute_input":"2025-01-12T21:34:24.619401Z","iopub.status.idle":"2025-01-12T21:34:31.761434Z","shell.execute_reply.started":"2025-01-12T21:34:24.619362Z","shell.execute_reply":"2025-01-12T21:34:31.760340Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix, classification_report\n\n# Confusion Matrix ve Classification Report 2\ny_true = []\ny_pred = []\n\nvit_model.eval()\nwith torch.no_grad():\n    for images, labels in test_loader:\n        images, labels = images.to(device), labels.to(device)\n        outputs = vit_model(images)\n        _, predicted = torch.max(outputs, 1)\n        \n        y_true.extend(labels.cpu().numpy())\n        y_pred.extend(predicted.cpu().numpy())\n\n# Confusion Matrix\ncm = confusion_matrix(y_true, y_pred)\nprint(\"Confusion Matrix:\\n\", cm)\n\n# Classification Report\ncr = classification_report(y_true, y_pred)\nprint(\"Classification Report:\\n\", cr)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:31.763129Z","iopub.execute_input":"2025-01-12T21:34:31.763540Z","iopub.status.idle":"2025-01-12T21:34:32.867283Z","shell.execute_reply.started":"2025-01-12T21:34:31.763456Z","shell.execute_reply":"2025-01-12T21:34:32.866333Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport cv2\nimport os\nfrom torchvision import transforms\nfrom PIL import Image\nimport numpy as np\n\ndef test_video(video_path, vit_model, transform, device, frame_skip=10):\n    \"\"\"\n    Bir video için deepfake testi yapar. (ViT Modeli İçin)\n    \n    Args:\n        video_path (str): Test edilecek videonun yolu.\n        model (torch.nn.Module): Eğitimli ViT modeli.\n        transform (torchvision.transforms.Compose): Görüntü dönüşümleri.\n        device (torch.device): CUDA veya CPU.\n        frame_skip (int): Kaç karede bir işlem yapılacağı.\n        \n    Returns:\n        str: Video tahmini ('REAL' veya 'FAKE').\n        float: Güven puanı (0 ile 1 arasında).\n    \"\"\"\n    vit_model.eval()  # Modeli değerlendirme moduna al\n    cap = cv2.VideoCapture(video_path)\n    frame_count = 0\n    predictions = []\n\n    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')\n\n    while cap.isOpened():\n        ret, frame = cap.read()\n        if not ret:\n            break  # Video sonu\n        \n        frame_count += 1\n        \n        # Kare atlama kontrolü\n        if frame_count % frame_skip != 0:\n            continue\n\n        # Gri tonlamaya çevir ve yüz tespiti\n        gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n        faces = face_cascade.detectMultiScale(gray_frame, 1.1, 4)\n\n        # Yüz tespit edilirse işlem yap\n        for (x, y, w, h) in faces:\n            face = frame[y:y+h, x:x+w]\n            face_resized = cv2.resize(face, (224, 224))\n            \n            # Görüntüyü PIL'e çevir ve modele uygun formata dönüştür\n            face_pil = Image.fromarray(face_resized).convert('RGB')\n            face_tensor = transform(face_pil).unsqueeze(0).to(device)\n            \n            # ViT modeliyle tahmin yap\n            with torch.no_grad():\n                outputs = vit_model(face_tensor)\n                probabilities = torch.softmax(outputs, dim=1)\n                predicted_class = torch.argmax(probabilities, dim=1).item()\n                predictions.append(predicted_class)\n    \n    cap.release()\n\n    # Yeterli yüz bulunmazsa sonuç belirsiz\n    if len(predictions) == 0:\n        return \"Unknown\", 0.0\n\n    # Sonuçları analiz et\n    real_count = predictions.count(0)\n    fake_count = predictions.count(1)\n    confidence = fake_count / len(predictions)\n    \n    if fake_count > real_count:\n        return \"FAKE\", confidence\n    else:\n        return \"REAL\", 1 - confidence","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:32.868879Z","iopub.execute_input":"2025-01-12T21:34:32.869135Z","iopub.status.idle":"2025-01-12T21:34:32.880439Z","shell.execute_reply.started":"2025-01-12T21:34:32.869081Z","shell.execute_reply":"2025-01-12T21:34:32.879772Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Test videosu\ntest_video_path = '/kaggle/input/dfdc-48/dfdc_train_part_48/eukxkhumll.mp4'\n\n# Test işlemi\nresult, confidence = test_video(test_video_path, vit_model, transform, device)\n\nprint(f\"Tahmin: {result}, Güven Puanı: {confidence:.2f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:32.881728Z","iopub.execute_input":"2025-01-12T21:34:32.882256Z","iopub.status.idle":"2025-01-12T21:34:47.195552Z","shell.execute_reply.started":"2025-01-12T21:34:32.881989Z","shell.execute_reply":"2025-01-12T21:34:47.194664Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Performans verilerinden loss ve accuracy değerlerini ayıklayın\nepochs = [h['epoch'] for h in history]\ntrain_loss = [h['train_loss'] for h in history]\nval_loss = [h['val_loss'] for h in history]\ntrain_accuracy = [h['train_accuracy'] for h in history]\nval_accuracy = [h['val_accuracy'] for h in history]\n\n# Kayıp grafiği (Loss)\nplt.figure(figsize=(10, 5))\nplt.plot(epochs, train_loss, label=\"Eğitim Kaybı\", marker='o')\nplt.plot(epochs, val_loss, label=\"Validasyon Kaybı\", marker='o')\nplt.title(\"Eğitim ve Validasyon Kaybı\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Kayıp\")\nplt.legend()\nplt.grid(True)\nplt.show()\n\n# Doğruluk grafiği (Accuracy)\nplt.figure(figsize=(10, 5))\nplt.plot(epochs, train_accuracy, label=\"Eğitim Doğruluğu\", marker='o')\nplt.plot(epochs, val_accuracy, label=\"Validasyon Doğruluğu\", marker='o')\nplt.title(\"Eğitim ve Validasyon Doğruluğu\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Doğruluk\")\nplt.legend()\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:47.196938Z","iopub.execute_input":"2025-01-12T21:34:47.197244Z","iopub.status.idle":"2025-01-12T21:34:47.765341Z","shell.execute_reply.started":"2025-01-12T21:34:47.197187Z","shell.execute_reply":"2025-01-12T21:34:47.764301Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import roc_auc_score, f1_score\nimport torch\n\ndef calculate_auc_f1(model, data_loader, device):\n    \"\"\"\n    Modelin AUC ve F1 skorunu hesaplar.\n    \n    Args:\n        model: Eğitilmiş model.\n        data_loader: Değerlendirilecek veri yükleyici (train_loader veya val_loader).\n        device: Kullanılan cihaz (CPU veya GPU).\n    \n    Returns:\n        auc_score: AUC değeri.\n        f1: F1 skoru.\n    \"\"\"\n    model.eval()\n    all_labels = []\n    all_preds = []\n\n    with torch.no_grad():\n        for batch in data_loader:\n            if len(batch) == 2:\n                images, labels = batch\n            elif len(batch) == 3:\n                images, labels, _ = batch  # Eğer fazladan veri varsa onu görmezden gel.\n            else:\n                raise ValueError(\"Unexpected number of elements in batch.\")\n                \n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            preds = torch.softmax(outputs, dim=1)[:, 1].cpu().numpy()\n            all_labels.extend(labels.cpu().numpy())\n            all_preds.extend(preds)\n\n    auc = roc_auc_score(all_labels, all_preds)\n    f1 = f1_score(all_labels, [1 if p > 0.5 else 0 for p in all_preds])\n    return auc, f1\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:47.766862Z","iopub.execute_input":"2025-01-12T21:34:47.767230Z","iopub.status.idle":"2025-01-12T21:34:47.785990Z","shell.execute_reply.started":"2025-01-12T21:34:47.767163Z","shell.execute_reply":"2025-01-12T21:34:47.784768Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Eğitim seti üzerinde hesaplama\ntrain_auc, train_f1 = calculate_auc_f1(vit_model, train_loader, device)\nprint(f\"Training AUC: {train_auc:.4f}, Training F1 Score: {train_f1:.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:47.787979Z","iopub.execute_input":"2025-01-12T21:34:47.788361Z","iopub.status.idle":"2025-01-12T21:34:54.543391Z","shell.execute_reply.started":"2025-01-12T21:34:47.788297Z","shell.execute_reply":"2025-01-12T21:34:54.542648Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Validation seti üzerinde hesaplama\nval_auc, val_f1 = calculate_auc_f1(vit_model, val_loader, device)\nprint(f\"Validation AUC: {val_auc:.4f}, Validation F1 Score: {val_f1:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:54.544796Z","iopub.execute_input":"2025-01-12T21:34:54.545008Z","iopub.status.idle":"2025-01-12T21:34:56.392870Z","shell.execute_reply.started":"2025-01-12T21:34:54.544968Z","shell.execute_reply":"2025-01-12T21:34:56.392087Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Test seti üzerinde hesaplama\ntest_auc, test_f1 = calculate_auc_f1(vit_model, test_loader, device)\nprint(f\"Test AUC: {test_auc:.4f}, Test F1 Score: {test_f1:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-12T21:34:56.394451Z","iopub.execute_input":"2025-01-12T21:34:56.394732Z","iopub.status.idle":"2025-01-12T21:34:57.478591Z","shell.execute_reply.started":"2025-01-12T21:34:56.394678Z","shell.execute_reply":"2025-01-12T21:34:57.477664Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}