{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":16880,"databundleVersionId":858837,"sourceType":"competition"},{"sourceId":378822,"sourceType":"datasetVersion","datasetId":166388},{"sourceId":841326,"sourceType":"datasetVersion","datasetId":444017},{"sourceId":854304,"sourceType":"datasetVersion","datasetId":452468},{"sourceId":893807,"sourceType":"datasetVersion","datasetId":451078},{"sourceId":903208,"sourceType":"datasetVersion","datasetId":448076},{"sourceId":9100588,"sourceType":"datasetVersion","datasetId":5491996}],"dockerImageVersionId":29845,"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\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 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\nimport 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","execution":{"iopub.status.busy":"2024-08-07T09:24:14.938551Z","iopub.execute_input":"2024-08-07T09:24:14.939055Z","iopub.status.idle":"2024-08-07T09:24:14.944651Z","shell.execute_reply.started":"2024-08-07T09:24:14.938989Z","shell.execute_reply":"2024-08-07T09:24:14.943592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_FOLDER = '/kaggle/input/deepfake-detection-challenge'\nTRAIN_SAMPLE_FOLDER = 'train_sample_videos'\nTEST_FOLDER = 'test_videos'\n\nprint(f\"Train samples: {len(os.listdir(os.path.join(DATA_FOLDER, TRAIN_SAMPLE_FOLDER)))}\")\nprint(f\"Test samples: {len(os.listdir(os.path.join(DATA_FOLDER, TEST_FOLDER)))}\")\ntrain_dir = os.path.join(DATA_FOLDER,TRAIN_SAMPLE_FOLDER)","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:14.947124Z","iopub.execute_input":"2024-08-07T09:24:14.947394Z","iopub.status.idle":"2024-08-07T09:24:14.967256Z","shell.execute_reply.started":"2024-08-07T09:24:14.947349Z","shell.execute_reply":"2024-08-07T09:24:14.965996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FACE_DETECTION_FOLDER = \"/kaggle/input/haar-cascades-for-face-detection\"\n\nprint(f\"Face detection resources: {os.listdir(FACE_DETECTION_FOLDER)}\")","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:14.968971Z","iopub.execute_input":"2024-08-07T09:24:14.969349Z","iopub.status.idle":"2024-08-07T09:24:14.974883Z","shell.execute_reply.started":"2024-08-07T09:24:14.969278Z","shell.execute_reply":"2024-08-07T09:24:14.974079Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Listing All the files in the TRAIN folder**","metadata":{}},{"cell_type":"code","source":"train_list = list(os.listdir(os.path.join(DATA_FOLDER,TRAIN_SAMPLE_FOLDER)))\next_dict = []\nfor file in train_list:\n    file_ext = file.split('.')[1]\n    if file_ext not in ext_dict:\n        ext_dict.append(file_ext)\nprint(f\"File Extensions: {ext_dict}\")\n\nfor file_ext in ext_dict:\n    print(f\"Files with extension '{file_ext}': {len([file for file in train_list if file.endswith(file_ext)])}\")","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:14.977911Z","iopub.execute_input":"2024-08-07T09:24:14.978278Z","iopub.status.idle":"2024-08-07T09:24:14.989038Z","shell.execute_reply.started":"2024-08-07T09:24:14.978210Z","shell.execute_reply":"2024-08-07T09:24:14.987861Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Listing All the files in the TEST folder**","metadata":{}},{"cell_type":"code","source":"test_list = list(os.listdir(os.path.join(DATA_FOLDER,TEST_FOLDER)))\next_dict = []\nfor file in test_list:\n    file_ext = file.split('.')[1]\n    if file_ext not in ext_dict:\n        ext_dict.append(file_ext)\nprint(f\"File Extensions: {ext_dict}\")\n\nfor file_ext in ext_dict:\n    print(f\"Files with extension '{file_ext}': {len([file for file in test_list if file.endswith(file_ext)])}\")","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:14.991319Z","iopub.execute_input":"2024-08-07T09:24:14.991613Z","iopub.status.idle":"2024-08-07T09:24:15.001194Z","shell.execute_reply.started":"2024-08-07T09:24:14.991565Z","shell.execute_reply":"2024-08-07T09:24:15.000191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"json_file = [file for file in train_list if file.endswith('json')][0]\nmeta_train_df = pd.read_json(os.path.join(DATA_FOLDER,TRAIN_SAMPLE_FOLDER,json_file)).T\nmeta_train_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:15.002802Z","iopub.execute_input":"2024-08-07T09:24:15.003303Z","iopub.status.idle":"2024-08-07T09:24:15.214849Z","shell.execute_reply.started":"2024-08-07T09:24:15.003246Z","shell.execute_reply":"2024-08-07T09:24:15.214000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_train_df.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:15.216524Z","iopub.execute_input":"2024-08-07T09:24:15.216860Z","iopub.status.idle":"2024-08-07T09:24:15.224648Z","shell.execute_reply.started":"2024-08-07T09:24:15.216803Z","shell.execute_reply":"2024-08-07T09:24:15.223820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The metadata of the dataset is divided into 3 columns (label,split,original) label is the obvious labelling of each video into real and fake; split is always going to be train for the train dataset; and original is the name of the original video of which the deepfake was made. So the 77 videos which are null in the metadata indicate the abscense of the original copy of the deepfaked video.","metadata":{}},{"cell_type":"code","source":"print(f\"Length of 'split' column: {len([item for item in meta_train_df.split])}\")\nprint(f\"unique values in split column: {meta_train_df.split.nunique()}\")","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:15.228174Z","iopub.execute_input":"2024-08-07T09:24:15.228475Z","iopub.status.idle":"2024-08-07T09:24:15.237183Z","shell.execute_reply.started":"2024-08-07T09:24:15.228427Z","shell.execute_reply":"2024-08-07T09:24:15.236274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Some basic visualization","metadata":{}},{"cell_type":"code","source":"train_dir","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:15.240201Z","iopub.execute_input":"2024-08-07T09:24:15.240488Z","iopub.status.idle":"2024-08-07T09:24:15.250016Z","shell.execute_reply.started":"2024-08-07T09:24:15.240440Z","shell.execute_reply":"2024-08-07T09:24:15.249190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2 as cv\nimport matplotlib\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfig, ax = plt.subplots(1,1,figsize=(15,15))\ntrain_video_files = [train_dir + x for x in os.listdir(train_dir)]\nvideo_file = '/kaggle/input/deepfake-detection-challenge/train_sample_videos/akxoopqjqz.mp4'\ncap = cv.VideoCapture(video_file)\nsuccess, image = cap.read()\nimage = cv.cvtColor(image,cv.COLOR_BGR2RGB)\ncap.release()\nax.imshow(image)\nax.xaxis.set_visible(False)\nax.yaxis.set_visible(False)\nax.title.set_text(f\"FRAME 0: {video_file.split('/')[-1]}\")\nplt.grid(False)","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:15.251633Z","iopub.execute_input":"2024-08-07T09:24:15.251931Z","iopub.status.idle":"2024-08-07T09:24:15.744993Z","shell.execute_reply.started":"2024-08-07T09:24:15.251876Z","shell.execute_reply":"2024-08-07T09:24:15.744157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_count(feature, title, df, size=1):\n    '''\n    Plot count of classes / feature\n    param: feature - the feature to analyze\n    param: title - title to add to the graph\n    param: df - dataframe from which we plot feature's classes distribution \n    param: size - default 1.\n    '''\n    f, ax = plt.subplots(1,1, figsize=(4*size,4))\n    total = float(len(df))\n    g = sns.countplot(df[feature], order = df[feature].value_counts().index[:20], palette='Set3')\n    g.set_title(\"Number and percentage of {}\".format(title))\n    if(size > 2):\n        plt.xticks(rotation=90, size=8)\n    for p in ax.patches:\n        height = p.get_height()\n        ax.text(p.get_x()+p.get_width()/2.,\n                height + 3,\n                '{:1.2f}%'.format(100*height/total),\n                ha=\"center\") \n    plt.show()  \nplot_count('split', 'split (train)', meta_train_df)","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:15.746393Z","iopub.execute_input":"2024-08-07T09:24:15.746670Z","iopub.status.idle":"2024-08-07T09:24:15.989419Z","shell.execute_reply.started":"2024-08-07T09:24:15.746609Z","shell.execute_reply":"2024-08-07T09:24:15.987834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_count('label', 'label (train)', meta_train_df)","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:15.991795Z","iopub.execute_input":"2024-08-07T09:24:15.992431Z","iopub.status.idle":"2024-08-07T09:24:16.257468Z","shell.execute_reply.started":"2024-08-07T09:24:15.992185Z","shell.execute_reply":"2024-08-07T09:24:16.255828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The below face detection is not very good it misses 90% of the faces in the sample video, so trying YOLOv2 instead**","metadata":{}},{"cell_type":"code","source":"class ObjectDetector():\n    def __init__(self, object_cascade_path):\n        self.objectCascade = cv.CascadeClassifier(object_cascade_path)\n    \n    def detect(self, image, scale_factor=1.3, min_neighbors=5, min_size=(20,20)):\n        rects = self.objectCascade.detectMultiScale(image,\n                                                    scaleFactor=scale_factor,\n                                                    minNeighbors=min_neighbors,\n                                                    minSize=min_size)\n        return rects\n\nfrontal_cascade_path = os.path.join(FACE_DETECTION_FOLDER, 'haarcascade_frontalface_default.xml')\neye_cascade_path = os.path.join(FACE_DETECTION_FOLDER, 'haarcascade_eye.xml')\nprofile_cascade_path = os.path.join(FACE_DETECTION_FOLDER, 'haarcascade_profileface.xml')\nsmile_cascade_path = os.path.join(FACE_DETECTION_FOLDER, 'haarcascade_smile.xml')\n\n# Create detector objects\nfd = ObjectDetector(frontal_cascade_path)\ned = ObjectDetector(eye_cascade_path)\npd = ObjectDetector(profile_cascade_path)\nsd = ObjectDetector(smile_cascade_path)\n\ndef detect_and_zoom_face(image):\n    image_gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)\n    faces = fd.detect(image_gray, scale_factor=1.3, min_neighbors=5, min_size=(50, 50))\n    \n    if len(faces) == 0:\n        return None\n    \n    # For simplicity, we'll focus on the first detected face\n    x, y, w, h = faces[0]\n    \n    # Add some margin around the face (20% on each side)\n    margin = int(1.5 * w)\n    x1 = max(0, x - margin)\n    y1 = max(0, y - margin)\n    x2 = min(image.shape[1], x + w + margin)\n    y2 = min(image.shape[0], y + h + margin)\n    \n    # Crop and return the face region\n    return image[y1:y2, x1:x2]\n\ndef detect_objects(image, scale_factor, min_neighbors, min_size):\n    zoomed_face = detect_and_zoom_face(image)\n    if zoomed_face is None:\n        print(\"No face detected in the image.\")\n        return\n    \n    image_gray = cv.cvtColor(zoomed_face, cv.COLOR_BGR2GRAY)\n    \n    eyes = ed.detect(image_gray, scale_factor=scale_factor, min_neighbors=min_neighbors, min_size=(int(min_size[0]/2), int(min_size[1]/2)))\n    for x, y, w, h in eyes:\n        cv.circle(zoomed_face, (int(x+w/2), int(y+h/2)), (int((w + h)/4)), (0, 0, 255), 2)\n    \n    profiles = pd.detect(image_gray, scale_factor=scale_factor, min_neighbors=min_neighbors, min_size=min_size)\n    for x, y, w, h in profiles:\n        cv.rectangle(zoomed_face, (x,y), (x+w, y+h), (255, 0, 0), 2)\n    \n    # Display the result\n    fig = plt.figure(figsize=(10,10))\n    ax = fig.add_subplot(111)\n    zoomed_face_rgb = cv.cvtColor(zoomed_face, cv.COLOR_BGR2RGB)\n    ax.imshow(zoomed_face_rgb)\n    plt.show()\n\ndef extract_image_objects(video_file, video_set_folder='train_sample_videos'):\n    video_path = os.path.join(DATA_FOLDER, video_set_folder, video_file)\n    capture_image = cv.VideoCapture(video_path) \n    print(video_path)\n    ret, frame = capture_image.read()\n    if ret:\n        detect_objects(image=frame, scale_factor=1.3, min_neighbors=5, min_size=(30, 30))\n    else:\n        print(f\"Failed to extract frame from {video_file}\")\n    capture_image.release()\n","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:16.259890Z","iopub.execute_input":"2024-08-07T09:24:16.260578Z","iopub.status.idle":"2024-08-07T09:24:16.401427Z","shell.execute_reply.started":"2024-08-07T09:24:16.260298Z","shell.execute_reply":"2024-08-07T09:24:16.400487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"same_original_fake_train_sample_video = list(meta_train_df.loc[meta_train_df.original=='kgbkktcjxf.mp4'].index)\nfor video_file in same_original_fake_train_sample_video[1:4]:\n    print(video_file)\n    extract_image_objects(video_file)","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:16.402977Z","iopub.execute_input":"2024-08-07T09:24:16.403268Z","iopub.status.idle":"2024-08-07T09:24:18.183890Z","shell.execute_reply.started":"2024-08-07T09:24:16.403225Z","shell.execute_reply":"2024-08-07T09:24:18.182916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"video_file = '/kaggle/input/deepfake-detection-challenge/train_sample_videos/akxoopqjqz.mp4'\n\ncap = cv.VideoCapture(video_file)\n\nframes = []\nwhile(cap.isOpened()):\n    ret, frame = cap.read()\n    if ret==True:\n        frames.append(frame)\n        if cv.waitKey(1) & 0xFF == ord('q'):\n            break\n    else:\n        break\ncap.release()\n\nprint('The number of frames saved: ', len(frames))","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:18.185508Z","iopub.execute_input":"2024-08-07T09:24:18.186049Z","iopub.status.idle":"2024-08-07T09:24:20.113597Z","shell.execute_reply.started":"2024-08-07T09:24:18.185993Z","shell.execute_reply":"2024-08-07T09:24:20.112514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axes = plt.subplots(3, 3, figsize=(15, 10))\naxes = np.array(axes)\naxes = axes.reshape(-1)\n\nax_ix = 0\nfor i in [0, 25, 50, 75, 100, 125, 150, 175, 250]:\n    frame = frames[i]\n    #fig, ax = plt.subplots(1,1, figsize=(5, 5))\n    image = cv.cvtColor(frame, cv.COLOR_BGR2RGB)\n    axes[ax_ix].imshow(image)\n    axes[ax_ix].xaxis.set_visible(False)\n    axes[ax_ix].yaxis.set_visible(False)\n    axes[ax_ix].set_title(f'Frame {i}')\n    ax_ix += 1\nplt.grid(False)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:20.114981Z","iopub.execute_input":"2024-08-07T09:24:20.115236Z","iopub.status.idle":"2024-08-07T09:24:21.443946Z","shell.execute_reply.started":"2024-08-07T09:24:20.115193Z","shell.execute_reply":"2024-08-07T09:24:21.443083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def detect_and_draw_features(image):\n    zoomed_face = detect_and_zoom_face(image)\n    if zoomed_face is None:\n        return None\n    \n    image_gray = cv.cvtColor(zoomed_face, cv.COLOR_BGR2GRAY)\n    \n    eyes = ed.detect(image_gray, scale_factor=1.3, min_neighbors=5, min_size=(20, 20))\n    for x, y, w, h in eyes:\n        cv.circle(zoomed_face, (int(x+w/2), int(y+h/2)), (int((w + h)/4)), (0, 255, 0), 2)\n    \n    return zoomed_face\n\nfig, axes = plt.subplots(3, 3, figsize=(15, 15))\naxes = np.array(axes).reshape(-1)\n\nfor ax_ix, i in enumerate([0, 25, 50, 75, 100, 125, 150, 175, 250]):\n    if i >= len(frames):\n        break\n    \n    frame = frames[i]\n    face_with_features = detect_and_draw_features(frame)\n    \n    if face_with_features is None:\n        print(f'Could not find face in frame {i}')\n        continue\n    \n    image = cv.cvtColor(face_with_features, cv.COLOR_BGR2RGB)\n    axes[ax_ix].imshow(image)\n    axes[ax_ix].xaxis.set_visible(False)\n    axes[ax_ix].yaxis.set_visible(False)\n    axes[ax_ix].set_title(f'Frame {i}')\n\n# Remove any unused subplots\nfor ax in axes[ax_ix+1:]:\n    ax.remove()\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:21.445641Z","iopub.execute_input":"2024-08-07T09:24:21.445998Z","iopub.status.idle":"2024-08-07T09:24:23.975849Z","shell.execute_reply.started":"2024-08-07T09:24:21.445936Z","shell.execute_reply":"2024-08-07T09:24:23.974784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# The below code is the YOLOv2 Code for face detection","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport matplotlib\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm_notebook\n%matplotlib inline \nimport cv2 as cv\nfrom matplotlib.patches import Rectangle","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:23.977262Z","iopub.execute_input":"2024-08-07T09:24:23.977580Z","iopub.status.idle":"2024-08-07T09:24:23.998264Z","shell.execute_reply.started":"2024-08-07T09:24:23.977520Z","shell.execute_reply":"2024-08-07T09:24:23.997287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.python.keras.layers import Conv2D, Input, ZeroPadding2D, Dense, Lambda\nfrom tensorflow.python.keras.models import Model\nfrom tensorflow.python.keras.applications.mobilenet_v2 import MobileNetV2\nimport tensorflow as tf\ntf.compat.v1.disable_eager_execution()\nimport math\nimport numpy as np\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:23.999846Z","iopub.execute_input":"2024-08-07T09:24:24.000115Z","iopub.status.idle":"2024-08-07T09:24:27.914247Z","shell.execute_reply.started":"2024-08-07T09:24:24.000062Z","shell.execute_reply":"2024-08-07T09:24:27.913261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_mobilenetv2_224_075_detector(path):\n    input_tensor = Input(shape=(224, 224, 3))\n    output_tensor = MobileNetV2(weights=None, include_top=False, input_tensor=input_tensor, alpha=0.75).output\n    output_tensor = ZeroPadding2D()(output_tensor)\n    output_tensor = Conv2D(kernel_size=(3, 3), filters=5)(output_tensor)\n\n    model = Model(inputs=input_tensor, outputs=output_tensor)\n    model.load_weights(path)\n    \n    return model\n\nmobilenetv2 = load_mobilenetv2_224_075_detector(\"/kaggle/input/facedetection-mobilenetv2/facedetection-mobilenetv2-size224-alpha0.75.h5\")\nmobilenetv2.summary()","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:27.916498Z","iopub.execute_input":"2024-08-07T09:24:27.916791Z","iopub.status.idle":"2024-08-07T09:24:37.760778Z","shell.execute_reply.started":"2024-08-07T09:24:27.916746Z","shell.execute_reply":"2024-08-07T09:24:37.759910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def transpose_shots(shots):\n    return [(shot[1], shot[0], shot[3], shot[2], shot[4]) for shot in shots]\n\nSHOTS = {\n    # Existing entries\n    '2-16/9': {\n        'aspect_ratio': 16/9,\n        'shots': [\n            (0, 0, 9/16, 1, 1),\n            (7/16, 0, 9/16, 1, 1)\n        ]\n    },\n    '10-16/9': {\n        'aspect_ratio': 16/9,\n        'shots': [\n            (0, 0, 9/16, 1, 1),\n            (7/16, 0, 9/16, 1, 1),\n            (0, 0, 5/16, 5/9, 0.5),\n            (0, 4/9, 5/16, 5/9, 0.5),\n            (11/48, 0, 5/16, 5/9, 0.5),\n            (11/48, 4/9, 5/16, 5/9, 0.5),\n            (22/48, 0, 5/16, 5/9, 0.5),\n            (22/48, 4/9, 5/16, 5/9, 0.5),\n            (11/16, 0, 5/16, 5/9, 0.5),\n            (11/16, 4/9, 5/16, 5/9, 0.5),\n        ]\n    },\n    # New entry for mobile aspect ratio\n    'mobile-1440-2546': {\n        'aspect_ratio': 1440/2546,\n        'shots': [\n            (0, 0, 1, 1, 1),  \n            (0, 0, 1, 0.5, 0.5), \n            (0, 0.5, 1, 0.5, 0.5),  \n            (0, 0, 0.5, 1, 0.5),  \n            (0.5, 0, 0.5, 1, 0.5),  \n            (0, 0, 0.5, 0.5, 0.25),  \n            (0.5, 0, 0.5, 0.5, 0.25),  \n            (0, 0.5, 0.5, 0.5, 0.25),  \n            (0.5, 0.5, 0.5, 0.5, 0.25), \n        ]\n    }\n}\n\n# Update SHOTS_T if needed\nSHOTS_T = {\n    '2-9/16': {\n        'aspect_ratio': 9/16,\n        'shots': transpose_shots(SHOTS['2-16/9']['shots'])\n    },\n    '10-9/16': {\n        'aspect_ratio': 9/16,\n        'shots': transpose_shots(SHOTS['10-16/9']['shots'])\n    },\n    # Add transposed version if needed\n    'mobile-2546-1440': {\n        'aspect_ratio': 2546/1440,\n        'shots': transpose_shots(SHOTS['mobile-1440-2546']['shots'])\n    }\n}\n\ndef r(x):\n    return int(round(x))\n\ndef sigmoid(x):\n    return 1 / (np.exp(-x) + 1)\n\ndef non_max_suppression(boxes, p, iou_threshold):\n\n    if len(boxes) == 0:\n        return np.array([])\n\n    x1 = boxes[:, 0]\n    y1 = boxes[:, 1]\n    x2 = boxes[:, 2]\n    y2 = boxes[:, 3]\n\n    indexes = np.argsort(p)\n    true_boxes_indexes = []\n\n    while len(indexes) > 0:\n        true_boxes_indexes.append(indexes[-1])\n\n        intersection = np.maximum(np.minimum(x2[indexes[:-1]], x2[indexes[-1]]) - np.maximum(x1[indexes[:-1]], x1[indexes[-1]]), 0) * np.maximum(np.minimum(y2[indexes[:-1]], y2[indexes[-1]]) - np.maximum(y1[indexes[:-1]], y1[indexes[-1]]), 0)\n        iou = intersection / ((x2[indexes[:-1]] - x1[indexes[:-1]]) * (y2[indexes[:-1]] - y1[indexes[:-1]]) + (x2[indexes[-1]] - x1[indexes[-1]]) * (y2[indexes[-1]] - y1[indexes[-1]]) - intersection)\n\n        indexes = np.delete(indexes, -1)\n        indexes = np.delete(indexes, np.where(iou >= iou_threshold)[0])\n\n    return boxes[true_boxes_indexes]\n\ndef union_suppression(boxes, threshold):\n    if len(boxes) == 0:\n        return np.array([])\n\n    x1 = boxes[:, 0]\n    y1 = boxes[:, 1]\n    x2 = boxes[:, 2]\n    y2 = boxes[:, 3]\n\n    indexes = np.argsort((x2 - x1) * (y2 - y1))\n    result_boxes = []\n\n    while len(indexes) > 0:\n        intersection = np.maximum(np.minimum(x2[indexes[:-1]], x2[indexes[-1]]) - np.maximum(x1[indexes[:-1]], x1[indexes[-1]]), 0) * np.maximum(np.minimum(y2[indexes[:-1]], y2[indexes[-1]]) - np.maximum(y1[indexes[:-1]], y1[indexes[-1]]), 0)\n        min_s = np.minimum((x2[indexes[:-1]] - x1[indexes[:-1]]) * (y2[indexes[:-1]] - y1[indexes[:-1]]), (x2[indexes[-1]] - x1[indexes[-1]]) * (y2[indexes[-1]] - y1[indexes[-1]]))\n        ioms = intersection / (min_s + 1e-9)\n        neighbours = np.where(ioms >= threshold)[0]\n        if len(neighbours) > 0:\n            result_boxes.append([min(np.min(x1[indexes[neighbours]]), x1[indexes[-1]]), min(np.min(y1[indexes[neighbours]]), y1[indexes[-1]]), max(np.max(x2[indexes[neighbours]]), x2[indexes[-1]]), max(np.max(y2[indexes[neighbours]]), y2[indexes[-1]])])\n        else:\n            result_boxes.append([x1[indexes[-1]], y1[indexes[-1]], x2[indexes[-1]], y2[indexes[-1]]])\n\n        indexes = np.delete(indexes, -1)\n        indexes = np.delete(indexes, neighbours)\n\n    return result_boxes\n\nclass FaceDetector():\n    def __init__(self, model=mobilenetv2, image_size=224, grids=7, iou_threshold=0.1, union_threshold=0.1, prob_threshold=0.65):\n        self.model = model\n        self.image_size = image_size\n        self.grids = grids\n        self.iou_threshold = iou_threshold\n        self.union_threshold = union_threshold\n        self.prob_threshold = prob_threshold\n    \n    def detect(self, frame):\n        original_frame_shape = frame.shape\n        aspect_ratio = frame.shape[1] / frame.shape[0]\n\n        # Define shots based on the current frame's aspect ratio\n        shots = {\n            'aspect_ratio': aspect_ratio,\n            'shots': [\n                (0, 0, 1, 1, 1),  # Full frame\n                (0, 0, 0.5, 1, 0.5),  # Left half\n                (0.5, 0, 0.5, 1, 0.5),  # Right half\n                (0, 0, 1, 0.5, 0.5),  # Top half\n                (0, 0.5, 1, 0.5, 0.5),  # Bottom half\n            ]\n        }\n\n        frames = []\n        for s in shots['shots']:\n            x1, y1 = int(s[0] * frame.shape[1]), int(s[1] * frame.shape[0])\n            x2, y2 = int((s[0] + s[2]) * frame.shape[1]), int((s[1] + s[3]) * frame.shape[0])\n            crop = frame[y1:y2, x1:x2]\n            frames.append(cv2.resize(crop, (self.image_size, self.image_size), interpolation=cv2.INTER_NEAREST))\n        \n        frames = np.array(frames)\n\n        predictions = self.model.predict(frames, batch_size=len(frames), verbose=0)\n\n        boxes = []\n        for i, s in enumerate(shots['shots']):\n            for j in range(predictions.shape[1]):\n                for k in range(predictions.shape[2]):\n                    p = sigmoid(predictions[i][j][k][4])\n                    if p > self.prob_threshold:\n                        px = sigmoid(predictions[i][j][k][0])\n                        py = sigmoid(predictions[i][j][k][1])\n                        pw = min(math.exp(predictions[i][j][k][2] / self.grids), self.grids)\n                        ph = min(math.exp(predictions[i][j][k][3] / self.grids), self.grids)\n                        if pw > 1e-9 and ph > 1e-9:\n                            cx = (px + j) / self.grids\n                            cy = (py + k) / self.grids\n                            wx = pw / self.grids\n                            wy = ph / self.grids\n                            lx = (s[0] + (cx - wx / 2) * s[2]) * frame.shape[1] / original_frame_shape[1]\n                            ly = (s[1] + (cy - wy / 2) * s[3]) * frame.shape[0] / original_frame_shape[0]\n                            rx = (s[0] + (cx + wx / 2) * s[2]) * frame.shape[1] / original_frame_shape[1]\n                            ry = (s[1] + (cy + wy / 2) * s[3]) * frame.shape[0] / original_frame_shape[0]\n                            boxes.append([lx, ly, rx, ry])\n\n        boxes = np.array(boxes)\n        boxes = non_max_suppression(boxes, np.ones(len(boxes)), self.iou_threshold)\n        boxes = union_suppression(boxes, self.union_threshold)\n\n        return list(boxes)","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:37.762311Z","iopub.execute_input":"2024-08-07T09:24:37.762576Z","iopub.status.idle":"2024-08-07T09:24:37.844940Z","shell.execute_reply.started":"2024-08-07T09:24:37.762530Z","shell.execute_reply":"2024-08-07T09:24:37.843557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"detector = FaceDetector()","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:37.846801Z","iopub.execute_input":"2024-08-07T09:24:37.847169Z","iopub.status.idle":"2024-08-07T09:24:37.861591Z","shell.execute_reply.started":"2024-08-07T09:24:37.847107Z","shell.execute_reply":"2024-08-07T09:24:37.860799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_image_from_video(video_path):\n    '''\n    input: video_path - path for video\n    process:\n    1. perform a video capture from the video\n    2. read the image\n    3. display the image\n    '''\n    capture_image = cv.VideoCapture(video_path) \n    ret, frame = capture_image.read()\n    fig = plt.figure(figsize=(10,10))\n    ax = fig.add_subplot(111)\n    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)\n    ax.imshow(frame)\n    boxes = detector.detect(frame)\n    for box in boxes:\n        lx = int(round(box[0] * frame.shape[1]))\n        ly = int(round(box[1] * frame.shape[0]))\n        rx = int(round(box[2] * frame.shape[1]))\n        ry = int(round(box[3] * frame.shape[0]))\n        # x, y, w, h here\n        ax.add_patch(Rectangle((lx,ly),rx - lx,ry - ly,linewidth=2,edgecolor='r',facecolor='none'))","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:37.862989Z","iopub.execute_input":"2024-08-07T09:24:37.863294Z","iopub.status.idle":"2024-08-07T09:24:37.874734Z","shell.execute_reply.started":"2024-08-07T09:24:37.863240Z","shell.execute_reply":"2024-08-07T09:24:37.873783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def detect_and_draw_faces(frame):\n    boxes = detector.detect(frame)\n    \n    frame_with_faces = frame.copy()\n    \n    height, width = frame.shape[:2]\n    \n    for box in boxes:\n        lx = int(box[0] * width)\n        ly = int(box[1] * height)\n        rx = int(box[2] * width)\n        ry = int(box[3] * height)\n        \n        padding = 5\n        lx = max(0, lx - padding)\n        ly = max(0, ly - padding)\n        rx = min(width - 1, rx + padding)\n        ry = min(height - 1, ry + padding)\n        \n        cv.rectangle(frame_with_faces, (lx, ly), (rx, ry), (0, 255, 0), 2)\n    \n    return frame_with_faces","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:37.887820Z","iopub.execute_input":"2024-08-07T09:24:37.888074Z","iopub.status.idle":"2024-08-07T09:24:37.897837Z","shell.execute_reply.started":"2024-08-07T09:24:37.888032Z","shell.execute_reply":"2024-08-07T09:24:37.897036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axes = plt.subplots(3, 3, figsize=(15, 15))\naxes = np.array(axes).reshape(-1)\n\nfor ax_ix, i in enumerate([0, 25, 50, 75, 100, 125, 150, 175, 250]):\n    if i >= len(frames):\n        break\n    \n    frame = frames[i]\n    frame_with_faces = detect_and_draw_faces(frame)\n    \n    image = cv.cvtColor(frame_with_faces, cv.COLOR_BGR2RGB)\n    axes[ax_ix].imshow(image)\n    axes[ax_ix].xaxis.set_visible(False)\n    axes[ax_ix].yaxis.set_visible(False)\n    axes[ax_ix].set_title(f'Frame {i}')\n\n# Remove any unused subplots\nfor ax in axes[ax_ix+1:]:\n    ax.remove()\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:37.899714Z","iopub.execute_input":"2024-08-07T09:24:37.900035Z","iopub.status.idle":"2024-08-07T09:24:43.920814Z","shell.execute_reply.started":"2024-08-07T09:24:37.899979Z","shell.execute_reply":"2024-08-07T09:24:43.919479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport json\nfrom tqdm import tqdm\nimport warnings\n\n# Ignore RuntimeWarnings\nwarnings.filterwarnings(\"ignore\", category=RuntimeWarning)\n\ndef load_metadata(json_path):\n    with open(json_path, 'r') as f:\n        return json.load(f)\n\ndef safe_detect(detector, frame):\n    try:\n        return detector.detect(frame)\n    except Exception as e:\n        print(f\"Error in face detection: {str(e)}\")\n        return []\n\ndef process_video(video_path, output_folder, detector, is_fake, frame_interval=25, face_padding=0.2):\n    video_name = os.path.splitext(os.path.basename(video_path))[0]\n    video_type = \"fake\" if is_fake else \"real\"\n    video_output_folder = os.path.join(output_folder, video_type, video_name)\n    os.makedirs(video_output_folder, exist_ok=True)\n    \n    cap = cv2.VideoCapture(video_path)\n    \n    frame_count = 0\n    while True:\n        ret, frame = cap.read()\n        if not ret:\n            break\n        \n        if frame_count % frame_interval == 0:\n            boxes = safe_detect(detector, frame)\n            \n            for i, box in enumerate(boxes):\n                height, width = frame.shape[:2]\n                lx, ly, rx, ry = [int(coord * dim) for coord, dim in zip(box, [width, height, width, height])]\n                \n                face_width, face_height = rx - lx, ry - ly\n                padding_x, padding_y = int(face_width * face_padding), int(face_height * face_padding)\n                \n                lx, ly = max(0, lx - padding_x), max(0, ly - padding_y)\n                rx, ry = min(width, rx + padding_x), min(height, ry + padding_y)\n                \n                face = frame[ly:ry, lx:rx]\n                \n                output_path = os.path.join(video_output_folder, f\"frame_{frame_count:04d}_face_{i:02d}.jpg\")\n                cv2.imwrite(output_path, face)\n        \n        frame_count += 1\n    \n    cap.release()\n\ndef process_all_videos(input_folder, output_folder, detector, metadata):\n    for video_file in tqdm(os.listdir(input_folder)):\n        if video_file.endswith(('.mp4', '.avi')):\n            if video_file in metadata:\n                video_path = os.path.join(input_folder, video_file)\n                is_fake = metadata[video_file]['label'] == 'FAKE'\n                try:\n                    process_video(video_path, output_folder, detector, is_fake)\n                except Exception as e:\n                    print(f\"Error processing video {video_file}: {str(e)}\")\n            else:\n                print(f\"Warning: Metadata not found for video {video_file}\")","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:43.922807Z","iopub.execute_input":"2024-08-07T09:24:43.923140Z","iopub.status.idle":"2024-08-07T09:24:43.949533Z","shell.execute_reply.started":"2024-08-07T09:24:43.923071Z","shell.execute_reply":"2024-08-07T09:24:43.948183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"OUTPUT_FOLDER = '/kaggle/working/processed_data'\nMETADATA_FILE = os.path.join(DATA_FOLDER, TRAIN_SAMPLE_FOLDER, 'metadata.json')\n\n# Ensure the output folders exist\nos.makedirs(os.path.join(OUTPUT_FOLDER, 'fake'), exist_ok=True)\nos.makedirs(os.path.join(OUTPUT_FOLDER, 'real'), exist_ok=True)\n\n# Load metadata\nmetadata = load_metadata(METADATA_FILE)\n\n# Process all videos in the training sample folder\nprocess_all_videos(os.path.join(DATA_FOLDER, TRAIN_SAMPLE_FOLDER), OUTPUT_FOLDER, detector, metadata)\n\nprint(\"Processing complete. Check the output folder for results.\")","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:24:43.950998Z","iopub.execute_input":"2024-08-07T09:24:43.951329Z","iopub.status.idle":"2024-08-07T09:38:58.788740Z","shell.execute_reply.started":"2024-08-07T09:24:43.951256Z","shell.execute_reply":"2024-08-07T09:38:58.787780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom tensorflow.keras import layers, models\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.model_selection import train_test_split\n\n# Set random seed for reproducibility\nnp.random.seed(42)\ntf.random.set_seed(42)\n\n# Define constants\nIMG_HEIGHT, IMG_WIDTH = 128, 128\nBATCH_SIZE = 32\nEPOCHS = 10\n\ndef create_model():\n    model = models.Sequential([\n        layers.Conv2D(32, (3, 3), activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),\n        layers.MaxPooling2D((2, 2)),\n        layers.Conv2D(64, (3, 3), activation='relu'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Conv2D(64, (3, 3), activation='relu'),\n        layers.Flatten(),\n        layers.Dense(64, activation='relu'),\n        layers.Dense(1, activation='sigmoid')\n    ])\n    \n    model.compile(optimizer='adam',\n                  loss='binary_crossentropy',\n                  metrics=['accuracy'])\n    return model\n\ndef load_data(data_dir):\n    fake_dir = os.path.join(data_dir, 'fake')\n    real_dir = os.path.join(data_dir, 'real')\n    \n    fake_files = [os.path.join(fake_dir, video, file) \n                  for video in os.listdir(fake_dir) \n                  for file in os.listdir(os.path.join(fake_dir, video))]\n    real_files = [os.path.join(real_dir, video, file) \n                  for video in os.listdir(real_dir) \n                  for file in os.listdir(os.path.join(real_dir, video))]\n    \n    all_files = fake_files + real_files\n    labels = ['fake'] * len(fake_files) + ['real'] * len(real_files)\n    \n    return train_test_split(all_files, labels, test_size=0.2, random_state=42)\n\ndef main():\n    # Load and prepare the data\n    data_dir = '/kaggle/working/processed_data'\n    train_files, val_files, train_labels, val_labels = load_data(data_dir)\n    \n    # Create dataframes\n    train_df = pd.DataFrame({'filename': train_files, 'class': train_labels})\n    val_df = pd.DataFrame({'filename': val_files, 'class': val_labels})\n    \n    # Create data generators\n    train_datagen = ImageDataGenerator(rescale=1./255)\n    val_datagen = ImageDataGenerator(rescale=1./255)\n    \n    train_generator = train_datagen.flow_from_dataframe(\n        dataframe=train_df,\n        x_col='filename',\n        y_col='class',\n        target_size=(IMG_HEIGHT, IMG_WIDTH),\n        batch_size=BATCH_SIZE,\n        class_mode='binary')\n    \n    val_generator = val_datagen.flow_from_dataframe(\n        dataframe=val_df,\n        x_col='filename',\n        y_col='class',\n        target_size=(IMG_HEIGHT, IMG_WIDTH),\n        batch_size=BATCH_SIZE,\n        class_mode='binary')\n    \n    # Create and train the model\n    model = create_model()\n    \n    history = model.fit(\n        train_generator,\n        steps_per_epoch=len(train_files) // BATCH_SIZE,\n        epochs=EPOCHS,\n        validation_data=val_generator,\n        validation_steps=len(val_files) // BATCH_SIZE\n    )\n    \n    # Evaluate the model\n    val_loss, val_accuracy = model.evaluate(val_generator)\n    print(f\"Validation accuracy: {val_accuracy:.4f}\")\n    \n    # Save the model\n    model.save('/kaggle/working/deepfake_detection_model.h5')\n    print(\"Model saved to /kaggle/working/deepfake_detection_model.h5\")\n\nif __name__ == \"__main__\":\n    main()","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:38:58.790736Z","iopub.execute_input":"2024-08-07T09:38:58.791172Z","iopub.status.idle":"2024-08-07T09:40:00.758327Z","shell.execute_reply.started":"2024-08-07T09:38:58.791018Z","shell.execute_reply":"2024-08-07T09:40:00.757428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow.keras.models import load_model\nfrom tensorflow.keras.preprocessing.image import img_to_array\n\nmodel = load_model('/kaggle/working/deepfake_detection_model.h5')\n\ndetector = FaceDetector()\n\ndef predict_video(video_path, frame_interval=25):\n    cap = cv2.VideoCapture(video_path)\n    frame_count = 0\n    predictions = []\n\n    while True:\n        ret, frame = cap.read()\n        if not ret:\n            break\n\n        if frame_count % frame_interval == 0:\n            boxes = detector.detect(frame)\n            \n            for box in boxes:\n                height, width = frame.shape[:2]\n                lx, ly, rx, ry = [int(coord * dim) for coord, dim in zip(box, [width, height, width, height])]\n                face = frame[ly:ry, lx:rx]\n                \n                face = cv2.resize(face, (128, 128))\n                face = img_to_array(face)\n                face = face.astype(\"float\") / 255.0\n                face = np.expand_dims(face, axis=0)\n                \n                prediction = model.predict(face)[0][0]\n                predictions.append(prediction)\n\n        frame_count += 1\n\n    cap.release()\n\n    # Aggregate predictions\n    if predictions:\n        print(predictions)\n        avg_prediction = np.mean(predictions)\n        if avg_prediction > 0.5:\n            return f\"The video is likely FAKE with {(avg_prediction):.2%} confidence.\"\n        else:\n            return f\"The video is likely REAL with {(1-avg_prediction):.2%} confidence.\"\n    else:\n        return \"No faces detected in the video.\"\n\n# Example usage\nvideo_path = '/kaggle/input/deepfake-detection-challenge/train_sample_videos/btjlfpzbdu.mp4'\nresult = predict_video(video_path)\nprint(result)","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:40:00.760377Z","iopub.execute_input":"2024-08-07T09:40:00.760777Z","iopub.status.idle":"2024-08-07T09:40:06.901548Z","shell.execute_reply.started":"2024-08-07T09:40:00.760707Z","shell.execute_reply":"2024-08-07T09:40:06.900517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"real_train_sample_video = list(meta_train_df.loc[meta_train_df.label=='REAL'].sample(10).index)\nreal_train_sample_video","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:40:06.903023Z","iopub.execute_input":"2024-08-07T09:40:06.903273Z","iopub.status.idle":"2024-08-07T09:40:06.911903Z","shell.execute_reply.started":"2024-08-07T09:40:06.903232Z","shell.execute_reply":"2024-08-07T09:40:06.910866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fake_train_sample_video = list(meta_train_df.loc[meta_train_df.label=='FAKE'].sample(10).index)\nfake_train_sample_video","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:40:06.913429Z","iopub.execute_input":"2024-08-07T09:40:06.913786Z","iopub.status.idle":"2024-08-07T09:40:06.925601Z","shell.execute_reply.started":"2024-08-07T09:40:06.913723Z","shell.execute_reply":"2024-08-07T09:40:06.924765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# The below is an established method to train a Neural Network for detecting deepfakes\n**I am using it to learn how to define the neural network and to get the dataset required for the neural network**","metadata":{"execution":{"iopub.status.busy":"2024-08-03T10:18:36.843284Z","iopub.execute_input":"2024-08-03T10:18:36.843650Z","iopub.status.idle":"2024-08-03T10:18:36.849564Z","shell.execute_reply.started":"2024-08-03T10:18:36.843586Z","shell.execute_reply":"2024-08-03T10:18:36.848487Z"}}},{"cell_type":"code","source":"!pip install ../input/mtcnn-package/mtcnn-0.1.0-py3-none-any.whl","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:40:06.926979Z","iopub.execute_input":"2024-08-07T09:40:06.927273Z","iopub.status.idle":"2024-08-07T09:40:15.135536Z","shell.execute_reply.started":"2024-08-07T09:40:06.927221Z","shell.execute_reply":"2024-08-07T09:40:15.134257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport keras\nimport os\nimport numpy as np\nfrom sklearn.metrics import log_loss\nfrom keras import Model,Sequential\nfrom keras.layers import *\nfrom keras.optimizers import *\nfrom sklearn.model_selection import train_test_split\nimport cv2\nfrom tqdm.notebook import tqdm\nimport glob\nfrom mtcnn import MTCNN","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:40:15.137523Z","iopub.execute_input":"2024-08-07T09:40:15.137870Z","iopub.status.idle":"2024-08-07T09:40:15.268547Z","shell.execute_reply.started":"2024-08-07T09:40:15.137814Z","shell.execute_reply":"2024-08-07T09:40:15.267714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sorted(glob.glob('../input/deepfake/meta*'))","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:40:15.269949Z","iopub.execute_input":"2024-08-07T09:40:15.270233Z","iopub.status.idle":"2024-08-07T09:40:15.327754Z","shell.execute_reply.started":"2024-08-07T09:40:15.270189Z","shell.execute_reply":"2024-08-07T09:40:15.326723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train0 = pd.read_json('../input/deepfake/metadata0.json')\ndf_train1 = pd.read_json('../input/deepfake/metadata1.json')\ndf_train2 = pd.read_json('../input/deepfake/metadata2.json')\ndf_train3 = pd.read_json('../input/deepfake/metadata3.json')\ndf_train4 = pd.read_json('../input/deepfake/metadata4.json')\ndf_train5 = pd.read_json('../input/deepfake/metadata5.json')\ndf_train6 = pd.read_json('../input/deepfake/metadata6.json')\ndf_train7 = pd.read_json('../input/deepfake/metadata7.json')\ndf_train8 = pd.read_json('../input/deepfake/metadata8.json')\ndf_train9 = pd.read_json('../input/deepfake/metadata9.json')\ndf_train10 = pd.read_json('../input/deepfake/metadata10.json')\ndf_train11 = pd.read_json('../input/deepfake/metadata11.json')\ndf_train12 = pd.read_json('../input/deepfake/metadata12.json')\ndf_train13 = pd.read_json('../input/deepfake/metadata13.json')\ndf_train14 = pd.read_json('../input/deepfake/metadata14.json')\ndf_train15 = pd.read_json('../input/deepfake/metadata15.json')\ndf_train16 = pd.read_json('../input/deepfake/metadata16.json')\ndf_train17 = pd.read_json('../input/deepfake/metadata17.json')\ndf_train18 = pd.read_json('../input/deepfake/metadata18.json')\ndf_train19 = pd.read_json('../input/deepfake/metadata19.json')\ndf_train20 = pd.read_json('../input/deepfake/metadata20.json')\ndf_train21 = pd.read_json('../input/deepfake/metadata21.json')\ndf_train22 = pd.read_json('../input/deepfake/metadata22.json')\ndf_train23 = pd.read_json('../input/deepfake/metadata23.json')\ndf_train24 = pd.read_json('../input/deepfake/metadata24.json')\ndf_train25 = pd.read_json('../input/deepfake/metadata25.json')\ndf_train26 = pd.read_json('../input/deepfake/metadata26.json')\ndf_train27 = pd.read_json('../input/deepfake/metadata27.json')\ndf_train28 = pd.read_json('../input/deepfake/metadata28.json')\ndf_train29 = pd.read_json('../input/deepfake/metadata29.json')\ndf_train30 = pd.read_json('../input/deepfake/metadata30.json')\ndf_train31 = pd.read_json('../input/deepfake/metadata31.json')\ndf_train32 = pd.read_json('../input/deepfake/metadata32.json')\ndf_train33 = pd.read_json('../input/deepfake/metadata33.json')\ndf_train34 = pd.read_json('../input/deepfake/metadata34.json')\ndf_train35 = pd.read_json('../input/deepfake/metadata35.json')\ndf_train36 = pd.read_json('../input/deepfake/metadata36.json')\ndf_train37 = pd.read_json('../input/deepfake/metadata37.json')\ndf_train38 = pd.read_json('../input/deepfake/metadata38.json')\ndf_train39 = pd.read_json('../input/deepfake/metadata39.json')\ndf_train40 = pd.read_json('../input/deepfake/metadata40.json')\ndf_train41 = pd.read_json('../input/deepfake/metadata41.json')\ndf_train42 = pd.read_json('../input/deepfake/metadata42.json')\ndf_train43 = pd.read_json('../input/deepfake/metadata43.json')\ndf_train44 = pd.read_json('../input/deepfake/metadata44.json')\ndf_train45 = pd.read_json('../input/deepfake/metadata45.json')\ndf_train46 = pd.read_json('../input/deepfake/metadata46.json')\ndf_val1 = pd.read_json('../input/deepfake/metadata47.json')\ndf_val2 = pd.read_json('../input/deepfake/metadata48.json')\ndf_val3 = pd.read_json('../input/deepfake/metadata49.json')\ndf_trains = [df_train0 ,df_train1, df_train2, df_train3, df_train4,\n             df_train5, df_train6, df_train7, df_train8, df_train9,df_train10,\n            df_train11, df_train12, df_train13, df_train14, df_train15,df_train16, \n            df_train17, df_train18, df_train19, df_train20, df_train21, df_train22, \n            df_train23, df_train24, df_train25, df_train26, df_train27, df_train28, \n            df_train29, df_train30, df_train31, df_train32, df_train33, df_train34,\n            df_train34, df_train35, df_train36, df_train37, df_train38, df_train39,\n            df_train40, df_train41, df_train42, df_train43, df_train44, df_train45,\n            df_train46]\ndf_vals=[df_val1, df_val2, df_val3]\nnums = list(range(len(df_trains)+1))\nLABELS = ['REAL','FAKE']\nval_nums=[47, 48, 49]","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:40:15.329179Z","iopub.execute_input":"2024-08-07T09:40:15.329469Z","iopub.status.idle":"2024-08-07T09:41:05.739022Z","shell.execute_reply.started":"2024-08-07T09:40:15.329424Z","shell.execute_reply":"2024-08-07T09:41:05.738140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_path(num,x):\n    num=str(num)\n    if len(num)==2:\n        path='../input/deepfake/DeepFake'+num+'/DeepFake'+num+'/' + x.replace('.mp4', '') + '.jpg'\n    else:\n        path='../input/deepfake/DeepFake0'+num+'/DeepFake0'+num+'/' + x.replace('.mp4', '') + '.jpg'\n    if not os.path.exists(path):\n       raise Exception\n    return path\npaths=[]\ny=[]\nfor df_train,num in tqdm(zip(df_trains,nums),total=len(df_trains)):\n    images = list(df_train.columns.values)\n    for x in images:\n        try:\n            paths.append(get_path(num,x))\n            y.append(LABELS.index(df_train[x]['label']))\n        except Exception as err:\n            #print(err)\n            pass\n\nval_paths=[]\nval_y=[]\nfor df_val,num in tqdm(zip(df_vals,val_nums),total=len(df_vals)):\n    images = list(df_val.columns.values)\n    for x in images:\n        try:\n            val_paths.append(get_path(num,x))\n            val_y.append(LABELS.index(df_val[x]['label']))\n        except Exception as err:\n            #print(err)\n            pass","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:41:05.740551Z","iopub.execute_input":"2024-08-07T09:41:05.740862Z","iopub.status.idle":"2024-08-07T09:46:33.189708Z","shell.execute_reply.started":"2024-08-07T09:41:05.740811Z","shell.execute_reply":"2024-08-07T09:46:33.188675Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('There are '+str(y.count(1))+' fake train samples')\nprint('There are '+str(y.count(0))+' real train samples')\nprint('There are '+str(val_y.count(1))+' fake val samples')\nprint('There are '+str(val_y.count(0))+' real val samples')","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:46:33.191428Z","iopub.execute_input":"2024-08-07T09:46:33.191740Z","iopub.status.idle":"2024-08-07T09:46:33.199973Z","shell.execute_reply.started":"2024-08-07T09:46:33.191682Z","shell.execute_reply":"2024-08-07T09:46:33.199156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\nreal=[]\nfake=[]\nfor m,n in zip(paths,y):\n    if n==0:\n        real.append(m)\n    else:\n        fake.append(m)\nfake=random.sample(fake,len(real))\npaths,y=[],[]\nfor x in real:\n    paths.append(x)\n    y.append(0)\nfor x in fake:\n    paths.append(x)\n    y.append(1)","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:46:33.201233Z","iopub.execute_input":"2024-08-07T09:46:33.201497Z","iopub.status.idle":"2024-08-07T09:46:33.267534Z","shell.execute_reply.started":"2024-08-07T09:46:33.201450Z","shell.execute_reply":"2024-08-07T09:46:33.266768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"real=[]\nfake=[]\nfor m,n in zip(val_paths,val_y):\n    if n==0:\n        real.append(m)\n    else:\n        fake.append(m)\nfake=random.sample(fake,len(real))\nval_paths,val_y=[],[]\nfor x in real:\n    val_paths.append(x)\n    val_y.append(0)\nfor x in fake:\n    val_paths.append(x)\n    val_y.append(1)","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:46:33.269063Z","iopub.execute_input":"2024-08-07T09:46:33.269329Z","iopub.status.idle":"2024-08-07T09:46:33.282718Z","shell.execute_reply.started":"2024-08-07T09:46:33.269287Z","shell.execute_reply":"2024-08-07T09:46:33.281904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('There are '+str(y.count(1))+' fake train samples')\nprint('There are '+str(y.count(0))+' real train samples')\nprint('There are '+str(val_y.count(1))+' fake val samples')\nprint('There are '+str(val_y.count(0))+' real val samples')","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:46:33.284355Z","iopub.execute_input":"2024-08-07T09:46:33.284674Z","iopub.status.idle":"2024-08-07T09:46:33.295831Z","shell.execute_reply.started":"2024-08-07T09:46:33.284575Z","shell.execute_reply":"2024-08-07T09:46:33.294599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_img(path):\n    return cv2.cvtColor(cv2.imread(path),cv2.COLOR_BGR2RGB)\nX=[]\nfor img in tqdm(paths):\n    X.append(read_img(img))\nval_X=[]\nfor img in tqdm(val_paths):\n    val_X.append(read_img(img))","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:46:33.297074Z","iopub.execute_input":"2024-08-07T09:46:33.297320Z","iopub.status.idle":"2024-08-07T09:49:53.951130Z","shell.execute_reply.started":"2024-08-07T09:46:33.297272Z","shell.execute_reply":"2024-08-07T09:49:53.950125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\ndef shuffle(X,y):\n    new_train=[]\n    for m,n in zip(X,y):\n        new_train.append([m,n])\n    random.shuffle(new_train)\n    X,y=[],[]\n    for x in new_train:\n        X.append(x[0])\n        y.append(x[1])\n    return X,y","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:49:53.952718Z","iopub.execute_input":"2024-08-07T09:49:53.953012Z","iopub.status.idle":"2024-08-07T09:49:53.960453Z","shell.execute_reply.started":"2024-08-07T09:49:53.952960Z","shell.execute_reply":"2024-08-07T09:49:53.959506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X,y=shuffle(X,y)\nval_X,val_y=shuffle(val_X,val_y)\ntf.compat.v1.disable_eager_execution()","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:49:53.962149Z","iopub.execute_input":"2024-08-07T09:49:53.962444Z","iopub.status.idle":"2024-08-07T09:49:54.052329Z","shell.execute_reply.started":"2024-08-07T09:49:53.962382Z","shell.execute_reply":"2024-08-07T09:49:54.051290Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.layers import Input, Conv2D, BatchNormalization, MaxPooling2D, Flatten, Dropout, Dense, LeakyReLU, Concatenate\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import LearningRateScheduler\nfrom sklearn.metrics import log_loss\nimport gc\n\ndef InceptionLayer(a, b, c, d):\n    def func(x):\n        x1 = Conv2D(a, (1, 1), padding='same', activation='elu')(x)\n        \n        x2 = Conv2D(b, (1, 1), padding='same', activation='elu')(x)\n        x2 = Conv2D(b, (3, 3), padding='same', activation='elu')(x2)\n            \n        x3 = Conv2D(c, (1, 1), padding='same', activation='elu')(x)\n        x3 = Conv2D(c, (3, 3), dilation_rate = 2, strides = 1, padding='same', activation='elu')(x3)\n        \n        x4 = Conv2D(d, (1, 1), padding='same', activation='elu')(x)\n        x4 = Conv2D(d, (3, 3), dilation_rate = 3, strides = 1, padding='same', activation='elu')(x4)\n        y = Concatenate(axis = -1)([x1, x2, x3, x4])\n            \n        return y\n    return func\n    \ndef define_model(shape=(256,256,3)):\n    x = Input(shape = shape)\n    \n    x1 = InceptionLayer(1, 4, 4, 2)(x)\n    x1 = BatchNormalization()(x1)\n    x1 = MaxPooling2D(pool_size=(2, 2), padding='same')(x1)\n    \n    x2 = InceptionLayer(2, 4, 4, 2)(x1)\n    x2 = BatchNormalization()(x2)        \n    x2 = MaxPooling2D(pool_size=(2, 2), padding='same')(x2)        \n        \n    x3 = Conv2D(16, (5, 5), padding='same', activation = 'elu')(x2)\n    x3 = BatchNormalization()(x3)\n    x3 = MaxPooling2D(pool_size=(2, 2), padding='same')(x3)\n        \n    x4 = Conv2D(16, (5, 5), padding='same', activation = 'elu')(x3)\n    x4 = BatchNormalization()(x4)\n    if shape==(256,256,3):\n        x4 = MaxPooling2D(pool_size=(4, 4), padding='same')(x4)\n    else:\n        x4 = MaxPooling2D(pool_size=(2, 2), padding='same')(x4)\n    y = Flatten()(x4)\n    y = Dropout(0.5)(y)\n    y = Dense(16)(y)\n    y = LeakyReLU(alpha=0.1)(y)\n    y = Dropout(0.5)(y)\n    y = Dense(1, activation = 'sigmoid')(y)\n    model=Model(inputs = x, outputs = y)\n    model.compile(loss='binary_crossentropy',optimizer=Adam(lr=1e-4))\n    #model.summary()\n    return model\ndf_model=define_model()\ndf_model.load_weights('../input/meso-pretrain/MesoInception_DF')\nf2f_model=define_model()\nf2f_model.load_weights('../input/meso-pretrain/MesoInception_F2F')","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:49:54.053951Z","iopub.execute_input":"2024-08-07T09:49:54.054251Z","iopub.status.idle":"2024-08-07T09:49:59.038356Z","shell.execute_reply.started":"2024-08-07T09:49:54.054195Z","shell.execute_reply":"2024-08-07T09:49:59.037252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.callbacks import LearningRateScheduler\nlrs=[1e-3,5e-4,1e-4]\ndef schedule(epoch):\n    return lrs[epoch]","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:49:59.040121Z","iopub.execute_input":"2024-08-07T09:49:59.040425Z","iopub.status.idle":"2024-08-07T09:49:59.045718Z","shell.execute_reply.started":"2024-08-07T09:49:59.040373Z","shell.execute_reply":"2024-08-07T09:49:59.044836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LOAD_PRETRAIN=True","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-08-07T09:49:59.047306Z","iopub.execute_input":"2024-08-07T09:49:59.047738Z","iopub.status.idle":"2024-08-07T09:49:59.058305Z","shell.execute_reply.started":"2024-08-07T09:49:59.047632Z","shell.execute_reply":"2024-08-07T09:49:59.057164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import gc\n# kfolds=5\n# losses=[]\n# if LOAD_PRETRAIN:\n#     # import keras.backend as K\n#     df_models=[]\n#     f2f_models=[]\n#     i=0\n#     while len(df_models)<kfolds:\n#         model=define_model((150,150,3))\n#         if i==0:\n#             model.summary()\n#         #model.load_weights('../input/meso-pretrain/MesoInception_DF')\n#         for new_layer, layer in zip(model.layers[1:-8], df_model.layers[1:-8]):\n#             new_layer.set_weights(layer.get_weights())\n#         model.fit([X],[y],epochs=2,callbacks=[LearningRateScheduler(schedule)])\n#         pred=model.predict([val_X])\n#         loss=log_loss(val_y,pred)\n#         losses.append(loss)\n#         print('fold '+str(i)+' model loss: '+str(loss))\n#         df_models.append(model)\n#         K.clear_session()\n#         del model\n#         gc.collect()\n#         i+=1\n#     i=0\n#     while len(f2f_models)<kfolds:\n#         model=define_model((150,150,3))\n#         #model.load_weights('../input/meso-pretrain/MesoInception_DF')\n#         for new_layer, layer in zip(model.layers[1:-8], f2f_model.layers[1:-8]):\n#             new_layer.set_weights(layer.get_weights())\n#         model.fit([X],[y],epochs=2,callbacks=[LearningRateScheduler(schedule)])\n#         pred=model.predict([val_X])\n#         loss=log_loss(val_y,pred)\n#         losses.append(loss)\n#         print('fold '+str(i)+' model loss: '+str(loss))\n#         f2f_models.append(model)\n#         K.clear_session()\n#         del model\n#         gc.collect()\n#         i+=1\n#         models=f2f_models+df_models\n# else:\n#     models=[]\n#     i=0\n#     while len(models)<kfolds:\n#         model=define_model((150,150,3))\n#         if i==0:\n#             model.summary()\n#         model.fit([X],[y],epochs=2,callbacks=[LearningRateScheduler(schedule)])\n#         pred=model.predict([val_X])\n#         loss=log_loss(val_y,pred)\n#         losses.append(loss)\n#         print('fold '+str(i)+' model loss: '+str(loss))\n#         if loss<0.68:\n#             models.append(model)\n#         else:\n#             print('loss too bad, retrain!')\n#         K.clear_session()\n#         del model\n#         gc.collect()\n#         i+=1","metadata":{"execution":{"iopub.status.busy":"2024-08-07T09:49:59.059793Z","iopub.execute_input":"2024-08-07T09:49:59.060186Z","iopub.status.idle":"2024-08-07T09:49:59.070100Z","shell.execute_reply.started":"2024-08-07T09:49:59.060120Z","shell.execute_reply":"2024-08-07T09:49:59.069018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Couldn't get the established method to work but understood somewhat the kind of neural network that is required***","metadata":{}}]}