{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":16880,"databundleVersionId":858837,"sourceType":"competition"}],"dockerImageVersionId":29844,"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\nfor 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-09-09T19:22:24.038401Z","iopub.execute_input":"2024-09-09T19:22:24.038676Z","iopub.status.idle":"2024-09-09T19:22:24.1339Z","shell.execute_reply.started":"2024-09-09T19:22:24.038621Z","shell.execute_reply":"2024-09-09T19:22:24.133135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install tensorflow","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:22:35.844433Z","iopub.execute_input":"2024-09-09T19:22:35.844737Z","iopub.status.idle":"2024-09-09T19:22:44.202745Z","shell.execute_reply.started":"2024-09-09T19:22:35.844693Z","shell.execute_reply":"2024-09-09T19:22:44.201888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow import keras\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport pandas as pd\nimport numpy as np\nimport imageio\nimport cv2\nimport os","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:23:12.346016Z","iopub.execute_input":"2024-09-09T19:23:12.346365Z","iopub.status.idle":"2024-09-09T19:23:12.351252Z","shell.execute_reply.started":"2024-09-09T19:23:12.346305Z","shell.execute_reply":"2024-09-09T19:23:12.350374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_FOLDER='../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\"Train samples:{len(os.listdir(os.path.join(DATA_FOLDER,TEST_FOLDER)))}\")","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:23:13.620132Z","iopub.execute_input":"2024-09-09T19:23:13.62043Z","iopub.status.idle":"2024-09-09T19:23:13.628452Z","shell.execute_reply.started":"2024-09-09T19:23:13.620385Z","shell.execute_reply":"2024-09-09T19:23:13.627538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_sample_metadata=pd.read_json('../input/deepfake-detection-challenge/train_sample_videos/metadata.json').T\ntrain_sample_metadata.head(5)","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:23:16.220515Z","iopub.execute_input":"2024-09-09T19:23:16.22086Z","iopub.status.idle":"2024-09-09T19:23:16.582662Z","shell.execute_reply.started":"2024-09-09T19:23:16.220808Z","shell.execute_reply":"2024-09-09T19:23:16.581703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_sample_metadata.groupby('label')['label'].count().plot(kind='bar')","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:23:19.416173Z","iopub.execute_input":"2024-09-09T19:23:19.416491Z","iopub.status.idle":"2024-09-09T19:23:19.756659Z","shell.execute_reply.started":"2024-09-09T19:23:19.416444Z","shell.execute_reply":"2024-09-09T19:23:19.755598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fake_train_sample_video=list(train_sample_metadata.loc[train_sample_metadata.label=='FAKE'].sample(10).index)\nfake_train_sample_video","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:23:21.628434Z","iopub.execute_input":"2024-09-09T19:23:21.628761Z","iopub.status.idle":"2024-09-09T19:23:21.638234Z","shell.execute_reply.started":"2024-09-09T19:23:21.628711Z","shell.execute_reply":"2024-09-09T19:23:21.637503Z"},"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 = cv2.VideoCapture(video_path) \n    ret, frame = capture_image.read()\n    fig = plt.figure(figsize=(10,10))\n    ax = fig.add_subplot(111)\n    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)\n    ax.imshow(frame)","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:23:23.906253Z","iopub.execute_input":"2024-09-09T19:23:23.906547Z","iopub.status.idle":"2024-09-09T19:23:23.913328Z","shell.execute_reply.started":"2024-09-09T19:23:23.906502Z","shell.execute_reply":"2024-09-09T19:23:23.912481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for video_file in fake_train_sample_video:\n    display_image_from_video(os.path.join(DATA_FOLDER, TRAIN_SAMPLE_FOLDER, video_file))","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:23:30.036945Z","iopub.execute_input":"2024-09-09T19:23:30.037282Z","iopub.status.idle":"2024-09-09T19:23:36.200687Z","shell.execute_reply.started":"2024-09-09T19:23:30.037225Z","shell.execute_reply":"2024-09-09T19:23:36.19997Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"real_train_sample_video = list(train_sample_metadata.loc[train_sample_metadata.label=='REAL'].sample(3).index)\nreal_train_sample_video","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:23:51.17834Z","iopub.execute_input":"2024-09-09T19:23:51.178688Z","iopub.status.idle":"2024-09-09T19:23:51.186659Z","shell.execute_reply.started":"2024-09-09T19:23:51.17863Z","shell.execute_reply":"2024-09-09T19:23:51.185747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for video_file in real_train_sample_video:\n    display_image_from_video(os.path.join(DATA_FOLDER, TRAIN_SAMPLE_FOLDER, video_file))","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:23:53.43821Z","iopub.execute_input":"2024-09-09T19:23:53.438512Z","iopub.status.idle":"2024-09-09T19:23:55.101142Z","shell.execute_reply.started":"2024-09-09T19:23:53.438466Z","shell.execute_reply":"2024-09-09T19:23:55.100338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_image_from_video_list(video_path_list, video_folder=TRAIN_SAMPLE_FOLDER):\n    '''\n    input: video_path_list - path for video\n    process:\n    0. for each video in the video path list\n        1. perform a video capture from the video\n        2. read the image\n        3. display the image\n    '''\n    plt.figure()\n    fig, ax = plt.subplots(2,3,figsize=(16,8))\n    # we only show images extracted from the first 6 videos\n    for i, video_file in enumerate(video_path_list[0:6]):\n        video_path = os.path.join(DATA_FOLDER, video_folder,video_file)\n        capture_image = cv2.VideoCapture(video_path) \n        ret, frame = capture_image.read()\n        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)\n        ax[i//3, i%3].imshow(frame)\n        ax[i//3, i%3].set_title(f\"Video: {video_file}\")\n        ax[i//3, i%3].axis('on')","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:24:20.972279Z","iopub.execute_input":"2024-09-09T19:24:20.972581Z","iopub.status.idle":"2024-09-09T19:24:20.981748Z","shell.execute_reply.started":"2024-09-09T19:24:20.972536Z","shell.execute_reply":"2024-09-09T19:24:20.980744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nsame_original_fake_train_sample_video = list(train_sample_metadata.loc[train_sample_metadata.original=='meawmsgiti.mp4'].index)\ndisplay_image_from_video_list(same_original_fake_train_sample_video)","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:24:23.437638Z","iopub.execute_input":"2024-09-09T19:24:23.437988Z","iopub.status.idle":"2024-09-09T19:24:25.15358Z","shell.execute_reply.started":"2024-09-09T19:24:23.437926Z","shell.execute_reply":"2024-09-09T19:24:25.152896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_videos = pd.DataFrame(list(os.listdir(os.path.join(DATA_FOLDER, TEST_FOLDER))), columns=['video'])","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:24:29.306779Z","iopub.execute_input":"2024-09-09T19:24:29.307075Z","iopub.status.idle":"2024-09-09T19:24:29.314333Z","shell.execute_reply.started":"2024-09-09T19:24:29.307032Z","shell.execute_reply":"2024-09-09T19:24:29.313469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_videos.head()","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:24:31.445097Z","iopub.execute_input":"2024-09-09T19:24:31.445392Z","iopub.status.idle":"2024-09-09T19:24:31.453534Z","shell.execute_reply.started":"2024-09-09T19:24:31.445345Z","shell.execute_reply":"2024-09-09T19:24:31.452813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_image_from_video(os.path.join(DATA_FOLDER,TEST_FOLDER,test_videos.iloc[2].video))","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:24:33.683313Z","iopub.execute_input":"2024-09-09T19:24:33.68371Z","iopub.status.idle":"2024-09-09T19:24:34.128662Z","shell.execute_reply.started":"2024-09-09T19:24:33.683645Z","shell.execute_reply":"2024-09-09T19:24:34.127852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fake_videos = list(train_sample_metadata.loc[train_sample_metadata.label=='FAKE'].index)","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:24:39.442522Z","iopub.execute_input":"2024-09-09T19:24:39.442844Z","iopub.status.idle":"2024-09-09T19:24:39.448607Z","shell.execute_reply.started":"2024-09-09T19:24:39.442801Z","shell.execute_reply":"2024-09-09T19:24:39.447722Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython.display import HTML\nfrom base64 import b64encode\n\ndef play_video(video_file, subset=TRAIN_SAMPLE_FOLDER):\n    '''\n    Display video\n    param: video_file - the name of the video file to display\n    param: subset - the folder where the video file is located (can be TRAIN_SAMPLE_FOLDER or TEST_Folder)\n    '''\n    video_url = open(os.path.join(DATA_FOLDER, subset,video_file),'rb').read()\n    data_url = \"data:video/mp4;base64,\" + b64encode(video_url).decode()\n    return HTML(\"\"\"<video width=500 controls><source src=\"%s\" type=\"video/mp4\"></video>\"\"\" % data_url)","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:24:40.679427Z","iopub.execute_input":"2024-09-09T19:24:40.679793Z","iopub.status.idle":"2024-09-09T19:24:40.686363Z","shell.execute_reply.started":"2024-09-09T19:24:40.679732Z","shell.execute_reply":"2024-09-09T19:24:40.685687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"play_video(fake_videos[0])","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:24:43.24266Z","iopub.execute_input":"2024-09-09T19:24:43.242998Z","iopub.status.idle":"2024-09-09T19:24:43.60643Z","shell.execute_reply.started":"2024-09-09T19:24:43.242938Z","shell.execute_reply":"2024-09-09T19:24:43.605081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#making a cnn-rnn architecture\n\nIMG_SIZE=224\nBATCH_SIZE=32\nEPOCHS=10\n\nMAX_SEQ_LENGTH=20\nNUM_FEATURES=2048\n","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:25:09.866745Z","iopub.execute_input":"2024-09-09T19:25:09.867051Z","iopub.status.idle":"2024-09-09T19:25:09.871487Z","shell.execute_reply.started":"2024-09-09T19:25:09.866995Z","shell.execute_reply":"2024-09-09T19:25:09.870552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#capture the frames of video, extracting the frames \ndef crop_center_square(frame):\n    y, x = frame.shape[0:2]\n    min_dim = min(y, x)\n    start_x = (x // 2) - (min_dim // 2)\n    start_y = (y // 2) - (min_dim // 2)\n    return frame[start_y:start_y + min_dim, start_x:start_x + min_dim]\n\ndef load_video(path, max_frames=0, resize=(IMG_SIZE, IMG_SIZE)):\n    cap = cv2.VideoCapture(path)\n    frames = []\n    try:\n        while True:\n            ret, frame = cap.read()\n            if not ret:\n                break\n            frame = crop_center_square(frame)\n            frame = cv2.resize(frame, resize)\n            frame = frame[:, :, [2, 1, 0]]\n            frames.append(frame)\n\n            if len(frames) == max_frames:\n                break\n    finally:\n        cap.release()\n    return np.array(frames)\n","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:25:13.754246Z","iopub.execute_input":"2024-09-09T19:25:13.754548Z","iopub.status.idle":"2024-09-09T19:25:13.764888Z","shell.execute_reply.started":"2024-09-09T19:25:13.754502Z","shell.execute_reply":"2024-09-09T19:25:13.764077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def build_feature_extractor():\n    feature_extractor = keras.applications.InceptionV3(\n        weights=\"imagenet\",\n        include_top=False,\n        pooling=\"avg\",\n        input_shape=(IMG_SIZE, IMG_SIZE, 3)\n    )\n\n    preprocess_input = keras.applications.inception_v3.preprocess_input\n\n    inputs = keras.Input((IMG_SIZE, IMG_SIZE, 3))\n    preprocessed = preprocess_input(inputs)\n\n    outputs = feature_extractor(preprocessed)\n    return keras.Model(inputs, outputs, name=\"feature_extractor\")\nfeature_extractor=build_feature_extractor()","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:25:18.506366Z","iopub.execute_input":"2024-09-09T19:25:18.506682Z","iopub.status.idle":"2024-09-09T19:25:29.911085Z","shell.execute_reply.started":"2024-09-09T19:25:18.506635Z","shell.execute_reply":"2024-09-09T19:25:29.910303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" def prepare_all_videos(df, root_dir):\n    num_samples = len(df)\n    video_paths = list(df.index)\n    labels = df[\"label\"].values\n    labels = np.array(labels == \"FAKE\").astype(np.int)\n\n    # 'frame_masks' and 'frame_features' are what we will feed to our sequence model.\n    # 'frame_masks' will contain a bunch of booleans denoting if a timestep is masked with padding or not.\n    frame_masks = np.zeros(shape=(num_samples, MAX_SEQ_LENGTH), dtype=\"bool\")\n    frame_features = np.zeros(\n        shape=(num_samples, MAX_SEQ_LENGTH, NUM_FEATURES), dtype=\"float32\"\n    )\n\n    # For each video.\n    for idx, path in enumerate(video_paths):\n        # Gather all its frames and add a batch dimension.\n        frames = load_video(os.path.join(root_dir, path))\n        frames = frames[None, ...]\n\n        # Initialize placeholders to store the masks and features of the current video.\n        temp_frame_mask = np.zeros(shape=(1, MAX_SEQ_LENGTH), dtype=\"bool\")\n        temp_frame_features = np.zeros(\n            shape=(1, MAX_SEQ_LENGTH, NUM_FEATURES), dtype=\"float32\"\n        )\n        \n    # Extract features from the frames of the current video.\n        for i, batch in enumerate(frames):\n            video_length = batch.shape[0]\n            length = min(MAX_SEQ_LENGTH, video_length)\n            for j in range(length):\n                temp_frame_features[i, j, :] = feature_extractor.predict(\n                    batch[None, j, :]\n                )\n            temp_frame_mask[i, :length] = 1  # 1 = not masked, 0 = masked\n\n        frame_features[idx,] = temp_frame_features.squeeze()\n        frame_masks[idx,] = temp_frame_mask.squeeze()\n\n    return (frame_features, frame_masks), labels\n        \n","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:25:32.196466Z","iopub.execute_input":"2024-09-09T19:25:32.196801Z","iopub.status.idle":"2024-09-09T19:25:32.210171Z","shell.execute_reply.started":"2024-09-09T19:25:32.196744Z","shell.execute_reply":"2024-09-09T19:25:32.208781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nTrain_set,Test_set=train_test_split(train_sample_metadata,test_size=0.2,random_state=42,stratify=train_sample_metadata['label'])","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:26:22.285446Z","iopub.execute_input":"2024-09-09T19:26:22.285856Z","iopub.status.idle":"2024-09-09T19:26:22.2948Z","shell.execute_reply.started":"2024-09-09T19:26:22.285775Z","shell.execute_reply":"2024-09-09T19:26:22.29374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(Train_set.shape,Test_set.shape)","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:26:25.441132Z","iopub.execute_input":"2024-09-09T19:26:25.441521Z","iopub.status.idle":"2024-09-09T19:26:25.445994Z","shell.execute_reply.started":"2024-09-09T19:26:25.441457Z","shell.execute_reply":"2024-09-09T19:26:25.445202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data,train_labels=prepare_all_videos(Train_set,'train')\ntest_data,test_labels=prepare_all_videos(Test_set,'test')\n\nprint(train_data[0].shape)\nprint(train_data[1].shape)","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:26:28.230725Z","iopub.execute_input":"2024-09-09T19:26:28.231058Z","iopub.status.idle":"2024-09-09T19:26:28.309315Z","shell.execute_reply.started":"2024-09-09T19:26:28.231Z","shell.execute_reply":"2024-09-09T19:26:28.30831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"frame_features_input = keras.Input((MAX_SEQ_LENGTH, NUM_FEATURES))\nmask_input = keras.Input((MAX_SEQ_LENGTH,), dtype=\"bool\")\nx = keras.layers.GRU(64, return_sequences=True)(frame_features_input, mask=mask_input)\nx = keras.layers.BatchNormalization()(x)\nx = keras.layers.GRU(32, return_sequences=True)(x)\nx = keras.layers.BatchNormalization()(x)\nx = keras.layers.GRU(16)(x)\nx = keras.layers.Dropout(0.5)(x)  # Increased dropout\nx = keras.layers.Dense(32, activation=\"relu\")(x)\nx = keras.layers.Dropout(0.5)(x)  # Added another dropout layer\noutput = keras.layers.Dense(1, activation=\"sigmoid\")(x)\n\nmodel = keras.Model([frame_features_input, mask_input], output)\n\n# Use a lower learning rate and different optimizer\noptimizer = keras.optimizers.Adam(learning_rate=1e-4)\n\nmodel.compile(loss=\"binary_crossentropy\", optimizer=optimizer, metrics=[\"accuracy\"])\nmodel.summary()\n\n# Include Early Stopping to prevent overfitting\nearly_stopping = keras.callbacks.EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\ncheckpoint = keras.callbacks.ModelCheckpoint('./', save_weights_only=True, save_best_only=True)\n\nhistory = model.fit(\n    [train_data[0], train_data[1]],\n    train_labels,\n    validation_data=([test_data[0], test_data[1]], test_labels),\n    callbacks=[checkpoint, early_stopping],\n    epochs=EPOCHS,\n    batch_size=32\n)","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:29:23.094647Z","iopub.execute_input":"2024-09-09T19:29:23.095119Z","iopub.status.idle":"2024-09-09T19:29:29.823659Z","shell.execute_reply.started":"2024-09-09T19:29:23.094908Z","shell.execute_reply":"2024-09-09T19:29:29.822517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#this part is to check the video [either 'REAL' or 'FAKE']\ndef prepare_single_video(frames):\n    frames = frames[None, ...]\n    frame_mask = np.zeros(shape=(1, MAX_SEQ_LENGTH,), dtype=\"bool\")\n    frame_features = np.zeros(shape=(1, MAX_SEQ_LENGTH, NUM_FEATURES), dtype=\"float32\")\n\n    for i, batch in enumerate(frames):\n        video_length = batch.shape[0]\n        length = min(MAX_SEQ_LENGTH, video_length)\n        for j in range(length):\n            frame_features[i, j, :] = feature_extractor.predict(batch[None, j, :])\n        frame_mask[i, :length] = 1  # 1 = not masked, 0 = masked\n\n    return frame_features, frame_mask\n\ndef sequence_prediction(path):\n    frames = load_video(os.path.join(DATA_FOLDER, TEST_FOLDER, path))\n    frame_features, frame_mask = prepare_single_video(frames)\n    return model.predict([frame_features, frame_mask])[0]\ndef to_gif(images):\n    converted_images = images.astype(np.uint8)\n    imageio.mimsave(\"animation.gif\", converted_images, fps=10)\n    return embed.embed_file(\"animation.gif\")\n\ntest_video = np.random.choice(test_videos[\"video\"].values.tolist())\nprint(f\"Test video path: {test_video}\")\n\nif(sequence_prediction(test_video)>=0.5):\n    print(f'The predicted class of the video is FAKE')\nelse:\n    print(f'The predicted class of the video is REAL')\n\nplay_video(test_video,TEST_FOLDER)","metadata":{"execution":{"iopub.status.busy":"2024-09-09T19:30:40.157755Z","iopub.execute_input":"2024-09-09T19:30:40.158091Z","iopub.status.idle":"2024-09-09T19:30:44.196552Z","shell.execute_reply.started":"2024-09-09T19:30:40.158039Z","shell.execute_reply":"2024-09-09T19:30:44.194882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}