{"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":"markdown","source":"## Resnext Model","metadata":{}},{"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-12-21T15:59:38.646987Z","iopub.execute_input":"2021-12-21T15:59:38.647320Z","iopub.status.idle":"2021-12-21T15:59:40.496103Z","shell.execute_reply.started":"2021-12-21T15:59:38.647271Z","shell.execute_reply":"2021-12-21T15:59:40.495408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dir = \"/kaggle/input/deepfake-detection-challenge/test_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-12-21T15:59:40.498067Z","iopub.execute_input":"2021-12-21T15:59:40.498349Z","iopub.status.idle":"2021-12-21T15:59:40.624671Z","shell.execute_reply.started":"2021-12-21T15:59:40.498296Z","shell.execute_reply":"2021-12-21T15:59:40.624011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"PyTorch version:\", torch.__version__)\nprint(\"CUDA version:\", torch.version.cuda)\nprint(\"cuDNN version:\", torch.backends.cudnn.version())","metadata":{"execution":{"iopub.status.busy":"2021-12-21T15:59:40.625906Z","iopub.execute_input":"2021-12-21T15:59:40.626248Z","iopub.status.idle":"2021-12-21T15:59:40.632986Z","shell.execute_reply.started":"2021-12-21T15:59:40.626151Z","shell.execute_reply":"2021-12-21T15:59:40.631823Z"},"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-12-21T15:59:40.634690Z","iopub.execute_input":"2021-12-21T15:59:40.635329Z","iopub.status.idle":"2021-12-21T15:59:40.689118Z","shell.execute_reply.started":"2021-12-21T15:59:40.635136Z","shell.execute_reply":"2021-12-21T15:59:40.688380Z"},"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-12-21T15:59:40.692581Z","iopub.execute_input":"2021-12-21T15:59:40.693119Z","iopub.status.idle":"2021-12-21T15:59:40.699279Z","shell.execute_reply.started":"2021-12-21T15:59:40.693050Z","shell.execute_reply":"2021-12-21T15:59:40.698564Z"},"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-12-21T15:59:40.702846Z","iopub.execute_input":"2021-12-21T15:59:40.703307Z","iopub.status.idle":"2021-12-21T15:59:44.632311Z","shell.execute_reply.started":"2021-12-21T15:59:40.703253Z","shell.execute_reply":"2021-12-21T15:59:44.631480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from helpers.read_video_1 import VideoReader\nfrom helpers.face_extract_1 import FaceExtractor\n\nframes_per_video = 81 #frame_h * frame_l\nvideo_reader = VideoReader()\nvideo_read_fn = lambda x: video_reader.read_frames(x, num_frames=frames_per_video)\nface_extractor = FaceExtractor(video_read_fn, facedet)","metadata":{"execution":{"iopub.status.busy":"2021-12-21T15:59:44.635146Z","iopub.execute_input":"2021-12-21T15:59:44.635667Z","iopub.status.idle":"2021-12-21T15:59:44.660856Z","shell.execute_reply.started":"2021-12-21T15:59:44.635614Z","shell.execute_reply":"2021-12-21T15:59:44.660155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_size = 224","metadata":{"execution":{"iopub.status.busy":"2021-12-21T15:59:44.663036Z","iopub.execute_input":"2021-12-21T15:59:44.663530Z","iopub.status.idle":"2021-12-21T15:59:44.668816Z","shell.execute_reply.started":"2021-12-21T15:59:44.663482Z","shell.execute_reply":"2021-12-21T15:59:44.668120Z"},"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-12-21T15:59:44.670336Z","iopub.execute_input":"2021-12-21T15:59:44.670924Z","iopub.status.idle":"2021-12-21T15:59:44.790174Z","shell.execute_reply.started":"2021-12-21T15:59:44.670856Z","shell.execute_reply":"2021-12-21T15:59:44.789413Z"},"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-12-21T15:59:44.791771Z","iopub.execute_input":"2021-12-21T15:59:44.792260Z","iopub.status.idle":"2021-12-21T15:59:44.800900Z","shell.execute_reply.started":"2021-12-21T15:59:44.792081Z","shell.execute_reply":"2021-12-21T15:59:44.799782Z"},"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-12-21T15:59:44.802424Z","iopub.execute_input":"2021-12-21T15:59:44.802853Z","iopub.status.idle":"2021-12-21T15:59:44.810808Z","shell.execute_reply.started":"2021-12-21T15:59:44.802696Z","shell.execute_reply":"2021-12-21T15:59:44.810045Z"},"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-12-21T15:59:44.812270Z","iopub.execute_input":"2021-12-21T15:59:44.812879Z","iopub.status.idle":"2021-12-21T15:59:47.507732Z","shell.execute_reply.started":"2021-12-21T15:59:44.812829Z","shell.execute_reply":"2021-12-21T15:59:47.506984Z"},"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        # 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-12-21T15:59:47.510238Z","iopub.execute_input":"2021-12-21T15:59:47.510773Z","iopub.status.idle":"2021-12-21T15:59:47.523024Z","shell.execute_reply.started":"2021-12-21T15:59:47.510721Z","shell.execute_reply":"2021-12-21T15:59:47.522289Z"},"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-12-21T15:59:47.524544Z","iopub.execute_input":"2021-12-21T15:59:47.524995Z","iopub.status.idle":"2021-12-21T15:59:47.536261Z","shell.execute_reply.started":"2021-12-21T15:59:47.524781Z","shell.execute_reply":"2021-12-21T15:59:47.535580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"speed_test = False  # you have to enable this manually","metadata":{"execution":{"iopub.status.busy":"2021-12-21T15:59:47.537929Z","iopub.execute_input":"2021-12-21T15:59:47.538378Z","iopub.status.idle":"2021-12-21T15:59:47.545115Z","shell.execute_reply.started":"2021-12-21T15:59:47.538211Z","shell.execute_reply":"2021-12-21T15:59:47.544247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if speed_test:\n    start_time = time.time()\n    speedtest_videos = test_videos[:5]\n    predictions = predict_on_video_set(speedtest_videos, num_workers=4)\n    elapsed = time.time() - start_time\n    print(\"Elapsed %f sec. Average per video: %f sec.\" % (elapsed, elapsed / len(speedtest_videos)))","metadata":{"execution":{"iopub.status.busy":"2021-12-21T15:59:47.547636Z","iopub.execute_input":"2021-12-21T15:59:47.548200Z","iopub.status.idle":"2021-12-21T15:59:47.555096Z","shell.execute_reply.started":"2021-12-21T15:59:47.548136Z","shell.execute_reply":"2021-12-21T15:59:47.554171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = predict_on_video_set(test_videos, num_workers=4)","metadata":{"execution":{"iopub.status.busy":"2021-12-21T15:59:47.556395Z","iopub.execute_input":"2021-12-21T15:59:47.556989Z","iopub.status.idle":"2021-12-21T16:27:56.532087Z","shell.execute_reply.started":"2021-12-21T15:59:47.556935Z","shell.execute_reply":"2021-12-21T16:27:56.531350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df_resnext = pd.DataFrame({\"filename\": test_videos, \"label\": predictions})\nsubmission_df_resnext.to_csv(\"submission_resnext.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:27:56.533632Z","iopub.execute_input":"2021-12-21T16:27:56.533916Z","iopub.status.idle":"2021-12-21T16:27:56.994573Z","shell.execute_reply.started":"2021-12-21T16:27:56.533870Z","shell.execute_reply":"2021-12-21T16:27:56.993783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Xception Net","metadata":{}},{"cell_type":"code","source":"!pip install ../input/deepfake-xception-trained-model/pytorchcv-0.0.55-py2.py3-none-any.whl --quiet","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:27:56.995960Z","iopub.execute_input":"2021-12-21T16:27:56.996270Z","iopub.status.idle":"2021-12-21T16:28:23.985910Z","shell.execute_reply.started":"2021-12-21T16:27:56.996222Z","shell.execute_reply":"2021-12-21T16:28:23.984863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dir = \"/kaggle/input/deepfake-detection-challenge/test_videos/\"\n\ntest_videos = sorted([x for x in os.listdir(test_dir) if x[-4:] == \".mp4\"])\nlen(test_videos)","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2021-12-21T16:28:23.988290Z","iopub.execute_input":"2021-12-21T16:28:23.988617Z","iopub.status.idle":"2021-12-21T16:28:23.999200Z","shell.execute_reply.started":"2021-12-21T16:28:23.988568Z","shell.execute_reply":"2021-12-21T16:28:23.998545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gpu = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:28:24.000587Z","iopub.execute_input":"2021-12-21T16:28:24.000884Z","iopub.status.idle":"2021-12-21T16:28:24.007802Z","shell.execute_reply.started":"2021-12-21T16:28:24.000837Z","shell.execute_reply":"2021-12-21T16:28:24.007116Z"},"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-12-21T16:28:24.008725Z","iopub.execute_input":"2021-12-21T16:28:24.008985Z","iopub.status.idle":"2021-12-21T16:28:24.016968Z","shell.execute_reply.started":"2021-12-21T16:28:24.008953Z","shell.execute_reply":"2021-12-21T16:28:24.016205Z"},"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-12-21T16:28:24.019614Z","iopub.execute_input":"2021-12-21T16:28:24.019906Z","iopub.status.idle":"2021-12-21T16:28:24.054101Z","shell.execute_reply.started":"2021-12-21T16:28:24.019862Z","shell.execute_reply":"2021-12-21T16:28:24.053439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from helpers.read_video_1 import VideoReader\nfrom helpers.face_extract_1 import FaceExtractor\n\nframes_per_video = 64 # originally 4\n\nvideo_reader = VideoReader()\nvideo_read_fn = lambda x: video_reader.read_frames(x, num_frames=frames_per_video)\nface_extractor = FaceExtractor(video_read_fn, facedet)","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:28:24.055297Z","iopub.execute_input":"2021-12-21T16:28:24.055571Z","iopub.status.idle":"2021-12-21T16:28:24.060883Z","shell.execute_reply.started":"2021-12-21T16:28:24.055526Z","shell.execute_reply":"2021-12-21T16:28:24.059901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_size = 150","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:28:24.062422Z","iopub.execute_input":"2021-12-21T16:28:24.063001Z","iopub.status.idle":"2021-12-21T16:28:24.071783Z","shell.execute_reply.started":"2021-12-21T16:28:24.062874Z","shell.execute_reply":"2021-12-21T16:28:24.071018Z"},"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-12-21T16:28:24.075123Z","iopub.execute_input":"2021-12-21T16:28:24.075431Z","iopub.status.idle":"2021-12-21T16:28:24.082030Z","shell.execute_reply.started":"2021-12-21T16:28:24.075377Z","shell.execute_reply":"2021-12-21T16:28:24.081336Z"},"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-12-21T16:28:24.085231Z","iopub.execute_input":"2021-12-21T16:28:24.085457Z","iopub.status.idle":"2021-12-21T16:28:24.095902Z","shell.execute_reply.started":"2021-12-21T16:28:24.085418Z","shell.execute_reply":"2021-12-21T16:28:24.095143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls ../input/deepfake-xception-trained-model","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:28:24.099076Z","iopub.execute_input":"2021-12-21T16:28:24.099399Z","iopub.status.idle":"2021-12-21T16:28:24.808852Z","shell.execute_reply.started":"2021-12-21T16:28:24.099348Z","shell.execute_reply":"2021-12-21T16:28:24.808101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pytorchcv.model_provider import get_model\nmodel = get_model(\"xception\", pretrained=False)\nmodel = nn.Sequential(*list(model.children())[:-1]) # Remove original output layer\n\nclass Pooling(nn.Module):\n  def __init__(self):\n    super(Pooling, self).__init__()\n    \n    self.p1 = nn.AdaptiveAvgPool2d((1,1))\n    self.p2 = nn.AdaptiveMaxPool2d((1,1))\n\n  def forward(self, x):\n    x1 = self.p1(x)\n    x2 = self.p2(x)\n    return (x1+x2) * 0.5\n\nmodel[0].final_block.pool = nn.Sequential(nn.AdaptiveAvgPool2d((1,1)))\n\nclass Head(torch.nn.Module):\n  def __init__(self, in_f, out_f):\n    super(Head, self).__init__()\n    \n    self.f = nn.Flatten()\n    self.l = nn.Linear(in_f, 512)\n    self.d = nn.Dropout(0.5)\n    self.o = nn.Linear(512, out_f)\n    self.b1 = nn.BatchNorm1d(in_f)\n    self.b2 = nn.BatchNorm1d(512)\n    self.r = nn.ReLU()\n\n  def forward(self, x):\n    x = self.f(x)\n    x = self.b1(x)\n    x = self.d(x)\n\n    x = self.l(x)\n    x = self.r(x)\n    x = self.b2(x)\n    x = self.d(x)\n\n    out = self.o(x)\n    return out\n\nclass FCN(torch.nn.Module):\n  def __init__(self, base, in_f):\n    super(FCN, self).__init__()\n    self.base = base\n    self.h1 = Head(in_f, 1)\n  \n  def forward(self, x):\n    x = self.base(x)\n    return self.h1(x)\n\nnet = []\nmodel = FCN(model, 2048)\nmodel = model.cuda()\nmodel.load_state_dict(torch.load('../input/deepfake-xception-trained-model/model.pth')) # new, updated\nnet.append(model)","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:28:24.810571Z","iopub.execute_input":"2021-12-21T16:28:24.810872Z","iopub.status.idle":"2021-12-21T16:28:27.296360Z","shell.execute_reply.started":"2021-12-21T16:28:24.810822Z","shell.execute_reply":"2021-12-21T16:28:27.295579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prediction loop","metadata":{}},{"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        # 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#                     x[i] = 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-12-21T16:28:27.298038Z","iopub.execute_input":"2021-12-21T16:28:27.298482Z","iopub.status.idle":"2021-12-21T16:28:27.311392Z","shell.execute_reply.started":"2021-12-21T16:28:27.298434Z","shell.execute_reply":"2021-12-21T16:28:27.310536Z"},"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-12-21T16:28:27.313001Z","iopub.execute_input":"2021-12-21T16:28:27.313413Z","iopub.status.idle":"2021-12-21T16:28:27.325212Z","shell.execute_reply.started":"2021-12-21T16:28:27.313309Z","shell.execute_reply":"2021-12-21T16:28:27.324290Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"speed_test = False","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:28:27.330580Z","iopub.execute_input":"2021-12-21T16:28:27.330832Z","iopub.status.idle":"2021-12-21T16:28:27.336768Z","shell.execute_reply.started":"2021-12-21T16:28:27.330783Z","shell.execute_reply":"2021-12-21T16:28:27.336013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if speed_test:\n    start_time = time.time()\n    speedtest_videos = test_videos[:5]\n    predictions = predict_on_video_set(speedtest_videos, num_workers=4)\n    elapsed = time.time() - start_time\n    print(\"Elapsed %f sec. Average per video: %f sec.\" % (elapsed, elapsed / len(speedtest_videos)))","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:28:27.339597Z","iopub.execute_input":"2021-12-21T16:28:27.339840Z","iopub.status.idle":"2021-12-21T16:28:27.346991Z","shell.execute_reply.started":"2021-12-21T16:28:27.339796Z","shell.execute_reply":"2021-12-21T16:28:27.346022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nmodel.eval()\npredictions = predict_on_video_set(test_videos, num_workers=4)","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:28:27.348703Z","iopub.execute_input":"2021-12-21T16:28:27.349311Z","iopub.status.idle":"2021-12-21T16:53:54.763212Z","shell.execute_reply.started":"2021-12-21T16:28:27.348982Z","shell.execute_reply":"2021-12-21T16:53:54.762313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df_xception = pd.DataFrame({\"filename\": test_videos, \"label\": predictions})\nsubmission_df_xception.to_csv(\"submission_xception.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:53:54.764573Z","iopub.execute_input":"2021-12-21T16:53:54.764885Z","iopub.status.idle":"2021-12-21T16:53:54.775003Z","shell.execute_reply.started":"2021-12-21T16:53:54.764829Z","shell.execute_reply":"2021-12-21T16:53:54.773942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df_resnext.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:53:54.777045Z","iopub.execute_input":"2021-12-21T16:53:54.777609Z","iopub.status.idle":"2021-12-21T16:53:54.806139Z","shell.execute_reply.started":"2021-12-21T16:53:54.777419Z","shell.execute_reply":"2021-12-21T16:53:54.805222Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df_xception.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:53:54.807935Z","iopub.execute_input":"2021-12-21T16:53:54.808801Z","iopub.status.idle":"2021-12-21T16:53:54.820815Z","shell.execute_reply.started":"2021-12-21T16:53:54.808452Z","shell.execute_reply":"2021-12-21T16:53:54.819959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Ensemble of Resnext and Xception","metadata":{}},{"cell_type":"code","source":"submission_df = pd.DataFrame({\"filename\": test_videos})","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:53:54.822387Z","iopub.execute_input":"2021-12-21T16:53:54.822838Z","iopub.status.idle":"2021-12-21T16:53:54.827897Z","shell.execute_reply.started":"2021-12-21T16:53:54.822644Z","shell.execute_reply":"2021-12-21T16:53:54.827116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"r1 = 0.46441\nr2 = 0.52189\ntotal = r1 + r2\nr11 = r1/total\nr22 = r2/total","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:53:54.829495Z","iopub.execute_input":"2021-12-21T16:53:54.830111Z","iopub.status.idle":"2021-12-21T16:53:54.839322Z","shell.execute_reply.started":"2021-12-21T16:53:54.830045Z","shell.execute_reply":"2021-12-21T16:53:54.838363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df[\"label\"] = r22*submission_df_resnext[\"label\"] + r11*submission_df_xception[\"label\"]","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:53:54.840873Z","iopub.execute_input":"2021-12-21T16:53:54.841405Z","iopub.status.idle":"2021-12-21T16:53:54.889623Z","shell.execute_reply.started":"2021-12-21T16:53:54.841351Z","shell.execute_reply":"2021-12-21T16:53:54.888617Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-12-21T16:53:54.892220Z","iopub.execute_input":"2021-12-21T16:53:54.892662Z","iopub.status.idle":"2021-12-21T16:53:54.900146Z","shell.execute_reply.started":"2021-12-21T16:53:54.892613Z","shell.execute_reply":"2021-12-21T16:53:54.899349Z"},"trusted":true},"execution_count":null,"outputs":[]}]}