{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport sys \nsys.path.append(\"/kaggle/input/retinafacev0\")\nsys.path.append(\"/kaggle/input/deepfakerepov5/DeepFake-master/\")\nsys.path.append(\"/kaggle/input/efficient-pytorch/EfficientNet-PyTorch-master/\")","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"def get_size(start_path = '../'):\n    total_size = 0\n    for dirpath, dirnames, filenames in os.walk(start_path):\n        for f in filenames:\n            if f.endswith('.mp4'): continue\n            fp = os.path.join(dirpath, f)\n            # skip if it is symbolic link\n            if not os.path.islink(fp):\n                total_size += os.path.getsize(fp)\n    return total_size\n\nprint(get_size()/1024/1024/1024, 'gigabytes')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimport glob\nimport numpy as np\nimport pandas as pd\nfrom tqdm.notebook import tqdm\nfrom shutil import copyfile\nfrom os.path import isfile, join, abspath, exists, isdir, expanduser\nfrom os import listdir, makedirs, getcwd, remove\nfrom PIL import Image\nimport torch.nn.functional as F\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as func\nimport torchvision\nfrom torchvision import transforms\n\nfrom efficientnet_pytorch import EfficientNet\nfrom models.face_detection.retinaface import RetinaFaceDetector\n\n# Hack so that RetinaFace does not download Resnet50\ncache_dir = expanduser(join('~', '.torch'))\nif not exists('/root/.cache/torch/checkpoints'):\n    makedirs('/root/.cache/torch/checkpoints')\nif not exists(cache_dir):\n    makedirs(cache_dir)\n\nmodels_dir = cache_dir + '/' + 'models/'\nif not exists(models_dir):\n    makedirs(models_dir)\n\nmodel_name = 'resnet50-19c8e357.pth'\nsrc = '/kaggle/input/resnet-pretrained/' + model_name;\ndest = \"/root/.cache/torch/checkpoints/resnet50-19c8e357.pth\"\ncopyfile(src, dest)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# File paths\nBASE_PATH = '/kaggle/input/deepfake-detection-challenge/'\nTEST_VIDEO_PATH = BASE_PATH + 'test_videos/'\nSAMP_PATH = BASE_PATH + 'sample_submission.csv'\n# File paths\ntest_img_list = glob.glob(f'{TEST_VIDEO_PATH}*.mp4')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class EffnetTest(nn.Module):\n    def __init__(self, version):\n        super(EffnetTest, self).__init__()\n        self.model = EfficientNet.from_name(f\"efficientnet-{version}\", override_params={\"num_classes\":1})\n        self.model.fc = nn.Linear(512, 1)\n        self.model._norm_layer = nn.GroupNorm(num_groups=32, num_channels=3)\n        \n    def forward(self, x):\n        x = self.model(x)\n        return torch.sigmoid(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class SimpleCNNInference:\n    def __init__(self, model_path, version='b6', img_size=200):\n        self.img_size = img_size\n        \n        self.transform = transforms.Compose([\n        transforms.ToPILImage(), \n        transforms.Resize(size=(self.img_size, self.img_size)),\n        transforms.ToTensor(),\n        transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))])\n        \n        self.device = torch.device(\"cuda\")\n        self.model = EffnetTest(version=version)\n        self.model.load_state_dict(torch.load(model_path, map_location=\"cuda:0\"))\n        self.model.to(self.device)\n        self.model.eval()\n        \n    def predict_single_from_array(self, img_frame):\n        img_frame = cv2.cvtColor(img_frame, cv2.COLOR_BGR2RGB) \n        img_frame = self.transform(img_frame).to(self.device).unsqueeze(0)\n        return float(self.model(img_frame))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_filenames = [string.split('/')[-1] for string in test_img_list]\n\ndetector = RetinaFaceDetector(weights=\"/kaggle/input/resnetretinaface/Resnet50_Final.pth\")\n# EffnetB6 with resolution 200\ninference = SimpleCNNInference(model_path=\"/kaggle/input/effnetb6-200-0741/EffnetB6_pytorch_group_imgface6_200_0.0741.pth\", \n                               version='b6', img_size=200)\n# EffnetB5 trained on different dataset\ninference2 = SimpleCNNInference(model_path=\"/kaggle/input/testefficientnet/testEfficientNet.pth\", \n                               version='b5', img_size=224)\n# Normal EffnetB5\ninference3 = SimpleCNNInference(model_path=\"/kaggle/input/effnetb5-imgface6-0074/EffnetB5_imgface6_0.074.pth\", \n                               version='b5', img_size=224)\n# Finetuned EffnetB6\ninference4 = SimpleCNNInference(model_path=\"/kaggle/input/effnetb6-0071-finetuned/EffnetB6_pytorch_group_imgface6_0.071_finetuned.pth\", \n                               version='b6', img_size=224)\n# EffnetB4 with data augmentation and label smoothing\ninference5 = SimpleCNNInference(model_path=\"/kaggle/input/effnetb4-0691/EffnetB4_pytorch_group_imgface6_0.0691.pth\", \n                               version='b4', img_size=224)\nframe_skip = 16\nres = 2 # Resolution lowered by this factor\nfinal_predictions = dict()\nfor i, video in enumerate(tqdm(test_img_list)):\n    single_predictions = []\n    cap = cv2.VideoCapture(video)   \n    for j in range(300):\n        _ = cap.grab()\n\n        # Skip n frames\n        if j % frame_skip == 0:\n            pass\n        else: \n            continue\n            \n        # Inference\n        try:\n            _, frame = cap.retrieve()\n            result = detector.detect_faces(frame[::res, ::res])\n            # empty frame\n            if result == []:\n                continue\n\n            # Result is an array with all the bounding boxes detected.\n            bounding_box = result[0]\n\n            x1, y1 = bounding_box[0]*res, bounding_box[1]*res\n            x2, y2 = bounding_box[2]*res, bounding_box[3]*res\n            frame_face = frame[y1:y2, x1:x2]\n            \n            pred = inference.predict_single_from_array(frame_face)\n            single_predictions.append(1-pred) \n            pred2 = inference2.predict_single_from_array(frame_face)\n            single_predictions.append(1-pred2)\n            pred3 = inference3.predict_single_from_array(frame_face)\n            single_predictions.append(1-pred3)\n            pred4 = inference4.predict_single_from_array(frame_face)\n            single_predictions.append(1-pred4)\n            pred5 = inference5.predict_single_from_array(frame_face)\n            single_predictions.append(1-pred5)\n        except:\n            print(\"E\")\n    final_predictions[test_filenames[i]] = np.mean(single_predictions)\n    \ncv2.destroyAllWindows()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub = pd.read_csv(SAMP_PATH)\n# Add predictions and fill nans to be safe\nsub['label'] = sub['filename'].map(final_predictions).clip(0.01, 0.99).fillna(0.5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Save as csv\nsub.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]}],"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"}},"nbformat":4,"nbformat_minor":4}