{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":104308,"databundleVersionId":12660285,"sourceType":"competition"},{"sourceId":430984,"sourceType":"modelInstanceVersion","isSourceIdPinned":false,"modelInstanceId":351318,"modelId":372567},{"sourceId":443805,"sourceType":"modelInstanceVersion","isSourceIdPinned":false,"modelInstanceId":360333,"modelId":381469}],"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\n#import numpy as np # linear algebra\n#import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n#import os\n#for dirname, _, filenames in os.walk('/kaggle/input'):\n#    for filename in filenames:\n#        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip install ultralytics tqdm pillow","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport csv\nimport torch\nimport timm\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision.transforms as transforms\nfrom PIL import Image\nfrom ultralytics import YOLO\nfrom tqdm import tqdm\nfrom timm.data.constants import \\\n    IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD, IMAGENET_INCEPTION_MEAN, IMAGENET_INCEPTION_STD\n\n# 1. 디바이스 설정\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"✅ Using device: {device}\")\n\n# 2. ConvNeXt 모델 (ImageNet pretrained + 2-class head)\n#model = timm.create_model(\"convnext_tiny\", pretrained=False, num_classes=2)\n#checkpoint = torch.load(args.finetune, map_location='cpu')\n#state_dict = model.state_dict()\n#model.head = nn.Sequential(\n#    nn.AdaptiveAvgPool2d(1),  # [B, 768, H, W] → [B, 768, 1, 1]\n#    nn.Flatten(1),            # [B, 768]\n#    nn.Linear(768, 2)         # [B, 2]\n#)\nmodel = timm.create_model(\"efficientnet_b0\", num_classes=2, checkpoint_path='/kaggle/input/classifier3/pytorch/default/1/checkpoint-1.pth')\nmodel.to(device)\nmodel.eval()\n\n# 3. YOLOv8 얼굴 탐지기 로드\nface_detector = YOLO(\"/kaggle/input/yolo-face11n/pytorch/default/1/yolov11n-face.pt\", task='detect')\nface_detector.to(device)\n\n# 4. 이미지 전처리\ntransform = transforms.Compose([\n    transforms.Resize((320, 320)),\n    transforms.ToTensor(),\n    transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD),\n])\n\n# 5. 경로 설정\nvideo_dir = \"/kaggle/input/Deepfake_Detection_and_Generation_Challenge_Blue_Team/test_sample_videos\"\noutput_csv = \"submission.csv\"\n\n\n\n# 6. 비디오 단위 예측 함수\ndef predict_video(video_path):\n    cap = cv2.VideoCapture(video_path)\n    h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))\n    w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))\n    is_fake = False\n\n    while True:\n        ret, frame = cap.read()\n        if not ret:\n            break\n\n        # 얼굴 검출\n        results = face_detector(frame, verbose=False)\n        boxes = results[0].boxes.xyxy if results[0].boxes else []\n\n        for box in boxes:\n            x1, y1, x2, y2 = map(int, box.tolist())\n            cx, cy = (x1 + x2) // 2, (y1 + y2) // 2\n\n            # 얼굴 중심 기준으로 320x320 crop 영역 설정\n            half = 160\n            top, bottom = cy - half, cy + half\n            left, right = cx - half, cx + half\n\n            pad_top = max(0, -top)\n            pad_bottom = max(0, bottom - h)\n            pad_left = max(0, -left)\n            pad_right = max(0, right - w)\n\n            # crop with padding\n            crop = frame[max(0, top):min(h, bottom), max(0, left):min(w, right)]\n            crop = cv2.copyMakeBorder(\n                crop, pad_top, pad_bottom, pad_left, pad_right,\n                borderType=cv2.BORDER_CONSTANT, value=[0, 0, 0]\n            )\n\n            # 이미지 변환 후 모델 추론\n            image = Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB))\n            input_tensor = transform(image).unsqueeze(0).to(device)\n\n            with torch.no_grad():\n                output = model(input_tensor)\n                prob = F.softmax(output, dim=1)\n\n                if prob[0, 0] >= 0.6:\n#                    print(\"첫 번째 노드의 확률이 0.6 이상입니다.\")\n                    pred = 0\n                else:\n#                    print(\"첫 번째 노드의 확률이 0.6 미만입니다.\")\n                    pred = 1\n                    \n                #pred = torch.argmax(output, dim=1).item()\n\n            if pred == 0:\n                is_fake = True\n                break  # 하나라도 fake면 종료\n\n        if is_fake:\n            break\n\n    cap.release()\n    return 1 if is_fake else 0\n\n\n# 7. 전체 비디오 처리 및 결과 수집\nresults = []\nfor video_name in tqdm(os.listdir(video_dir), desc=\"🔍 Predicting\"):\n    if not video_name.endswith(\".mp4\"):\n        continue\n    video_path = os.path.join(video_dir, video_name)\n    label = predict_video(video_path)\n    results.append((video_name, label))\n\n\n#for i in range(2151):\n#    results.append((\"dummy.mp3\", 0))\n\n# 8. CSV 저장\nwith open(output_csv, \"w\", newline=\"\") as f:\n    writer = csv.writer(f)\n    writer.writerow([\"ID\", \"label\"])\n    writer.writerows(results)\n\nprint(f\"\\n🎯 Inference 완료! 결과 CSV: {output_csv}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}