<jupyter_start><jupyter_text>Inference notebook for DFDC Short notebook to run inference on Deep Fake Detection Challenge test set in submission ImportsSeperated in blocks:- Python imports- Pytorch/torchvision imports- User imports**** Note: As well as our user submitted code, we are rllying on [facenet-pytorch](https://github.com/timesler/facenet-pytorch) for the preprocessing stage to isolate people's faces<jupyter_code>%load_ext autoreload
%autoreload 2
import os
import sys
import pandas as pd
import numpy as np
import yaml
from tqdm import tqdm

import torch
from torch.utils.data import DataLoader
from torchvision import transforms

sys.path.insert(1, '../')
import dfdet as dfd
from facenet_pytorch import MTCNN<jupyter_output>The autoreload extension is already loaded. To reload it, use:
  %reload_ext autoreload<jupyter_text>ConfigSet the device for processing (should be gpu for this analysis) and whether or not to run the preprocessing stage.  This second switch is mostly there for debugging the second stage after preprocessing<jupyter_code>device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
preprocess = True<jupyter_output><empty_output><jupyter_text>Index dataIndex the test data and return it in data-frame compatible with our defined data-sets<jupyter_code>test_path = '../deepfake-detection'
def index_test_dir(test_path=''):
    ''' Index files and create data frame
    Parameters
    ----------
    test_path : str
        Path to directory with test files
    Returns
    -------
    df : pd.DataFrame
        DataFrame for preprocessing
    '''
    path, dirs, files = next(os.walk('{}/test_videos'.format(test_path)))
    df = pd.DataFrame(files, columns=['File'])
    df['split'] = 'test_videos'
    df['label'] = -1
    return df<jupyter_output><empty_output><jupyter_text>PreprocessingPreprocessing stage.  Feed to the files to face-net pytorch to isolate faces and save the desired frames to a local directory "temp"<jupyter_code>if preprocess:
    df = index_test_dir(test_path)
    with open('../config_files/preprocess.yaml') as f:
        config = yaml.load(f)
    mt = config['mtcnn']
    mtcnn = MTCNN(
        image_size=mt['image_size'], margin=mt['margin'],
        min_face_size=mt['min_face_size'], thresholds=mt['thresholds'],
        factor=mt['factor'], post_process=mt['post_process'],
        device=device
    )
    faces_df = dfd.preprocess_df(df=df, mtcnn=mtcnn, path=test_path, 
                                 outpath='./temp', n_seconds=6, debug=False)
    faces_df.to_csv('./temp/faces_metadata.csv')
    del mtcnn, df
else:
    faces_df = pd.read_csv('./temp/faces_metadata.csv')<jupyter_output><empty_output><jupyter_text>Re-indexingRe-index the dataframe to allow the DataLoader to reference the file names.  Not needed but added safegaurd for correct submission<jupyter_code>faces_df['label'] = faces_df.index<jupyter_output><empty_output><jupyter_text>Deep Fake DetectorCreate deep fake detector model and load the pre-trained weights<jupyter_code>model = dfd.ConvLSTM(num_classes=1, attention=True, encoder='ResNet').to(device)
chpt = torch.load('../checkpoints/best_model.pth.tar')
model.load_state_dict(chpt['model'])
print(chpt['description'])<jupyter_output>best model loss: 0.3598859710824972<jupyter_text>DataCreate dataset and dataloader using the correct transformations for input to the model<jupyter_code>transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406],
                         std=[0.229, 0.224, 0.225])
])
batch_size = 16
testset = dfd.DFDC_Dataset(df=faces_df, transform=transform, path='./temp')
testloader = DataLoader(testset, batch_size=batch_size, shuffle=False, num_workers=16)<jupyter_output><empty_output><jupyter_text>EvaluationInference step to produce predictions for the test set and return a dataframe with (File, probability) pairs<jupyter_code>def dfdc_evaluation(df=None, model=None, dataloader=None):
    ''' Evaluate model on dataset
    Parameters
    ----------
    df : pd.DataFrame
        DataFrame associated to pre-processed data
    model : torch.Module
        Pytorch model for inference
    dataloader : torch.utils.data.DataLoader
        Data-loader for pre-processed data
    Returns
    -------
    probabilities : pd.DataFrame
        DataFrame with (filename, probaility) pairs
    '''
    model.eval()
    model.to(device)
    probabilities = []
    for idx, batch in enumerate(dataloader):
        frames, lbls = batch
        frames = frames.to(device)
        with torch.no_grad():
            model.lstm.reset_hidden_state()
            predictions = model(frames)
        for idx in range(predictions.shape[0]):
            probabilities.append(
                {'File' : df['File'][lbls[idx].item()], 'Probability': predictions[idx].cpu().item()}
            )
    return pd.DataFrame(probabilities)
probabilities = dfdc_evaluation(df=faces_df, model=model, dataloader=testloader)<jupyter_output><empty_output><jupyter_text>SaveCreate predictions csv for submission to competition<jupyter_code>probabilities.to_csv('submission.csv', index=False, columns=False)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10734898037706811, 'fraction_numerical': 0.010003847633705272, 'mean_word_length': 4.199, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '137916', 'license': 'MIT', 'n_tokens_mistral': 1658, 'n_tokens_neox': 1598, 'n_words': 408, 'path': 'notebooks/InferenceNotebook.ipynb', 'repo_name': 'mlomnitz/DeepFakeDetection', 'size': '5198'}