{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install mtcnn\n!pip install keras-video-generators\nimport os\nimport cv2 as cv\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom keras.layers import *\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport json\nimport numpy as np\nimport gc\nfrom keras.layers import Dense,Conv2D,MaxPooling2D,BatchNormalization,Dropout\nfrom keras.models import Sequential\nfrom mtcnn.mtcnn import MTCNN\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.utils import to_categorical","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:46:43.607481Z","iopub.execute_input":"2021-09-28T16:46:43.608266Z","iopub.status.idle":"2021-09-28T16:47:03.739082Z","shell.execute_reply.started":"2021-09-28T16:46:43.608187Z","shell.execute_reply":"2021-09-28T16:47:03.738244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with open(\"../input/deepfake-detection-challenge/train_sample_videos/metadata.json\", \"r\") as read_file:\n    data = json.load(read_file)","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:03.741085Z","iopub.execute_input":"2021-09-28T16:47:03.741396Z","iopub.status.idle":"2021-09-28T16:47:03.750343Z","shell.execute_reply.started":"2021-09-28T16:47:03.741352Z","shell.execute_reply":"2021-09-28T16:47:03.749705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path ='../input/deepfake-detection-challenge/train_sample_videos/'\ntrain_videos_name = sorted(os.listdir(train_path))\nX = [train_path+i  for i in train_videos_name]","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:03.752352Z","iopub.execute_input":"2021-09-28T16:47:03.752766Z","iopub.status.idle":"2021-09-28T16:47:03.843948Z","shell.execute_reply.started":"2021-09-28T16:47:03.752601Z","shell.execute_reply":"2021-09-28T16:47:03.843396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Y = []\nfor i in data:\n    Y.append(data[i]['label'])","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:03.845454Z","iopub.execute_input":"2021-09-28T16:47:03.845876Z","iopub.status.idle":"2021-09-28T16:47:03.850926Z","shell.execute_reply.started":"2021-09-28T16:47:03.845699Z","shell.execute_reply":"2021-09-28T16:47:03.849651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    os.mkdir('./train')\n    os.mkdir('./train/Real')\n    os.mkdir('./train/Fake')\nexcept:\n    print('Dir already exists')\n    \npath_fake = './train/Fake/'\npath_real = './train/Real/'","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:03.85442Z","iopub.execute_input":"2021-09-28T16:47:03.854864Z","iopub.status.idle":"2021-09-28T16:47:03.860407Z","shell.execute_reply.started":"2021-09-28T16:47:03.854766Z","shell.execute_reply":"2021-09-28T16:47:03.859636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path1 = './train/Fake/'\npath2 = './train/Real/'\n\nfor i in os.listdir(path1):\n    os.remove(path1+i)\n    \nfor i in os.listdir(path2):\n    os.remove(path2+i)","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:03.861867Z","iopub.execute_input":"2021-09-28T16:47:03.862314Z","iopub.status.idle":"2021-09-28T16:47:03.869377Z","shell.execute_reply.started":"2021-09-28T16:47:03.862267Z","shell.execute_reply":"2021-09-28T16:47:03.868456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"frames = 100\niter = 300","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:03.870628Z","iopub.execute_input":"2021-09-28T16:47:03.870915Z","iopub.status.idle":"2021-09-28T16:47:03.877198Z","shell.execute_reply.started":"2021-09-28T16:47:03.870861Z","shell.execute_reply":"2021-09-28T16:47:03.876393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def crop_frames(image,img_stack,k):\n    \n    faces = detector.detect_faces(image)\n    p= 60\n    \n    if(len(faces)>0):\n        for face in faces:\n\n            x, y, width, height = face['box']\n            x = x - min(x,60)\n            x1 = x+width+ min(image.shape[1]-x-width,60)\n            y = y - min(y,60)\n            y1 = y+height+ min(image.shape[0]-y-height,60)\n            crop = np.array(image[y:y1,x:x1])\n            crop = cv.cvtColor(crop,cv.COLOR_BGR2RGB)\n            crop = cv.resize(crop,(256,256))\n            k = k+1\n            \n            if k>=frames:\n                break\n\n            img_stack.append(crop)\n\n    return k,img_stack","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:03.878544Z","iopub.execute_input":"2021-09-28T16:47:03.879025Z","iopub.status.idle":"2021-09-28T16:47:03.890696Z","shell.execute_reply.started":"2021-09-28T16:47:03.878836Z","shell.execute_reply":"2021-09-28T16:47:03.890028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"detector = MTCNN()\n\nframe = np.arange(0,iter)\nsize = (256,256)\nclass_path = ''\n\nfor i in range(len(X)):\n    cnt = 0\n    k = 0\n    cap = cv.VideoCapture(X[i])\n    img_stack = []\n    \n    while(cnt<iter):\n        _,image = cap.read()\n        \n        if cnt in frame:\n            k,img_stack = crop_frames(image,img_stack,k)\n        \n            if k == frames:\n                break\n        cnt= cnt+1\n    \n    if Y[i]=='FAKE':\n        class_path = './train/Fake/'\n    \n    else:\n        class_path = './train/Real/'\n        \n    out = cv.VideoWriter(class_path+str(i)+'.avi',cv.VideoWriter_fourcc(*'MJPG'), 15, size)\n \n    for j in range(len(img_stack)):\n        out.write(img_stack[j])\n    out.release()\n\n    cap.release()\n    print(i)","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:03.893199Z","iopub.execute_input":"2021-09-28T16:47:03.893434Z","iopub.status.idle":"2021-09-28T16:47:47.273597Z","shell.execute_reply.started":"2021-09-28T16:47:03.893394Z","shell.execute_reply":"2021-09-28T16:47:47.271712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport glob\nimport keras\nfrom keras_video import VideoFrameGenerator\n\nclasses = [i.split(os.path.sep)[2] for i in glob.glob('./train/*')]\nclasses.sort()\n\nSIZE = (256,256)\nCHANNELS = 3\nNBFRAME = 20\nBS = 8\n# pattern to get videos and classes\nglob_pattern='train/{classname}/*.avi'","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:47.274567Z","iopub.status.idle":"2021-09-28T16:47:47.274951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_aug = keras.preprocessing.image.ImageDataGenerator(\n    zoom_range=.1,\n    horizontal_flip=True,\n    rotation_range=8,\n    width_shift_range=.2,\n    height_shift_range=.2)\n# Create video frame generator\ntrain = VideoFrameGenerator(\n    classes=classes, \n    glob_pattern=glob_pattern,\n    nb_frames=NBFRAME,\n    split=.3, \n    shuffle=True,\n    batch_size=BS,\n    target_shape=SIZE,\n    nb_channel=CHANNELS,\n    transformation=data_aug,\n    use_frame_cache=True)","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:47.275975Z","iopub.status.idle":"2021-09-28T16:47:47.276389Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid = train.get_validation_generator()","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:47.277309Z","iopub.status.idle":"2021-09-28T16:47:47.277671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import keras_video.utils\nkeras_video.utils.show_sample(train)","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:47.278926Z","iopub.status.idle":"2021-09-28T16:47:47.279647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.layers import Conv2D, BatchNormalization, \\\n    MaxPool2D, GlobalMaxPool2D\n\ndef build_convnet(shape=(256,256, 3)):\n    momentum = .9\n    model = keras.Sequential()\n    model.add(Conv2D(64, (3,3), input_shape=shape,\n        padding='same', activation='relu'))\n    model.add(Conv2D(64, (3,3), padding='same', activation='relu'))\n    model.add(BatchNormalization(momentum=momentum))\n    \n    model.add(MaxPool2D())\n    \n    model.add(Conv2D(128, (3,3), padding='same', activation='relu'))\n    model.add(Conv2D(128, (3,3), padding='same', activation='relu'))\n    model.add(BatchNormalization(momentum=momentum))\n    \n    model.add(MaxPool2D())\n    \n    model.add(Conv2D(256, (3,3), padding='same', activation='relu'))\n    model.add(Conv2D(256, (3,3), padding='same', activation='relu'))\n    model.add(BatchNormalization(momentum=momentum))\n    \n    model.add(MaxPool2D())\n    \n    model.add(Conv2D(512, (3,3), padding='same', activation='relu'))\n    model.add(Conv2D(512, (3,3), padding='same', activation='relu'))\n    model.add(BatchNormalization(momentum=momentum))\n    \n    # flatten...\n    model.add(GlobalMaxPool2D())\n    return model","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:47.281078Z","iopub.status.idle":"2021-09-28T16:47:47.281694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.layers import TimeDistributed, GRU, Dense, Dropout\ndef action_model(shape=(20, 256,256, 3), nbout=3):\n    # Create our convnet with (112, 112, 3) input shape\n    convnet = build_convnet(shape[1:])\n    \n    # then create our final model\n    model = keras.Sequential()\n    # add the convnet with (5, 112, 112, 3) shape\n    model.add(TimeDistributed(convnet, input_shape=shape))\n    # here, you can also use GRU or LSTM\n    model.add(GRU(64))\n    # and finally, we make a decision network\n    model.add(Dense(1024, activation='relu'))\n    model.add(Dropout(.5))\n    model.add(Dense(512, activation='relu'))\n    model.add(Dropout(.5))\n    model.add(Dense(128, activation='relu'))\n    model.add(Dropout(.5))\n    model.add(Dense(64, activation='relu'))\n    model.add(Dense(nbout, activation='softmax'))\n    return model","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:47.28323Z","iopub.status.idle":"2021-09-28T16:47:47.283969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INSHAPE=(NBFRAME,) + SIZE + (CHANNELS,) # (5, 112, 112, 3)\nmodel = action_model(INSHAPE, len(classes))\noptimizer = keras.optimizers.Adam(0.001)\nmodel.compile(\n    optimizer,\n    'categorical_crossentropy',\n    metrics=['accuracy']\n)","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:47.285384Z","iopub.status.idle":"2021-09-28T16:47:47.286045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.mkdir('./chkp')","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:47.287797Z","iopub.status.idle":"2021-09-28T16:47:47.288788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EPOCHS=5\n# create a \"chkp\" directory before to run that\n# because ModelCheckpoint will write models inside\ncallbacks = [\n    keras.callbacks.ReduceLROnPlateau(verbose=1),\n    keras.callbacks.ModelCheckpoint(\n        './chkp/weights.{epoch:02d}-{accuracy:.2f}.hdf5',\n        verbose=1),\n]\nmodel.fit_generator(\n    train,\n    validation_data=valid,\n    verbose=1,\n    epochs=EPOCHS,\n    callbacks=callbacks\n)","metadata":{"execution":{"iopub.status.busy":"2021-09-28T16:47:47.289998Z","iopub.status.idle":"2021-09-28T16:47:47.290647Z"},"trusted":true},"execution_count":null,"outputs":[]}]}