{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os, sys, time\nimport cv2\nimport numpy as np\nimport pandas as pd\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\n%matplotlib inline\nimport matplotlib.pyplot as plt\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:38:20.343804Z","iopub.execute_input":"2021-05-29T04:38:20.344111Z","iopub.status.idle":"2021-05-29T04:38:22.365814Z","shell.execute_reply.started":"2021-05-29T04:38:20.344059Z","shell.execute_reply":"2021-05-29T04:38:22.365019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dir = \"../input/videos\"\n\ntest_videos = sorted([x for x in os.listdir(test_dir) if x[-4:] == \".mp4\"])\nframe_h = 5\nframe_l = 5\nlen(test_videos)","metadata":{"execution":{"iopub.status.busy":"2021-05-29T06:16:42.019439Z","iopub.execute_input":"2021-05-29T06:16:42.019729Z","iopub.status.idle":"2021-05-29T06:16:42.031928Z","shell.execute_reply.started":"2021-05-29T06:16:42.019679Z","shell.execute_reply":"2021-05-29T06:16:42.030998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gpu = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\ngpu","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:38:29.6206Z","iopub.execute_input":"2021-05-29T04:38:29.621051Z","iopub.status.idle":"2021-05-29T04:38:29.691432Z","shell.execute_reply.started":"2021-05-29T04:38:29.620842Z","shell.execute_reply":"2021-05-29T04:38:29.689909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.insert(0, \"/kaggle/input/blazeface-pytorch\")\nsys.path.insert(0, \"/kaggle/input/deepfakes-inference-demo\")","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:38:33.598209Z","iopub.execute_input":"2021-05-29T04:38:33.598664Z","iopub.status.idle":"2021-05-29T04:38:33.602547Z","shell.execute_reply.started":"2021-05-29T04:38:33.598447Z","shell.execute_reply":"2021-05-29T04:38:33.601788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from blazeface import BlazeFace\nfacedet = BlazeFace().to(gpu)\nfacedet.load_weights(\"/kaggle/input/blazeface-pytorch/blazeface.pth\")\nfacedet.load_anchors(\"/kaggle/input/blazeface-pytorch/anchors.npy\")\n_ = facedet.train(False)","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:38:39.506749Z","iopub.execute_input":"2021-05-29T04:38:39.507092Z","iopub.status.idle":"2021-05-29T04:38:43.33623Z","shell.execute_reply.started":"2021-05-29T04:38:39.507041Z","shell.execute_reply":"2021-05-29T04:38:43.335521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"something to print here\n","metadata":{}},{"cell_type":"code","source":"from helpers.read_video_1 import VideoReader\nfrom helpers.face_extract_1 import FaceExtractor\n\nframes_per_video = 64 \nvideo_reader = VideoReader()\nframes_read_fn = lambda x: video_reader.read_frames(x, num_frames=frames_per_video)\nface_extractor = FaceExtractor(frames_read_fn, facedet)","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:38:47.41914Z","iopub.execute_input":"2021-05-29T04:38:47.419418Z","iopub.status.idle":"2021-05-29T04:38:47.453568Z","shell.execute_reply.started":"2021-05-29T04:38:47.419366Z","shell.execute_reply":"2021-05-29T04:38:47.45285Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_size = 224","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:38:51.843954Z","iopub.execute_input":"2021-05-29T04:38:51.844248Z","iopub.status.idle":"2021-05-29T04:38:51.848267Z","shell.execute_reply.started":"2021-05-29T04:38:51.844198Z","shell.execute_reply":"2021-05-29T04:38:51.847327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchvision.transforms import Normalize\n\nmean = [0.485, 0.456, 0.406]\nstd = [0.229, 0.224, 0.225]\nnormalize_transform = Normalize(mean, std)","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:38:54.770215Z","iopub.execute_input":"2021-05-29T04:38:54.77056Z","iopub.status.idle":"2021-05-29T04:38:54.926712Z","shell.execute_reply.started":"2021-05-29T04:38:54.770513Z","shell.execute_reply":"2021-05-29T04:38:54.92575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def isotropically_resize_image(img, size, resample=cv2.INTER_AREA):\n    h, w = img.shape[:2]\n    if w > h:\n        h = h * size // w\n        w = size\n    else:\n        w = w * size // h\n        h = size\n\n    resized = cv2.resize(img, (w, h), interpolation=resample)\n    return resized\n\n\ndef make_square_image(img):\n    h, w = img.shape[:2]\n    size = max(h, w)\n    t = 0\n    b = size - h\n    l = 0\n    r = size - w\n    return cv2.copyMakeBorder(img, t, b, l, r, cv2.BORDER_CONSTANT, value=0)","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:39:00.845157Z","iopub.execute_input":"2021-05-29T04:39:00.845443Z","iopub.status.idle":"2021-05-29T04:39:00.853367Z","shell.execute_reply.started":"2021-05-29T04:39:00.845394Z","shell.execute_reply":"2021-05-29T04:39:00.852557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn as nn\nimport torchvision.models as models\n\nclass MyResNeXt(models.resnet.ResNet):\n    def __init__(self, training=True):\n        super(MyResNeXt, self).__init__(block=models.resnet.Bottleneck,\n                                        layers=[3, 4, 6, 3], \n                                        groups=32, \n                                        width_per_group=4)\n        self.fc = nn.Linear(2048, 1)","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:39:05.151766Z","iopub.execute_input":"2021-05-29T04:39:05.152077Z","iopub.status.idle":"2021-05-29T04:39:05.158028Z","shell.execute_reply.started":"2021-05-29T04:39:05.152023Z","shell.execute_reply":"2021-05-29T04:39:05.157266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint = torch.load(\"/kaggle/input/deepfakes-inference-demo/resnext.pth\", map_location=gpu)\n\nmodel = MyResNeXt().to(gpu)\nmodel.load_state_dict(checkpoint)\n_ = model.eval()\n\ndel checkpoint","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:39:12.48535Z","iopub.execute_input":"2021-05-29T04:39:12.485641Z","iopub.status.idle":"2021-05-29T04:39:15.34988Z","shell.execute_reply.started":"2021-05-29T04:39:12.485589Z","shell.execute_reply":"2021-05-29T04:39:15.34913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict_on_video(video_path, batch_size):\n    try:\n        # Find the faces for N frames in the video.\n        faces = face_extractor.process_video(video_path)\n            \n        \n        # Only look at one face per frame.\n        face_extractor.keep_only_best_face(faces)\n        \n        if len(faces) > 0:\n            # NOTE: When running on the CPU, the batch size must be fixed\n            # or else memory usage will blow up. (Bug in PyTorch?)\n            x = np.zeros((batch_size, input_size, input_size, 3), dtype=np.uint8)\n\n            # If we found any faces, prepare them for the model.\n            n = 0\n            for frame_data in faces:\n                for face in frame_data[\"faces\"]:\n                    # Resize to the model's required input size.\n                    # We keep the aspect ratio intact and add zero\n                    # padding if necessary.                    \n                    resized_face = isotropically_resize_image(face, input_size)\n                    resized_face = make_square_image(resized_face)\n\n                    if n < batch_size:\n                        x[n] = resized_face\n                        n += 1\n                    else:\n                        print(\"WARNING: have %d faces but batch size is %d\" % (n, batch_size))\n                    \n                    # Test time augmentation: horizontal flips.\n                    # TODO: not sure yet if this helps or not\n                    #x[n] = cv2.flip(resized_face, 1)\n                    #n += 1\n\n            if n > 0:\n                x = torch.tensor(x, device=gpu).float()\n\n                # Preprocess the images.\n                x = x.permute((0, 3, 1, 2))\n\n                for i in range(len(x)):\n                    x[i] = normalize_transform(x[i] / 255.)\n\n                # Make a prediction, then take the average.\n                with torch.no_grad():\n                    y_pred = model(x)\n                    y_pred = torch.sigmoid(y_pred.squeeze())\n                    return y_pred[:n].mean().item()\n\n    except Exception as e:\n        print(\"Prediction error on video %s: %s\" % (video_path, str(e)))\n\n    return 0.5","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:39:20.470054Z","iopub.execute_input":"2021-05-29T04:39:20.470336Z","iopub.status.idle":"2021-05-29T04:39:20.483155Z","shell.execute_reply.started":"2021-05-29T04:39:20.470289Z","shell.execute_reply":"2021-05-29T04:39:20.482111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from concurrent.futures import ThreadPoolExecutor\n\ndef predict_on_video_set(videos, num_workers):\n    def process_file(i):\n        filename = videos[i]\n        y_pred = predict_on_video(os.path.join(test_dir, filename), batch_size=frames_per_video)\n        return y_pred\n\n    with ThreadPoolExecutor(max_workers=num_workers) as ex:\n        predictions = ex.map(process_file, range(len(videos)))\n\n    return list(predictions)","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:39:26.218115Z","iopub.execute_input":"2021-05-29T04:39:26.218635Z","iopub.status.idle":"2021-05-29T04:39:26.229958Z","shell.execute_reply.started":"2021-05-29T04:39:26.218428Z","shell.execute_reply":"2021-05-29T04:39:26.227437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = predict_on_video_set(test_videos[:5], num_workers=4)","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:43:27.266591Z","iopub.execute_input":"2021-05-29T04:43:27.266892Z","iopub.status.idle":"2021-05-29T04:43:48.885172Z","shell.execute_reply.started":"2021-05-29T04:43:27.266829Z","shell.execute_reply":"2021-05-29T04:43:48.884352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:54:41.622685Z","iopub.execute_input":"2021-05-29T04:54:41.623Z","iopub.status.idle":"2021-05-29T04:54:41.627778Z","shell.execute_reply.started":"2021-05-29T04:54:41.622947Z","shell.execute_reply":"2021-05-29T04:54:41.627027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prediction_value = []\nfor value in predictions:\n    if value > .60:\n        prediction_value.append('FAKE')\n    else:\n        prediction_value.append('REAL')","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:57:05.711677Z","iopub.execute_input":"2021-05-29T04:57:05.711983Z","iopub.status.idle":"2021-05-29T04:57:05.719037Z","shell.execute_reply.started":"2021-05-29T04:57:05.711926Z","shell.execute_reply":"2021-05-29T04:57:05.718154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df_resnext = pd.DataFrame({\"filename\": test_videos[:5], \"label\": predictions,\"result\":prediction_value})\nsubmission_df_resnext.to_csv(\"submission_resnext.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:57:08.706666Z","iopub.execute_input":"2021-05-29T04:57:08.706972Z","iopub.status.idle":"2021-05-29T04:57:08.714047Z","shell.execute_reply.started":"2021-05-29T04:57:08.706919Z","shell.execute_reply":"2021-05-29T04:57:08.713032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df_resnext.head()","metadata":{"execution":{"iopub.status.busy":"2021-05-29T04:57:14.317393Z","iopub.execute_input":"2021-05-29T04:57:14.317678Z","iopub.status.idle":"2021-05-29T04:57:14.329578Z","shell.execute_reply.started":"2021-05-29T04:57:14.317626Z","shell.execute_reply":"2021-05-29T04:57:14.328292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}