{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"%%capture\n!pip install ../input/maruti/facenet_pytorch-2.2.7-py3-none-any.whl\n!pip install --no-deps ../input/maruti/maruti-1.3.1-py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from maruti.imports.ml import *","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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 in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\nfrom torch.nn.utils.rnn import PackedSequence\nimport os\nfrom facenet_pytorch import MTCNN\nfrom torch.nn.utils.rnn import pack_sequence\ntest_dir = '../input/deepfake-detection-challenge/test_videos/'\ntest_videos = sorted(os.listdir(test_dir))\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mtcnn = MTCNN(select_largest=False,device=device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"feature_model = torchvision.models.resnext50_32x4d(False)\nfeature_model.fc = nn.Identity()\n_ = feature_model.to(device)\n_ = feature_model.eval()\n\nclassifier = nn.Sequential(nn.Linear(78, 32),\n                           nn.ReLU(),\n                           nn.BatchNorm1d(32),\n                           nn.Linear(32, 1),)\n_ = classifier.to(device).eval()\nimport os\ncp = '../input/featurestdmean/'\n\nmean_path = cp+'mean.pth'\nstd_path = cp+'std.pth'\nfilter_path = cp+'filter.pth'\nfeature_model_path = cp+'feature_model.pth'\nclassifier_path = cp+'classifier.pth'\nfor path in [cp, mean_path, std_path, filter_path, feature_model_path, classifier_path]:\n    assert os.path.exists(path)\n\nmean = torch.load(mean_path)\nstd = torch.load(std_path)\nfilter_idx = torch.load(filter_path)\nfeature_model_dict = torch.load(feature_model_path)\nclassifier_dict = torch.load(classifier_path)\nfeature_model.load_state_dict(feature_model_dict)\nclassifier.load_state_dict(classifier_dict)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndef predict_feature(batch):\n\n    \n    with torch.no_grad():\n        # feature calculation\n        features = feature_model(batch)\n        \n        features = features[:, filter_idx]\n        \n        features -= mean\n        features /= std\n        std_feat = features.std(dim = 0)\n        mean_feat = features.mean(dim = 0)\n        features = torch.cat([std_feat, mean_feat])\n        #classification\n        pred = classifier(features.unsqueeze(0))\n        \n        \n\n    return torch.sigmoid(pred).item()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class ResLSTM(nn.Module):\n\n    def __init__(self, pretrained=False, hidden_size=512, num_layers=1, bidirectional=False, dropout=0.5):\n        super().__init__()\n        # resnext\n        self.feature_model = maruti.deepfake.models.resnext50(True, pretrained)\n\n        # lstm\n        self.hidden_size = hidden_size\n        self.lstm = nn.LSTM(2048, hidden_size=hidden_size, num_layers=num_layers,\n                            bidirectional=bidirectional, dropout=dropout)\n        classifier_features = hidden_size * num_layers\n        if bidirectional:\n            classifier_features *= 2\n        self.classifier = nn.Linear(hidden_size, 1)\n\n    def forward(self, x):\n        # indices\n        unsorted_indices = x.unsorted_indices\n\n        # prediction on all images from each batch\n        x_data = self.feature_model(x.data)\n\n        # converting again to PackedSequence\n        x = PackedSequence(x_data, x.batch_sizes)\n\n        # lstm\n        out, (h, c) = self.lstm(x)\n        batch_size = h.shape[1]\n\n        # treat each batch differently instaed of lstm layer\n        split_on_batch = h.permute(1, 0, 2)\n\n        # reshape to make each bach flat\n        combining_passes = split_on_batch.reshape(batch_size, -1)\n\n        # classify\n        val = self.classifier(combining_passes).squeeze(1)\n        return val[unsorted_indices]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"reslstm = ResLSTM(hidden_size = 128, bidirectional=False, dropout = 0).to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"reslstm.load_state_dict(torch.load('../input/reslstm/reslstm.pth'))\n_=reslstm.eval()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = torchvision.models.resnext50_32x4d(False)\nmodel.fc = nn.Linear(2048,1)\n_ = model.to(device)\nimport os\ncp = '../input/resnexextsusp/resnextmodelsusp.pth'\nassert os.path.exists(cp)\nmodel.load_state_dict(torch.load(cp))\n_=model.eval()\n# def predict(path):\n#     cap = cv2.VideoCapture(path)\n#     frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))\n# #     rng = [[0,40],[frame_count-40,frame_count],[(frame_count-40)//2,(frame_count-40)//2 +40]]\n#     frame_id = np.linspace(0, frame_count - 30, 16, dtype = int)\n#     detection = mvis.video.get_face_frames(path, frame_id, mtcnn=mtcnn, margin = 30)\n#     plt.imshow(detection[0])\n#     batch = torch.stack([mdata.transform['val'](faces).to(device) for faces in detection])\n    \n# #     ps = pack_sequence(batch)\n#     with torch.no_grad():\n#         pred = model(batch.to(device))\n#     return torch.sigmoid(pred).mean().item()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import math\ndef better_mean(values, n):\n    sum_ = 0\n    for val in values:\n        sum_ += math.pow(val, n)\n    sum_ /= len(values)\n    return math.pow(sum_, 1/n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def predict(path):\n    cap = cv2.VideoCapture(path)\n    frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))\n    rng = [[0,40],[frame_count-40,frame_count],[(frame_count-40)//2,(frame_count-40)//2 +40]]\n    final_pred = []\n#     fig, (a1,a2) = plt.subplots(2,1)\n    detection = mvis.video.get_face_frames2(path, rng, mtcnn=mtcnn)\n    \n    for i in range(2):\n        if i==1:\n            new_det = []\n            for rng in detection:\n                rng_det = []\n                for face in rng:\n#                     a2.imshow(face)\n                    \n                    rng_det.append(cv2.flip(face, 1))\n#                     a1.imshow(rng_det[-1])\n                new_det.append(rng_det)\n            detection= new_det\n                    \n        \n    #     print(shape(detection))\n        if i==0:\n            new_det = []\n            for frames in detection:\n                new_range = []\n                for faces in frames:\n                    new_range.append(faces[0])\n                new_det.append(new_range)\n            detection = new_det\n        single_frame_batch = []\n        try:\n            for faces in detection:\n                for face in faces:\n                    single_frame_batch.append(mdata.transform['val'](face))\n            single_batch = torch.stack(single_frame_batch)\n            single_batch = single_batch.to(device)\n            num_feature = (len(single_batch)+31)//32\n            pred_sum = 0\n            for i in range(num_feature):\n                index = np.linspace(i, len(single_batch)-num_feature+i,32, endpoint =False, dtype = int)\n                index = list(map(int, index))\n                feature_batch = single_batch[index]\n        #         print(feature_batch.shape)\n                pred_sum+= predict_feature(feature_batch)\n            pred_sum/=num_feature\n            final_pred.append(pred_sum)\n        except Exception as e:\n            print(e)\n        \n        try:\n            with torch.no_grad():\n                pred = model(single_batch)\n            single_batch_pred =  torch.sigmoid(pred).mean().item()\n            final_pred.append(single_batch_pred)\n        except Excpetion as e:\n            print(e)\n            pass\n        try:\n            batch = [mdata.group_transform['val'](faces).to(device) for faces in detection]\n            ps = pack_sequence(batch)\n            with torch.no_grad():\n                pred = reslstm(ps)\n            final_pred.append(torch.sigmoid(pred).mean().item())\n        except Exception as e:\n            print(e)\n            pass\n        \n        \n        \n        \n    return better_mean(final_pred, 2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#SPEED TEST\nspeed_test = False\nmin_test = test_videos[:10]\nif speed_test:\n    start = time.perf_counter()\n    for vid in tqdm(min_test):\n        print(predict(test_dir+vid))\n    print((time.perf_counter()-start)/len(min_test))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"start = time.perf_counter()\npredictions = []\nfor i, vid in enumerate(test_videos):\n    if i%20==19:\n        os.system(f'echo {str(i)} {predictions[-1]:.2f}')\n    try:\n        predictions.append(predict(test_dir+vid))\n    except Exception as e:\n        print(vid+' error:'+str(e))\n        predictions.append(0.5)\nprint((time.perf_counter()-start)/len(test_videos))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df = pd.DataFrame({\"filename\": test_videos, \"label\": predictions})\nsubmission_df['label'] = submission_df['label'].clip(0.05, 0.95)\nsubmission_df.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch.nn.functional as F\nfrom sklearn.metrics import accuracy_score, log_loss\nimport json\n\n\nloss_fn = nn.BCELoss()\nsubmission = pd.read_csv('submission.csv')\nprint(submission.head())\n\nmetadata =  maruti.read_json('../input/filled-metadata/filled_metadata.json')\n\nx = submission['filename']\nypred = submission['label'].to_list()\ny = []\n\nfor i, _ in enumerate(x):\n    y.append(float(metadata[x[i]]['label'] == 'FAKE'))\ny = torch.tensor(y)\nypred = torch.tensor(ypred)\nloss = F.binary_cross_entropy(ypred, y)\nassert loss < 0.65, f'Loss Too High: {loss}'\nprint('loss',F.binary_cross_entropy(ypred, y).item())\nif True:\n    plt.hist(ypred, bins=200, alpha=0.5)\n    plt.hist(y, bins=200, alpha=0.2)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}