├── report.pdf ├── .gitignore ├── README.md ├── densenet-arch ├── densenet_augmented.ipynb └── densenet.ipynb ├── vggface-arch └── vggface.ipynb └── custom-arch └── custom_cnn.ipynb /report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vidhig/deepfake-image-detection/HEAD/report.pdf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | combined-real-and-fake-faces/* 3 | .ipynb_checkpoints 4 | */.ipynb_checkpoints/* 5 | vector_reps/ 6 | models/ 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## DeepFake Image Detection 2 | 3 | ### Problem Statement 4 | 5 | With the advent of Generative Adversarial Network (GAN) and other deep learning based DeepFake techniques, the immediate challenge we face as a community is how to assess the validity of online material be it machine learning derived images or videos. We are faced with an unprecedented potential for an extreme violation of basic human rights along with a fundamental unavoidable change in how humans interact socially. We have already seen evidence of maligning and manipulation of news headlines, medical (dis)information along with abuse of individual privacy. The goal of this proposed project is to use an online image database to effectively detect DeepFake images. This paper focuses on use of convolutional neural networks for classification of true versus fake images obtained from a large online database. We aimed to compare three different convolutional neural networks: 6 | 7 | 1. VGGFace16 8 | 2. DenseNet-121 9 | 3. 3 Custom CNN Architectures. 10 | 11 | Future work would include the use of unsupervised clustering methods / auto-encoders explore if true versus fake images cluster separately and also to add transparency and interpretability to our models by use of CNN visualization methods. 12 | 13 | For all the models we extracted the output of the last layer before classification to see if the vectors are representative of the images. The vectors have dimensions of 512, 2048, 1024 for custom, VGGFace and DenseNet models. This was entirely too large, therefore, we used principal component analysis (PCA) to keep points that contributed the most in terms of variability. By running PCA, we were able to retain 50 principal components. We then used support vector machine (SVM) with polynomial kernel to classify the retained components into the two classes (real or fake). We also looked at the PCA visualization and found that most architectures were able to learn the differentiating patterns of real vs. fake images and distinct clusters could be seen against the first 2 principle components. 14 | 15 | > Detailed analysis, performance metrics and inferences are provided in the report. 16 | 17 | ### Dataset Source 18 | 19 | Two datasets from Kaggle were taken and combined together. Since the datasets are too large they are not pushed to the repository. Please download the following datasets: 20 | 21 | 1. https://www.kaggle.com/xhlulu/140k-real-and-fake-faces 22 | 2. https://www.kaggle.com/ciplab/real-and-fake-face-detection 23 | 24 | Once downloaded create a folder called `combined-real-and-fake-faces/combined-real-vs-fake`. Within this folder should be 3 subfolders: `train`, `valid` and `test`. Combine the second dataset with the first one. 25 | 26 | ### How to Run? 27 | 28 | The notebooks within the specific arch. are indepedent and can be run parallely. Each of these notebooks will save the `.h5` models. Place all the saved models in the folder called `models`. 29 | 30 | > Please note that pretrained models could not be uploaded due to file size restrictions. 31 | 32 | Once the models are saved run the `performance-eval` notebook to see the performance comparision of the various models and extracting the last layer of the network which gives the vector representation of the images which was learnt by the model. 33 | 34 | After this run the `pca_svm` notebook to look at the PCA visualizations and perform classification using SVM. -------------------------------------------------------------------------------- /densenet-arch/densenet_augmented.ipynb: -------------------------------------------------------------------------------- 1 | {"cells":[{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"import cv2\nimport numpy as np\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.applications import DenseNet121\nfrom tensorflow.keras.callbacks import Callback, ModelCheckpoint\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.optimizers import Adam\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn import metrics\nimport tensorflow as tf\nfrom tqdm import tqdm","execution_count":1,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_model(pretrained):\n model = Sequential([\n pretrained,\n layers.GlobalAveragePooling2D(),\n layers.Dense(1, activation='sigmoid')\n ])\n \n model.compile(\n loss='binary_crossentropy',\n optimizer=Adam(),\n metrics=['accuracy']\n )\n \n return model","execution_count":2,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Generator"},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"base_path = '/kaggle/input/140k-real-and-fake-faces/real_vs_fake/real-vs-fake/'\nimage_gen = ImageDataGenerator(rescale=1./255.,\n rotation_range=20,\n #shear_range=0.2,\n #zoom_range=0.2,\n horizontal_flip=True)\n\ntrain_flow = image_gen.flow_from_directory(\n base_path + 'train/',\n target_size=(224, 224),\n batch_size=64,\n class_mode='binary'\n)\n\n\n","execution_count":3,"outputs":[{"output_type":"stream","text":"Found 100000 images belonging to 2 classes.\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_gen1 = ImageDataGenerator(rescale=1./255.)\n\nvalid_flow = image_gen1.flow_from_directory(\n base_path + 'valid/',\n target_size=(224, 224),\n batch_size=64,\n class_mode='binary'\n)\n","execution_count":4,"outputs":[{"output_type":"stream","text":"Found 20000 images belonging to 2 classes.\nFound 20000 images belonging to 2 classes.\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"# Train Model DenseNet Augmented Data "},{"metadata":{"trusted":true},"cell_type":"code","source":"densenet = DenseNet121(\n weights=None,\n include_top=False,\n input_shape=(224,224,3)\n)\nmodel = build_model(densenet)\nmodel.summary()","execution_count":5,"outputs":[{"output_type":"stream","text":"Model: \"sequential\"\n_________________________________________________________________\nLayer (type) Output Shape Param # \n=================================================================\ndensenet121 (Model) (None, 7, 7, 1024) 7037504 \n_________________________________________________________________\nglobal_average_pooling2d (Gl (None, 1024) 0 \n_________________________________________________________________\ndense (Dense) (None, 1) 1025 \n=================================================================\nTotal params: 7,038,529\nTrainable params: 6,954,881\nNon-trainable params: 83,648\n_________________________________________________________________\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_steps = 100000//64\nvalid_steps = 20000//64\n\nhistory = model.fit_generator(\n train_flow,\n epochs = 5,\n steps_per_epoch= train_steps,\n validation_data= valid_flow,\n validation_steps= valid_steps\n)","execution_count":6,"outputs":[{"output_type":"stream","text":"Train for 1562 steps, validate for 312 steps\nEpoch 1/5\n1562/1562 [==============================] - 2511s 2s/step - loss: 0.6121 - accuracy: 0.6593 - val_loss: 0.5734 - val_accuracy: 0.7058\nEpoch 2/5\n1562/1562 [==============================] - 1964s 1s/step - loss: 0.4540 - accuracy: 0.7873 - val_loss: 0.5459 - val_accuracy: 0.7530\nEpoch 3/5\n1562/1562 [==============================] - 1966s 1s/step - loss: 0.3492 - accuracy: 0.8474 - val_loss: 0.3648 - val_accuracy: 0.8399\nEpoch 4/5\n1562/1562 [==============================] - 1941s 1s/step - loss: 0.2699 - accuracy: 0.8868 - val_loss: 0.5084 - val_accuracy: 0.7928\nEpoch 5/5\n1562/1562 [==============================] - 1948s 1s/step - loss: 0.2115 - accuracy: 0.9133 - val_loss: 0.2043 - val_accuracy: 0.9174\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"# Evaluation"},{"metadata":{"trusted":true},"cell_type":"code","source":"#model.save('completed_augmented_trained_model.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\"\"\"\nPlot the training and validation loss\nepochs - list of epoch numbers\nloss - training loss for each epoch\nval_loss - validation loss for each epoch\n\"\"\"\ndef plot_loss(epochs, loss, val_loss):\n plt.plot(epochs, loss, 'bo', label='Training Loss')\n plt.plot(epochs, val_loss, 'orange', label = 'Validation Loss')\n plt.title('Training and Validation Loss')\n plt.legend()\n plt.show()\n\"\"\"\nPlot the training and validation accuracy\nepochs - list of epoch numbers\nacc - training accuracy for each epoch\nval_acc - validation accuracy for each epoch\n\"\"\"\ndef plot_accuracy(epochs, acc, val_acc):\n plt.plot(epochs, acc, 'bo', label='Training accuracy')\n plt.plot(epochs, val_acc, 'orange', label = 'Validation accuracy')\n plt.title('Training and Validation Accuracy')\n plt.legend()\n plt.show()","execution_count":7,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"acc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']","execution_count":8,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_loss(range(1, len(loss) + 1), loss, val_loss)\nplot_accuracy(range(1, len(loss) + 1), acc, val_acc)","execution_count":9,"outputs":[{"output_type":"display_data","data":{"text/plain":"
","image/png":"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\n"},"metadata":{"needs_background":"light"}},{"output_type":"display_data","data":{"text/plain":"
","image/png":"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\n"},"metadata":{"needs_background":"light"}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_flow = image_gen1.flow_from_directory(\n base_path + 'test/',\n target_size=(224, 224),\n batch_size=1,\n shuffle = False,\n class_mode='binary'\n)\ny_pred=model.predict(test_flow)\ny_test = test_flow.classes","execution_count":10,"outputs":[{"output_type":"stream","text":"Found 20000 images belonging to 2 classes.\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"ROC AUC Score:\", metrics.roc_auc_score(y_test, y_pred))\nprint(\"AP Score:\", metrics.average_precision_score(y_test, y_pred))\nprint()\nprint(metrics.classification_report(y_test, y_pred > 0.5))","execution_count":11,"outputs":[{"output_type":"stream","text":"ROC AUC Score: 0.9754987100000001\nAP Score: 0.9752373964211345\n\n precision recall f1-score support\n\n 0 0.93 0.91 0.92 10000\n 1 0.91 0.93 0.92 10000\n\n accuracy 0.92 20000\n macro avg 0.92 0.92 0.92 20000\nweighted avg 0.92 0.92 0.92 20000\n\n","name":"stdout"}]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.3"}},"nbformat":4,"nbformat_minor":4} -------------------------------------------------------------------------------- /densenet-arch/densenet.ipynb: -------------------------------------------------------------------------------- 1 | {"cells":[{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"import cv2\nimport numpy as np\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.applications import DenseNet121\nfrom tensorflow.keras.callbacks import Callback, ModelCheckpoint\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.optimizers import Adam\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn import metrics\nimport tensorflow as tf\nfrom tqdm import tqdm","execution_count":1,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_model(pretrained):\n model = Sequential([\n pretrained,\n layers.GlobalAveragePooling2D(),\n layers.Dense(1, activation='sigmoid')\n ])\n \n model.compile(\n loss='binary_crossentropy',\n optimizer=Adam(),\n metrics=['accuracy']\n )\n \n return model","execution_count":2,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Generator"},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"base_path = '/kaggle/input/140k-real-and-fake-faces/real_vs_fake/real-vs-fake/'\nimage_gen = ImageDataGenerator(rescale=1./255.)\n\ntrain_flow = image_gen.flow_from_directory(\n base_path + 'train/',\n target_size=(224, 224),\n batch_size=64,\n class_mode='binary'\n)\n\n\n","execution_count":13,"outputs":[{"output_type":"stream","text":"Found 100000 images belonging to 2 classes.\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_gen1 = ImageDataGenerator(rescale=1./255.)\n\nvalid_flow = image_gen1.flow_from_directory(\n base_path + 'valid/',\n target_size=(224, 224),\n batch_size=64,\n class_mode='binary'\n)\n","execution_count":4,"outputs":[{"output_type":"stream","text":"Found 20000 images belonging to 2 classes.\nFound 20000 images belonging to 2 classes.\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"# Train Model DenseNet "},{"metadata":{"trusted":true},"cell_type":"code","source":"densenet = DenseNet121(\n weights=None,\n include_top=False,\n input_shape=(224,224,3)\n)\nmodel = build_model(densenet)\nmodel.summary()","execution_count":14,"outputs":[{"output_type":"stream","text":"Model: \"sequential_1\"\n_________________________________________________________________\nLayer (type) Output Shape Param # \n=================================================================\ndensenet121 (Model) (None, 7, 7, 1024) 7037504 \n_________________________________________________________________\nglobal_average_pooling2d_1 ( (None, 1024) 0 \n_________________________________________________________________\ndense_1 (Dense) (None, 1) 1025 \n=================================================================\nTotal params: 7,038,529\nTrainable params: 6,954,881\nNon-trainable params: 83,648\n_________________________________________________________________\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_steps = 100000//64\nvalid_steps = 20000//64\n\nhistory = model.fit_generator(\n train_flow,\n epochs = 10,\n steps_per_epoch =train_steps,\n validation_data =valid_flow,\n validation_steps = valid_steps\n)","execution_count":16,"outputs":[{"output_type":"stream","text":"Train for 1562 steps, validate for 312 steps\nEpoch 1/10\n1562/1562 [==============================] - 626s 401ms/step - loss: 0.5267 - accuracy: 0.7306 - val_loss: 0.5864 - val_accuracy: 0.7350\nEpoch 2/10\n1562/1562 [==============================] - 626s 401ms/step - loss: 0.3204 - accuracy: 0.8616 - val_loss: 0.3838 - val_accuracy: 0.8302\nEpoch 3/10\n1562/1562 [==============================] - 624s 400ms/step - loss: 0.1853 - accuracy: 0.9256 - val_loss: 0.3160 - val_accuracy: 0.8630\nEpoch 4/10\n1562/1562 [==============================] - 623s 399ms/step - loss: 0.1143 - accuracy: 0.9555 - val_loss: 0.2638 - val_accuracy: 0.9045\nEpoch 5/10\n1562/1562 [==============================] - 624s 399ms/step - loss: 0.0771 - accuracy: 0.9710 - val_loss: 0.2181 - val_accuracy: 0.9152\nEpoch 6/10\n1562/1562 [==============================] - 624s 399ms/step - loss: 0.0562 - accuracy: 0.9788 - val_loss: 0.1217 - val_accuracy: 0.9543\nEpoch 7/10\n1562/1562 [==============================] - 623s 399ms/step - loss: 0.0420 - accuracy: 0.9845 - val_loss: 0.3343 - val_accuracy: 0.8878\nEpoch 8/10\n1562/1562 [==============================] - 645s 413ms/step - loss: 0.0337 - accuracy: 0.9873 - val_loss: 0.2627 - val_accuracy: 0.9122\nEpoch 9/10\n1562/1562 [==============================] - 623s 399ms/step - loss: 0.0279 - accuracy: 0.9898 - val_loss: 0.5455 - val_accuracy: 0.8429\nEpoch 10/10\n1562/1562 [==============================] - 622s 398ms/step - loss: 0.0240 - accuracy: 0.9913 - val_loss: 0.2837 - val_accuracy: 0.9146\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"# Evaluation"},{"metadata":{"trusted":true},"cell_type":"code","source":"#model.save('completed_trained_model.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\"\"\"\nPlot the training and validation loss\nepochs - list of epoch numbers\nloss - training loss for each epoch\nval_loss - validation loss for each epoch\n\"\"\"\ndef plot_loss(epochs, loss, val_loss):\n plt.plot(epochs, loss, 'bo', label='Training Loss')\n plt.plot(epochs, val_loss, 'orange', label = 'Validation Loss')\n plt.title('Training and Validation Loss')\n plt.legend()\n plt.show()\n\"\"\"\nPlot the training and validation accuracy\nepochs - list of epoch numbers\nacc - training accuracy for each epoch\nval_acc - validation accuracy for each epoch\n\"\"\"\ndef plot_accuracy(epochs, acc, val_acc):\n plt.plot(epochs, acc, 'bo', label='Training accuracy')\n plt.plot(epochs, val_acc, 'orange', label = 'Validation accuracy')\n plt.title('Training and Validation Accuracy')\n plt.legend()\n plt.show()","execution_count":17,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"acc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']","execution_count":18,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_loss(range(1, len(loss) + 1), loss, val_loss)\nplot_accuracy(range(1, len(loss) + 1), acc, val_acc)","execution_count":19,"outputs":[{"output_type":"display_data","data":{"text/plain":"
","image/png":"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Rw8eeuihY/uWnEkXFxfTpEkTxo8fT58+fejfvz9btmwB4De/+Q0TJ048tv/48ePp168fJ598Mp9//jkA+/bt48orr6RPnz6MHDmSrKysgM/QDxw4wPXXX0+vXr3IzMxkzpw5AHz11Vecdtpp9O3bl969e7N27Vr27NnD4MGD6dOnDz179mTatGnBfOvCpuTDvqAAVH/4sK+zFSpNnRe1yT3cNU1WrFjBzTffzKJFi2jTpg2PPPIIubm5LFmyhA8//JAVK1Yc95pdu3Zx7rnnsmTJEvr378+LL75Y7rFVlS+//JLHHnvs2AfF008/TatWrViyZAnjx49n0aJFAcf617/+laSkJL766iteeeUVRo8ezaFDh/j73//OuHHjWLx4MfPnz6d169bMmDGD9PR0lixZwrJly7joootq9gZ5zAqYGVNa1Cb3cNc06dixI6eddtqxx5MnTyYzM5PMzEzy8vLKTe7169dn8ODBAJx66qnk5+eXe+wrrrjiuH3mzp3LiBEjAOjTpw89evQIONa5c+cyevRoAHr06EHr1q1Zs2YNZ555Jg8//DCPPvoo69evJzk5md69ezNz5kzGjx/Pf//7Xxo3bhxwO5HECpgZU1rUJvdw1zRp0KDBse9Xr17NU089xSeffMLSpUsZNGhQuWO8k5KSjn0fHx9PcXFxuceuV6/ecfuo1mgqQaWvHT16NG+++Sb16tXjoosuYs6cOXTr1o3c3Fx69OjBPffcwx//+Mcat+slK2BmTGlRm9y9rGmye/duGjZsSKNGjdi0aROzZs0Kehtnn302U6dOBVxfeXlXBhU555xzjo3GycvLY9OmTXTq1Im1a9fSqVMn7rrrLoYMGcLSpUvZsGEDqampjB49mrvvvpuFCxcG/WcJBytgZkxpUb0S06hR3oyGyMzMpHv37vTs2ZMOHTpw1llnBb2Nn//854wZM4bevXuTmZlJz549K+wyueSSS47VdBkwYAAvvvgiP/3pT+nVqxeJiYn861//Iikpiddee43JkyeTmJhI69atefjhh/n8888ZP348cXFxJCUl8Y9//CPoP0s4lPw/sNEyxjhSm8v/2sjKytLc3NxS2/Ly8ujWrZsn8USa4uJiiouLSU5OZvXq1Vx88cWsXr2ahITI/Ty2358xoSciC1Q1q6r9orZbJtbt3buXs846iz59+nDllVfy3HPP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\n"},"metadata":{"needs_background":"light"}},{"output_type":"display_data","data":{"text/plain":"
","image/png":"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KYn169cX+voA5syZw+mnn05iYiJdu3Zl7969nHHGGflKRvfs2ZOFCxcW+3sqjcrV/7H0SahWD1rf4HUkxlQKjRo1omvXrnz11VdceOGFjB8/niFDhiAi1KxZk08++YR69eqxbds2unfvzgUXXFDkHK6vvPIKsbGxLFy4kIULF5KUlJS3bvTo0RxzzDFkZ2fTr18/Fi5cyK233spzzz3H9OnTady4cb59zZ07l3HjxjF79mxUlW7dutGnTx8aNmzIihUreP/993nttdf44x//yMcff8zll1+e7/m9evVi1qxZiAivv/46Tz31FM8++yyPPvoo9evXZ9GiRQDs3LmTjIwMrrvuOmbOnEnLli3z1dEpym+//ca4ceP497//XeTrO+200xgyZAgffPABXbp0Yc+ePdSqVYuRI0fy1ltvMWbMGJYvX86hQ4dISEgo1e+tOJUn6e9bDes/dH351euXvL0xFU3nMZ4cNreLJzfpv/nmm4DrurjvvvuYOXMmMTExbNiwgS1btnD88ccXup+ZM2dy6623Aq42jX8imzBhAmPHjiUrK4tNmzaxdOnSYhPd999/zx/+8Ie8ipcXX3wx3333HRdccAEtW7akY8eOQNHlm9PT0xkyZAibNm3i8OHDtGzZEoCpU6fm685q2LAhn332Gb17987bJpDyyy1atKB7998vCi3s9YkIJ5xwQl556nr16gFw2WWX8eijj/L000/z5ptvcvXVV5d4vNKoNN07733aghtSPuCEM28PytygxhjnoosuYtq0acybN48DBw7ktdBTUlLIyMhg7ty5LFiwgOOOO67Qcsr+CvsWsGbNGp555hmmTZvGwoULOffcc0vcT3E1w3LLMkPR5ZtvueUWbr75ZhYtWsSrr76ad7zCSiIHUn4Z8pdg9i+/XNTrK2q/sbGxDBgwgE8//ZQJEybwpz/9qcjXWhaVIumnpMB1o6rwny8uZfOu4/PmBrXEb0z51alTh759+3LNNdfkO4GbW1a4WrVqTJ8+nZIKJfbu3Ttv8vPFixfn9VPv2bOH2rVrU79+fbZs2cKXX36Z95y6deuyd+/eQvf1v//9j8zMTPbv388nn3zCGWecEfBr2r17N02bNgXg7bffzls+cOBAXnrppbzHO3fupEePHsyYMYM1a9YA+csvz5s3D4B58+blrS+oqNd32mmnsXHjRubMmQPA3r178z6gRo4cya233kqXLl0C+mZRGpUi6YdzblBjotGwYcP45Zdf8mauAlciODU1leTkZFJSUkqcEOSGG25g3759JCQk8NRTT9G1a1fAzYLVqVMn2rdvzzXXXJOvLPOoUaMYPHhw3oncXElJSVx99dV07dqVbt26MXLkSDp16hTw63n44Ye57LLLOOOMM/KdL3jggQfYuXMn8fHxJCYmMn36dJo0acLYsWO5+OKLSUxMzCuJfMkll7Bjxw46duzIK6+8wqmnnlrosYp6fdWrV+eDDz7glltuITExkQEDBuR9W+jcuTP16tULSc39Eksrh1tycrKWNHa3oJgYd01WQSKurrgxFZWVVo5OGzdupG/fvvz666/ExBzdNi9PaeVK0dIP99ygxhgTKu+88w7dunVj9OjRhSb88qoUST/cc4MaY0yoXHnllaxfv57LLrssJPuvFEnfy7lBjQm1SOuCNd4q799DpRmnP3y4JXlT+dSsWZPt27fTqFGjIi96MtFDVdm+fTs1a5a94kClSfrGVEbNmjUjPT2djIwMr0MxEaJmzZo0a9aszM+3pG9MBKtWrVrelaDGBEOl6NM3xhgTGEv6xhgTRSzpG2NMFIm4K3JFJAMovohH5GsMbPM6iAhi70d+9n78zt6L/MrzfrRQ1SYlbRRxSb8yEJHUQC6Hjhb2fuRn78fv7L3ILxzvh3XvGGNMFLGkb4wxUcSSfmiM9TqACGPvR372fvzO3ov8Qv5+WJ++McZEEWvpG2NMFLGkb4wxUcSSfhCJyEkiMl1ElonIEhG5zeuYvCYiVURkvoh87nUsXhORBiLykYj86vsb6eF1TF4SkTt8/yeLReR9ESl76cgKSETeFJGtIrLYb9kxIjJFRFb4bhsG+7iW9IMrC/irqrYFugM3iUg7j2Py2m3AMq+DiBAvAF+p6mlAIlH8vohIU+BWIFlV44EqwNDin1XpvAUMKrDsHmCaqrYGpvkeB5Ul/SBS1U2qOs93fy/un7qpt1F5R0SaAecCr3sdi9dEpB7QG3gDQFUPq+oub6PyXFWglohUBWKBjR7HE1aqOhPYUWDxhcDbvvtvAxcF+7iW9ENEROKATsBsbyPx1BjgbsCmp4eTgQxgnK+763URqe11UF5R1Q3AM8A6YBOwW1W/9jaqiHCcqm4C14gEjg32ASzph4CI1AE+Bm5X1T1ex+MFETkP2Kqqc72OJUJUBZKAV1S1E7CfEHx1ryh8fdUXAi2BE4HaInK5t1FFB0v6QSYi1XAJP0VV/8/reDzUE7hARNKA8cBZIvJfb0PyVDqQrqq53/w+wn0IRKv+wBpVzVDVI8D/Aad7HFMk2CIiJwD4brcG+wCW9INI3CSmbwDLVPU5r+Pxkqreq6rNVDUOd4LuG1WN2pacqm4G1otIG9+ifsBSD0Py2jqgu4jE+v5v+hHFJ7b9TASu8t2/Cvg02Aew6RKDqydwBbBIRBb4lt2nqpM8jMlEjluAFBGpDqwGRngcj2dUdbaIfATMw416m0+UlWQQkfeBvkBjEUkHHgKeACaIyLW4D8bLgn5cK8NgjDHRw7p3jDEmiljSN8aYKGJJ3xhjooglfWOMiSKW9I0xJopY0jfGmChiSd8YY6LI/wMRRCf9OBmlrgAAAABJRU5ErkJggg==\n"},"metadata":{"needs_background":"light"}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_flow = image_gen1.flow_from_directory(\n base_path + 'test/',\n target_size=(224, 224),\n batch_size=1,\n shuffle = False,\n class_mode='binary'\n)\ny_pred = model.predict(test_flow)\ny_test = test_flow.classes","execution_count":20,"outputs":[{"output_type":"stream","text":"Found 20000 images belonging to 2 classes.\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"ROC AUC Score:\", metrics.roc_auc_score(y_test, y_pred))\nprint(\"AP Score:\", metrics.average_precision_score(y_test, y_pred))\nprint()\nprint(metrics.classification_report(y_test, y_pred > 0.5))","execution_count":21,"outputs":[{"output_type":"stream","text":"ROC AUC Score: 0.992412935\nAP Score: 0.9915270175017084\n\n precision recall f1-score support\n\n 0 1.00 0.83 0.91 10000\n 1 0.86 1.00 0.92 10000\n\n accuracy 0.92 20000\n macro avg 0.93 0.92 0.91 20000\nweighted avg 0.93 0.92 0.91 20000\n\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.3"}},"nbformat":4,"nbformat_minor":4} -------------------------------------------------------------------------------- /vggface-arch/vggface.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19", 8 | "_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5" 9 | }, 10 | "outputs": [], 11 | "source": [ 12 | "# import numpy as np # linear algebra\n", 13 | "# import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n", 14 | "\n", 15 | "\n", 16 | "# import os\n", 17 | "# for dirname, _, filenames in os.walk('../combined-real-and-fake-faces/combined-real-vs-fake/'):\n", 18 | "# for filename in filenames[:1]:\n", 19 | "# print(os.path.join(dirname, filename))\n" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "**Load Required Packages**" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 2, 32 | "metadata": {}, 33 | "outputs": [], 34 | "source": [ 35 | "## Dowload packages\n", 36 | "# !pip install --user keras-vggface\n", 37 | "# !pip install --user opencv-python" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 3, 43 | "metadata": { 44 | "_cell_guid": "79c7e3d0-c299-4dcb-8224-4455121ee9b0", 45 | "_uuid": "d629ff2d2480ee46fbb7e2d37f6b5fab8052498a" 46 | }, 47 | "outputs": [ 48 | { 49 | "name": "stderr", 50 | "output_type": "stream", 51 | "text": [ 52 | "Using TensorFlow backend.\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "import cv2\n", 58 | "import pandas as pd\n", 59 | "import numpy as np\n", 60 | "import tensorflow as tf\n", 61 | "import matplotlib.pyplot as plt\n", 62 | "\n", 63 | "from sklearn import metrics\n", 64 | "\n", 65 | "from keras_vggface.vggface import VGGFace\n", 66 | "from keras.models import Sequential, Model\n", 67 | "from keras.layers import Dense, Flatten, Dropout\n", 68 | "from keras.callbacks.callbacks import ReduceLROnPlateau\n", 69 | "\n", 70 | "from keras.optimizers import Adam, RMSprop\n", 71 | "from keras.preprocessing.image import ImageDataGenerator\n" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "**Load Images**" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 4, 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "name": "stdout", 88 | "output_type": "stream", 89 | "text": [ 90 | "Found 100000 images belonging to 2 classes.\n", 91 | "Found 20000 images belonging to 2 classes.\n", 92 | "Found 21591 images belonging to 2 classes.\n" 93 | ] 94 | } 95 | ], 96 | "source": [ 97 | "base_path = '../combined-real-and-fake-faces/combined-real-vs-fake/'\n", 98 | "image_gen = ImageDataGenerator(rescale=1./255.)\n", 99 | "batch_size = 64\n", 100 | "\n", 101 | "train_flow = image_gen.flow_from_directory(\n", 102 | " base_path + 'train/',\n", 103 | " target_size=(224, 224),\n", 104 | " batch_size=batch_size,\n", 105 | " class_mode='binary'\n", 106 | ")\n", 107 | "\n", 108 | "valid_flow = image_gen.flow_from_directory(\n", 109 | " base_path + 'valid/',\n", 110 | " target_size=(224, 224),\n", 111 | " batch_size=batch_size,\n", 112 | " class_mode='binary'\n", 113 | ")\n", 114 | "\n", 115 | "test_flow = image_gen.flow_from_directory(\n", 116 | " base_path + 'test/',\n", 117 | " target_size=(224, 224),\n", 118 | " batch_size=1,\n", 119 | " shuffle=False,\n", 120 | " class_mode='binary'\n", 121 | ")" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 5, 127 | "metadata": {}, 128 | "outputs": [ 129 | { 130 | "data": { 131 | "text/plain": [ 132 | "{'fake': 0, 'real': 1}" 133 | ] 134 | }, 135 | "execution_count": 5, 136 | "metadata": {}, 137 | "output_type": "execute_result" 138 | } 139 | ], 140 | "source": [ 141 | "train_flow.class_indices" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 6, 147 | "metadata": {}, 148 | "outputs": [ 149 | { 150 | "data": { 151 | "text/plain": [ 152 | "{'fake': 0, 'real': 1}" 153 | ] 154 | }, 155 | "execution_count": 6, 156 | "metadata": {}, 157 | "output_type": "execute_result" 158 | } 159 | ], 160 | "source": [ 161 | "valid_flow.class_indices" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": 7, 167 | "metadata": {}, 168 | "outputs": [ 169 | { 170 | "data": { 171 | "text/plain": [ 172 | "{'fake': 0, 'real': 1}" 173 | ] 174 | }, 175 | "execution_count": 7, 176 | "metadata": {}, 177 | "output_type": "execute_result" 178 | } 179 | ], 180 | "source": [ 181 | "test_flow.class_indices" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "**Helper Functions**" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 8, 194 | "metadata": {}, 195 | "outputs": [], 196 | "source": [ 197 | "\"\"\"\n", 198 | "Plot the training and validation loss\n", 199 | "epochs - list of epoch numbers\n", 200 | "loss - training loss for each epoch\n", 201 | "val_loss - validation loss for each epoch\n", 202 | "\"\"\"\n", 203 | "def plot_loss(epochs, loss, val_loss):\n", 204 | " plt.plot(epochs, loss, 'bo', label='Training Loss')\n", 205 | " plt.plot(epochs, val_loss, 'orange', label = 'Validation Loss')\n", 206 | " plt.title('Training and Validation Loss')\n", 207 | " plt.legend()\n", 208 | " plt.show()\n", 209 | " \n", 210 | " \n", 211 | "\"\"\"\n", 212 | "Plot the training and validation accuracy\n", 213 | "epochs - list of epoch numbers\n", 214 | "acc - training accuracy for each epoch\n", 215 | "val_acc - validation accuracy for each epoch\n", 216 | "\"\"\"\n", 217 | "def plot_accuracy(epochs, acc, val_acc):\n", 218 | " plt.plot(epochs, acc, 'bo', label='Training accuracy')\n", 219 | " plt.plot(epochs, val_acc, 'orange', label = 'Validation accuracy')\n", 220 | " plt.title('Training and Validation Accuracy')\n", 221 | " plt.legend()\n", 222 | " plt.show()" 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "**Fine Tune VGGFace Model**" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 9, 235 | "metadata": {}, 236 | "outputs": [], 237 | "source": [ 238 | "vgg_model = VGGFace(include_top=False, input_shape = (224,224,3))\n", 239 | "\n", 240 | "last_layer = vgg_model.get_layer('pool5').output\n", 241 | "flat_layer = Flatten(name='flatten')(last_layer)\n", 242 | "fc1 = Dense(2048, activation='relu', name='fc1')(flat_layer)\n", 243 | "dense2 = Dense(1, activation='sigmoid', name='dense2')(fc1)\n", 244 | "\n", 245 | "custom_vgg_model = Model(vgg_model.input, dense2)" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": 10, 251 | "metadata": {}, 252 | "outputs": [ 253 | { 254 | "name": "stdout", 255 | "output_type": "stream", 256 | "text": [ 257 | "Model: \"model_1\"\n", 258 | "_________________________________________________________________\n", 259 | "Layer (type) Output Shape Param # \n", 260 | "=================================================================\n", 261 | "input_1 (InputLayer) (None, 224, 224, 3) 0 \n", 262 | "_________________________________________________________________\n", 263 | "conv1_1 (Conv2D) (None, 224, 224, 64) 1792 \n", 264 | "_________________________________________________________________\n", 265 | "conv1_2 (Conv2D) (None, 224, 224, 64) 36928 \n", 266 | "_________________________________________________________________\n", 267 | "pool1 (MaxPooling2D) (None, 112, 112, 64) 0 \n", 268 | "_________________________________________________________________\n", 269 | "conv2_1 (Conv2D) (None, 112, 112, 128) 73856 \n", 270 | "_________________________________________________________________\n", 271 | "conv2_2 (Conv2D) (None, 112, 112, 128) 147584 \n", 272 | "_________________________________________________________________\n", 273 | "pool2 (MaxPooling2D) (None, 56, 56, 128) 0 \n", 274 | "_________________________________________________________________\n", 275 | "conv3_1 (Conv2D) (None, 56, 56, 256) 295168 \n", 276 | "_________________________________________________________________\n", 277 | "conv3_2 (Conv2D) (None, 56, 56, 256) 590080 \n", 278 | "_________________________________________________________________\n", 279 | "conv3_3 (Conv2D) (None, 56, 56, 256) 590080 \n", 280 | "_________________________________________________________________\n", 281 | "pool3 (MaxPooling2D) (None, 28, 28, 256) 0 \n", 282 | "_________________________________________________________________\n", 283 | "conv4_1 (Conv2D) (None, 28, 28, 512) 1180160 \n", 284 | "_________________________________________________________________\n", 285 | "conv4_2 (Conv2D) (None, 28, 28, 512) 2359808 \n", 286 | "_________________________________________________________________\n", 287 | "conv4_3 (Conv2D) (None, 28, 28, 512) 2359808 \n", 288 | "_________________________________________________________________\n", 289 | "pool4 (MaxPooling2D) (None, 14, 14, 512) 0 \n", 290 | "_________________________________________________________________\n", 291 | "conv5_1 (Conv2D) (None, 14, 14, 512) 2359808 \n", 292 | "_________________________________________________________________\n", 293 | "conv5_2 (Conv2D) (None, 14, 14, 512) 2359808 \n", 294 | "_________________________________________________________________\n", 295 | "conv5_3 (Conv2D) (None, 14, 14, 512) 2359808 \n", 296 | "_________________________________________________________________\n", 297 | "pool5 (MaxPooling2D) (None, 7, 7, 512) 0 \n", 298 | "_________________________________________________________________\n", 299 | "flatten (Flatten) (None, 25088) 0 \n", 300 | "_________________________________________________________________\n", 301 | "fc1 (Dense) (None, 2048) 51382272 \n", 302 | "_________________________________________________________________\n", 303 | "dense2 (Dense) (None, 1) 2049 \n", 304 | "=================================================================\n", 305 | "Total params: 66,099,009\n", 306 | "Trainable params: 66,099,009\n", 307 | "Non-trainable params: 0\n", 308 | "_________________________________________________________________\n" 309 | ] 310 | } 311 | ], 312 | "source": [ 313 | "custom_vgg_model.summary()" 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": 11, 319 | "metadata": {}, 320 | "outputs": [], 321 | "source": [ 322 | "custom_vgg_model.compile(\n", 323 | " loss='binary_crossentropy',\n", 324 | " optimizer=Adam(0.0002), \n", 325 | " metrics=['acc']\n", 326 | ")" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": 12, 332 | "metadata": {}, 333 | "outputs": [ 334 | { 335 | "name": "stdout", 336 | "output_type": "stream", 337 | "text": [ 338 | "Epoch 1/5\n", 339 | "1562/1562 [==============================] - 2711s 2s/step - loss: 0.2014 - acc: 0.9101 - val_loss: 0.0475 - val_acc: 0.9742\n", 340 | "Epoch 2/5\n", 341 | "1562/1562 [==============================] - 2679s 2s/step - loss: 0.0503 - acc: 0.9819 - val_loss: 0.0927 - val_acc: 0.9829\n", 342 | "Epoch 3/5\n", 343 | "1562/1562 [==============================] - 2674s 2s/step - loss: 0.0295 - acc: 0.9893 - val_loss: 0.0112 - val_acc: 0.9853\n", 344 | "Epoch 4/5\n", 345 | "1562/1562 [==============================] - 2672s 2s/step - loss: 0.0221 - acc: 0.9923 - val_loss: 0.0031 - val_acc: 0.9875\n", 346 | "Epoch 5/5\n", 347 | "1562/1562 [==============================] - 2668s 2s/step - loss: 0.0173 - acc: 0.9937 - val_loss: 0.0739 - val_acc: 0.9808\n" 348 | ] 349 | } 350 | ], 351 | "source": [ 352 | "train_steps = 100000//batch_size\n", 353 | "valid_steps = 20000//batch_size\n", 354 | "\n", 355 | "history = custom_vgg_model.fit_generator(\n", 356 | " train_flow,\n", 357 | " epochs=5,\n", 358 | " steps_per_epoch=train_steps,\n", 359 | " validation_data=valid_flow,\n", 360 | " validation_steps=valid_steps\n", 361 | ")" 362 | ] 363 | }, 364 | { 365 | "cell_type": "code", 366 | "execution_count": 13, 367 | "metadata": {}, 368 | "outputs": [], 369 | "source": [ 370 | "custom_vgg_model.save('vggface_v1.h5')" 371 | ] 372 | }, 373 | { 374 | "cell_type": "code", 375 | "execution_count": 14, 376 | "metadata": {}, 377 | "outputs": [], 378 | "source": [ 379 | "acc = history.history['acc']\n", 380 | "val_acc = history.history['val_acc']\n", 381 | "loss = history.history['loss']\n", 382 | "val_loss = history.history['val_loss']" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": 15, 388 | "metadata": {}, 389 | "outputs": [ 390 | { 391 | "data": { 392 | "image/png": "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2LNnTyihF+qRRx7h73//e6nXE06WAIwx5crw4cOZOHHiCWUTJ05k+PDhIS3fqFGjUvWmmT8BTJs2jTp16pR4feWZJQBjTLkydOhQPvroo+ODv2zcuJGtW7fSq1ev4+3yk5OT6dChA++/f3Ifkhs3bqR9e9fLzMGDBxk2bBht2rThyiuv5ODBg8fnu/322493Jf3www8DrgfPrVu30rdvX/r27QtAUlISP/30EwBPPfUU7du3p3379se7kt64cSNt2rTh1ltvpV27dgwYMOCE7RQl2DoPHDjApZdeerx76LfffhuA0aNH07ZtWzp27HjSGAklYc8BGGMKtvj3sDvMI13V7QxdxxU4uV69enTv3p3p06czZMgQJk6cyDXXXIOIkJCQwJQpU6hVqxY//fQTPXr0YPDgwQWOhfvCCy+QmJjImjVrWL58OcnJycenjR07lnr16nHs2DH69evH8uXL+d3vfsdTTz3F7NmzadCgwQnrWrx4Ma+++ioLFixAVTnnnHPo06cPdevWZd26dbz11lv8+9//5pprruGdd9453hNoYQpa5/r162nUqBEfffQR4Lq03rlzJ1OmTOHbb79FRMJSLWVXAMaYciewGiiw+kdV+fOf/0zHjh256KKL2LJlC9u3by9wPXPnzj1+IO7YsSMdO3Y8Pm3SpEkkJyfTpUsXVq1aVWRHb/Pnz+fKK6+kevXq1KhRg6uuuop58+YB0KJFCzp37gwU3uV0qOvs0KEDM2fO5L777mPevHnUrl2b2rVrk5CQwM0338y7775LYv7RrkrArgCMMQUr5Ey9LA0ZMoS7776bJUuWkJ2dTdeuXQFITU0lMzOTxYsXExcXR1JSUtAuoIuyYcMG/v73v7No0SLq1q3LjTfeWKL15MnrShpcd9LFqQIK5qyzzmLJkiVMmzaNBx54gH79+vHQQw+xcOFCPvvsMyZPnsxzzz3HrFmzSrUduwIwxpQ7NWrUoG/fvvzqV7864eZvVlYWp5xyCnFxccyePZsfgg36HaB3795MmDABgJUrV7J8+XLAdSVdvXp1ateuzfbt25k+/efhSGrWrMm+fftOWlevXr147733yM7O5sCBA0yZMoVevXqV6nsWtM6tW7eSmJjIddddx7333suSJUvYv38/WVlZXHLJJTz99NMsW7asVNsGuwIwxpRTw4cP58orrzyhRdCIESO4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\n", 393 | "text/plain": [ 394 | "
" 395 | ] 396 | }, 397 | "metadata": { 398 | "needs_background": "light" 399 | }, 400 | "output_type": "display_data" 401 | } 402 | ], 403 | "source": [ 404 | "plot_loss(range(1, len(loss) + 1), loss, val_loss)" 405 | ] 406 | }, 407 | { 408 | "cell_type": "code", 409 | "execution_count": 16, 410 | "metadata": {}, 411 | "outputs": [ 412 | { 413 | "data": { 414 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEICAYAAABRSj9aAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO3deXxU9b3/8dcnJGyyBxQLsrghARIMIWhFVkHsglfcsHHDq7RatctVr62ttlrqfdQNe/VhpVYrt1T0aq1iXapAS/15tSwiqFSgNUogrEG2gBD4/P44Z8IkZpIJTDLJ4f18POaRmfM9y2dOkvd853vOnDF3R0REoisj3QWIiEjDUtCLiEScgl5EJOIU9CIiEaegFxGJOAW9iEjEKeiPMGbWwsx2mlmvVM6bTmZ2opk1yHnC1ddtZn82s6KGqMPMfmxmvzrU5UUSUdA3cWHQxm4HzGx33OMaA6c27r7f3du5+6epnLepMrM3zOz2Gqafb2ZrzaxFfdbn7uPdfVYK6jrLzIqrrfsud//W4a67jm26mf1HQ21DmiYFfRMXBm07d28HfAp8PW7aFwLHzDIbv8om7UngshqmXwb8zt33N3I96XQFUAZc3tgb1t9leinomzkz+5mZPW1mT5nZDuBSMzvdzN42s8/MrNTMfmlmWeH8mWGvrk/4+Hdh+ytmtsPM/s/M+tZ33rD9HDNbaWbbzOy/zez/mdmVCepOpsZvmtlqM9tqZr+MW7aFmT1gZlvM7F/AhFp20R+A7mb25bjls4GvADPDxxPNbKmZbTezT83sx7Xs7zdjz6muOszsajNbEe6rf5rZ1eH0jsAcoFfcu7Ojw9/lb+OWP8/MPgj30Twz6xfXVmJm3zez5eH+fsrMWtVSd3tgEnAdkGNmg6u1jwh/H9vMbI2ZXRZObxs+x0/DtgVm1qqmdyRhTaPC+/X6uwyXGRS+Ayszs/VmdouZ9TCzcjPrFDdfYdiuF49kubtuzeQGFANnVZv2M2Av8HWCF+42wFBgGJAJHA+sBK4P588EHOgTPv4dsBkoALKApwl6uvWd92hgB3Bu2PZ9YB9wZYLnkkyNLwAdgT4EPdGzwvbrgQ+AnkA2sCD4U064354AfhX3+NvAorjHY4AB4f7LC5/j18K2E+PXDbwZe0511RH+To4HLNzGbiA3bDsLKK7hd/nb8H5/YGe4XBbwQ+AjICtsLwHeBrqH214JXF3LPpgSLpMBvAI8ENfWN9zWReG+7woMDtseBeYCxwItgOFhPTXVXwKMOsS/y47ABuA7QCugA1AYtv0ZuCZuO/8dX79uSWRHugvQrR6/rMRBP6+O5W4C/je8X1N4x4fgROD9Q5j3KuBvcW0GlJIg6JOs8bS49j8AN4X3F8SHGkHv3GtZ9yiCF4pW4eN3gBtqmf8h4J7wfm1BX986XgK+Hd6vK+h/Cvw+ri0DWA8MDx+XAJPj2u8HHqpl238B7g3vXxaGamb4+MexfV9tmRbA58CAGtqSCfr6/F1eBixMMF8R8Ne4v41NQH6q/7+ifNPQTTSsiX9gZqeY2Z/Ct7fbgTsJemmJrI+7Xw60O4R5vxRfhwf/lSWJVpJkjUltC/iklnoB/gpsB75uZicDpwJPxdVyupn9xcw2mdk24OoaaqlJrXWY2dfM7J1wKOIzYHyS642tu3J97n6AYH/2iJsnqd9bOPQ2Aogd03k+nDc21HQc8M8aFj0GaJmgLRn1+btMVEOs3jwLzv6aAGx09yWHWNMRSUEfDdVP6XsUeB840d07ALcT9LAbUinBEAYAZmZUDaXqDqfGUoJgiKn19M/wRWcmwUHIy4CX3X1z3CyzgeeA49y9I/BYkrUkrMPM2gDPAncDx7h7J4IhiNh66zoNcx3QO259GQT7d20SdVV3ebjdV8xsPbCaIMCvCNvXACfUsNwGguGXmtp2AW3j6sskGEKKV5+/y0Q14O7lBL+fIoLf3//UNJ8kpqCPpvbANmCXmfUHvtkI23wJyDezr4f/9N8BujVQjc8A3w0P1GUD/5nEMjMJeoNXEZyJU72WMnffY2anAZNTUEcrgjDdBOw3s68BY+PaNwBdw4OkidY90cxGhQcsbyY4BvJOkrXFu5wgVAfH3S4meIfTmWBIboIFp5xmmllXM8vz4Iyk3wLTzax7ePD5jLCefwDtzezs8PEdBGP3tantd/4iwcHp68ODvR3MrDCufSbB7+6rYb1SDwr6aPoPgt7aDoJe1NMNvUF330AQHvcDWwh6Z+8SjPGmusZHCA4QLgcWEvSc66pvNfB3ggD+U7Xma4G7w7NDfkgQsodVh7t/BnyPYNihDLiA4MUw1v4+QS+1ODwL5ehq9X5AsH8eIXixmABMdPd9SdYGgJkNJxgGetjd18duYV3FwMXu/jHBQdP/DGtdAgwKV/E9YAWwOGz7OWDuvhW4geBFc23YFj+UVJOEv3N33waMA84neBFcCYyMW3YBwfj8O+6ecEhQambhAQ6RlLLgg0jrgAvc/W/prkeaPzNbADzu7r9Ndy3NjXr0kjJmNsHMOoXnc/+Y4PTKv6e5LImAcEhtIPC/6a6lOVLQSyoNB/5FMNRwNnCeuycauhFJipnNAl4FvuPuu9JdT3OkoRsRkYhTj15EJOKa3LUiunbt6n369El3GSIizcrixYs3u3uNpzQ3uaDv06cPixYtSncZIiLNipkl/IS4hm5ERCJOQS8iEnEKehGRiFPQi4hEnIJeRCTiFPQiImk2axb06QMZGcHPWYf99fNVNbnTK0VEjiSzZsHUqVBeHjz+5JPgMUBRUWq2oR69iEga3XbbwZCPKS8PpqeKgl5EJI0+/bR+0w+Fgl5EUq6hx5yjpFeCL8JMNP1QKOhFJKViY86ffALuB8ecFfY1mzYN2ratOq1t22B6qijoRSSlGmPMOUqKimDGDOjdG8yCnzNmpO5ALDTB69EXFBS4Lmom0nxlZAQ9+erM4MCBxq/nSGFmi929oKY29ehFJKUaY8xZ6kdBLyIp1RhjzlI/CnoRSanGGHOW+lHQiyRBpwvWT1ERFBcHY/LFxQr5dNMlEETq0BgfURdpSOrRi9RBpwtKc6egF6lDY3xEXaQhKehF6qDTBaW5U9CL1EGnC0pzp4OxInWIHXC97bZguKZXryDkj7gDse6wfzfs3Qp7y+DzsoP343/GT2/ZBbKHQnZh8LPNsel+FkckXQJB5EhzoAL2fpYgoOsI7wOfJ16vtQiCvWXngz/3lMJny8H3B/O07Qld4oK/SwG07Ng4zzviarsEgnr0Is2RO1TsrLkXXVePe9/22ted2R5adTkY1h1ygp+tqoV4yy5Vp2W2Cz4hVV1FOWxdClv+DlsWBj9Lnj/Y3qFf1fDvPBhatE7t/jrCKehF0mn/52EIJxj6SNjj3gpekXi9GS0PBnKrLtCmB3QaFBfUXRKEdyfIyErtc8xsC92+HNxiPi+DskVB8JcthA1zofh3QZtlQqfcg8GfPTR4sclokdq6jiAKepHD5QeCXnJtQyCJwrtiVy0rNsjqWDWMj+qduHddOb0LtGhTc++6qWjVBY4dH9xiytdW7fV/8hSs/lXQlnkUdM6PC/9COKpP036OTYiCXiTGPQzsLbBnc/Dz8/AWu1/TkMi+z4KwT6RFm6pB3K4vtBxS+zBIy85ByB9Jvdi2PaDteXDcecFjPwA7VlcN/5UPHTxO0Cq72nj/UGhzTPrqb8IU9BJNB/aFgVxDWH++BT6vKcjLahkOsTCosw/+bH9izQFdfVhE482HxjKgw8nBre+lwbQD+4KDu7HgL1sIH/zs4Att215Ve/1dhkBW+/Q9hyZCQS9NmzvsL08c1tWnxe7v25Z4nRmtgqBulQ0ts6FjzsH7rbpWbYvdz+p0ZPWum6qMLOiSH9xO+mYwrWIXlC2pGv5rng0XMOhwStXw75QLLVql7Smkg4JeGo8fCE7rqxLOtYR1rL22U/qyOlQN5PYnJQ7r2OPMozS2GyWZR8HRZwa3mD2bDx7s3fJ3KH0FPn4yaMvIgk6DDx7ozS6E9v0i/UKu8+jl0Ozfm8RQSLW2vVsTj2XHzsFuFderbpmdILC7ho+7pP4MEYkmdyhfU7XXv2URVOwI2jPbBef0x3+4q22vZtUh0Hn0kljsfOw6e9fV2ip2Jl5ni7ZVA7rz4GphXUOQZ3UIxmRFGoIZHNUruPU6P5jmB2D7RwcP9pYthI8ehAN7g/ZW3aqN9w+F1l3T9xwOg4L+SPP5Flg/l9Vvvk5W2TyO7biGlpn7Es/fsvPBQG7THToOqBrWNfW8M9s03vMROVSWAR37B7fjrwim7f88PNgb6/X/Hda9DIQjH0f1rTrk0zkfstql7SkkS0Efdfv3wua3YP3rUPpnKFsMOF13d2Tev8bwUelFbNmRzc692Uy+MptR4+MOSrbsHOlxS5EvaNEKsguCW8y+HeHB3lj4vwOfPhO0WUbwYa74IZ+Og6BFy/TUn4DG6KPGHbavCEJ9/euw4S/BWSvWArqeDt3Hcd5145nzVgH7D1R9ne/dO/jaNxGpw56N4Xj/woM9/883B20ZrYLhyvghnw4nN/jQZG1j9Ar6KNizEda/EfbaX4fda4Pp7U+G7uOCTx8eMyoYByf43tOafu1mwXd8ikg9ucOuT6oO+ZQtPvjJ56wO4cHeuA93te2Z0oO9OhgbNfv3wKY3g1Bf/+fgglEQnLXS/aww3McFH5evQa9ewfee1jRdRA6BGbTrE9x6XxRMO7A/eHcd3+v/x33Bh74AWnev2uvPHhqcSdYAkgp6M5sAPAi0AB5z9/+q1t4beBzoBpQBl7p7Sdj2C+CrBF9y8jrwHW9qbyOaOvfgAFFsnH3TgiDsM7Kg6xmQNw26j4fOpyY1pj5tWtUvuwZ9kYZIymW0gE4Dg9sJU4Jp+/fA1veqnua5ds7BZY4ZC2PfSHkpdQa9mbUAHgbGASXAQjN70d0/jJvtXmCmuz9pZmOAu4HLzOzLwBlAbjjfm8BI4C+pewoRtbs07LGHtz0bgukdc+DEbwbBfvSIQzriry/SEEmTFq2h67DgFrN3WzDMU7YwuOpoA0imR18IrHb3fwGY2WzgXCA+6HOA74f35wN/DO870BpoCRiQBWw4/LIjqKIcNi442Gvf9n4wvVW3g0Mx3ccFF35KgaIiBbtIk9CyI3QfE9waSDJB3wNYE/e4BBhWbZ73gEkEwzvnAe3NLNvd/8/M5gOlBEH/kLuvqL4BM5sKTAXodaQMFPuBYGw9dnbMpjeDD2pktAo+yt33suAgaqdcfZBIRA5Lqg7G3gQ8ZGZXAguAtcB+MzsR6A/0DOd73czOdPe/xS/s7jOAGRCcdZOimpqeXWsODsWsf+Pg6VidcuHkG4Jg73amPnAkIimVTNCvBY6Le9wznFbJ3dcR9Ogxs3bA+e7+mZldA7zt7jvDtleA04EqQR9Z+3bCxr8cPDtm+z+C6a27w5e+EgzFdD8r+MSpiEgDSSboFwInmVlfgoCfDHwjfgYz6wqUufsB4AcEZ+AAfApcY2Z3EwzdjASmp6j2pufA/uCgyvpwOGbz/wWnUrVoA0ePhBOuCXrtHQc0q4sliUjzVmfQu3uFmV0PvEZweuXj7v6Bmd0JLHL3F4FRwN1m5gRDN98OF38WGAMsJzgw+6q7z6m+jWZtZ3EQ7KWvB997uXdrML1zPpzyH0GvvduX9eUTIpI2+mRsfe3dBhvmHzw7ZufqYHrbnsEpj93HQfex0LpbeusUkSOKPhl7OA5UhF9cEA7HbHkHfH9w/eqjR0G/G4KA79BPwzEi0iQp6Ktzh53/jLso2LzgC6MtI7hWRc4PgnPas09rcleoExGpiYIegi+F3jDv4HDMruJg+lF9oPfkYDjmmDENdh0KEZGGdGQG/f69sOXtg732skXBB5iyOgSB3v/m4OyYdidoOEZEmr0jI+jdg68Mi50ds3F+cPlQawHZw2Dg7UGvPbsQMo6MXSIiR47optqeTbB+7sFz2stLguntToS+V4TDMaOD60yIiERYdIJ+/97gejGxXvvWJcH0lp2DS38ODE99bNcnrWWKiDS26AT95xth3liwzOADSrk/C4K9yxB976mIHNGiE/Rte8KYN4Jx9qz26a5GRKTJiE7QQ/CJVBERqUIXOhcRiTgFvYhIxCnoRUQiTkEvIhJxCnoRkYhT0IuIRJyCXkQk4hT0IiIRp6AXEYk4Bb2ISMQp6EVEIk5BLyIScQp6EZGIU9CLiEScgl5EJOIU9CIiEaegFxGJOAW9iEjEKehFRCJOQS8iEnEKehGRiFPQi4hEnIJeRCTiFPQiIhGnoBcRiTgFvYhIxCnoRUQiTkEvIhJxSQW9mU0ws4/MbLWZ3VpDe28zm2tmy8zsL2bWM66tl5n92cxWmNmHZtYndeWLiEhd6gx6M2sBPAycA+QAl5hZTrXZ7gVmunsucCdwd1zbTOAed+8PFAIbU1G4iIgkJ5kefSGw2t3/5e57gdnAudXmyQHmhffnx9rDF4RMd38dwN13unt5SioXEZGkJBP0PYA1cY9Lwmnx3gMmhffPA9qbWTZwMvCZmf3BzN41s3vCdwhVmNlUM1tkZos2bdpU/2chIiIJpepg7E3ASDN7FxgJrAX2A5nAmWH7UOB44MrqC7v7DHcvcPeCbt26pagkERGB5IJ+LXBc3OOe4bRK7r7O3Se5+6nAbeG0zwh6/0vDYZ8K4I9AfkoqFxGRpCQT9AuBk8ysr5m1BCYDL8bPYGZdzSy2rh8Aj8ct28nMYt30McCHh1+2iIgkq86gD3vi1wOvASuAZ9z9AzO708wmhrONAj4ys5XAMcC0cNn9BMM2c81sOWDAr1P+LEREJCFz93TXUEVBQYEvWrQo3WWIiDQrZrbY3QtqatMnY0VEIk5BLyIScQp6EZGIU9CLiEScgl5EJOIU9CIiEaegFxGJOAW9iEjEKehFRCJOQS8iEnEKehGRiFPQi4hEnIJeRCTiFPQiIhGnoBcRiTgFvYhIxCnoRUQiTkEvIhJxCnoRkYhT0IuIRJyCXkQk4hT0IiIRp6AXEYk4Bb2ISMQp6EVEIk5BLyIScQp6EZGIU9CLiEScgl5EJOIU9CIiEaegFxGJOAW9iEjEKehFRCJOQS8iEnEKehGRiFPQi4hEnIJeRCTiFPQiIhGXVNCb2QQz+8jMVpvZrTW09zazuWa2zMz+YmY9q7V3MLMSM3soVYWLiEhy6gx6M2sBPAycA+QAl5hZTrXZ7gVmunsucCdwd7X2u4AFh1+uiIjUVzI9+kJgtbv/y933ArOBc6vNkwPMC+/Pj283syHAMcCfD79cERGpr2SCvgewJu5xSTgt3nvApPD+eUB7M8s2swzgPuCm2jZgZlPNbJGZLdq0aVNylYuISFJSdTD2JmCkmb0LjATWAvuB64CX3b2ktoXdfYa7F7h7Qbdu3VJUkoiIAGQmMc9a4Li4xz3DaZXcfR1hj97M2gHnu/tnZnY6cKaZXQe0A1qa2U53/8IBXRERaRjJBP1C4CQz60sQ8JOBb8TPYGZdgTJ3PwD8AHgcwN2L4ua5EihQyIuINK46h27cvQK4HngNWAE84+4fmNmdZjYxnG0U8JGZrSQ48DqtgeoVEZF6MndPdw1VFBQU+KJFi9JdhohIs2Jmi929oKY2fTJWRCTiFPQiIhGnoBcRiTgFvYhIxCnoRUQiTkEvIhJxCnoRkYhT0IuIRJyCXkQk4hT0IiIRp6AXEYk4Bb2ISMQp6EVEIk5BLyIScQp6EZGIU9CLiEScgl5EJOIU9CIiEaegFxGJOAW9iEjEKehFRCJOQS8iEnEKehGRiFPQi4hEnIJeRCTiFPQiIhGnoBcRiTgFvYhIxCnoRUQiTkEvIhJxCnoRkYhT0IuIRJyCXkQk4hT0IiIRp6AXEYk4Bb2ISMQp6EVEIi4z3QWISGL79u2jpKSEPXv2pLsUaSJat25Nz549ycrKSnqZpILezCYADwItgMfc/b+qtfcGHge6AWXApe5eYmaDgUeADsB+YJq7P510dSJHuJKSEtq3b0+fPn0ws3SXI2nm7mzZsoWSkhL69u2b9HJ1Dt2YWQvgYeAcIAe4xMxyqs12LzDT3XOBO4G7w+nlwOXuPgCYAEw3s05JVydyhNuzZw/Z2dkKeQHAzMjOzq73O7xkxugLgdXu/i933wvMBs6tNk8OMC+8Pz/W7u4r3X1VeH8dsJGg1y8iSVLIS7xD+XtIJuh7AGviHpeE0+K9B0wK758HtDez7GrFFQItgX9W34CZTTWzRWa2aNOmTcnWLiIiSUjVWTc3ASPN7F1gJLCWYEweADM7FvgfYIq7H6i+sLvPcPcCdy/o1k0dfpFDNWsW9OkDGRnBz1mzDm99W7ZsYfDgwQwePJju3bvTo0ePysd79+5Nah1Tpkzho48+qnWehx9+mFmHW6wklMzB2LXAcXGPe4bTKoXDMpMAzKwdcL67fxY+7gD8CbjN3d9ORdEi8kWzZsHUqVBeHjz+5JPgMUBR0aGtMzs7m6VLlwLwk5/8hHbt2nHTTTdVmcfdcXcyMmruNz7xxBN1bufb3/72oRWYRhUVFWRmNo8TF5Pp0S8ETjKzvmbWEpgMvBg/g5l1NbPYun5AcAYO4fzPExyofTZ1ZYtIdbfddjDkY8rLg+mptnr1anJycigqKmLAgAGUlpYydepUCgoKGDBgAHfeeWflvMOHD2fp0qVUVFTQqVMnbr31VvLy8jj99NPZuHEjAD/60Y+YPn165fy33norhYWF9OvXj7feeguAXbt2cf7555OTk8MFF1xAQUFB5YtQvDvuuIOhQ4cycOBAvvWtb+HuAKxcuZIxY8aQl5dHfn4+xcXFAPz85z9n0KBB5OXlcVu4s2I1A6xfv54TTzwRgMcee4x/+7d/Y/To0Zx99tls376dMWPGkJ+fT25uLi+99FJlHU888QS5ubnk5eUxZcoUtm3bxvHHH09FRQUAW7durfK4QcVejWu7AV8BVhKMr98WTrsTmBjevwBYFc7zGNAqnH4psA9YGncbXNu2hgwZ4iIS+PDDD5Oe18wdvngzS00td9xxh99zzz3u7r5q1So3M1+4cGFl+5YtW9zdfd++fT58+HD/4IMP3N39jDPO8Hfffdf37dvngL/88svu7v69733P7777bnd3v+222/yBBx6onP+WW25xd/cXXnjBzz77bHd3v/vuu/26665zd/elS5d6RkaGv/vuu1+oM1bHgQMHfPLkyZXby8/P9xdffNHd3Xfv3u27du3yF1980YcPH+7l5eVVlo3V7O5eWlrqJ5xwgru7//rXv/ZevXp5WVmZu7vv3bvXt23b5u7uGzZs8BNPPLGyvn79+lWuL/bz0ksv9Tlz5ri7+8MPP1z5POurpr8LYJEnyNWkxujd/WV3P9ndT3D3aeG02939xfD+s+5+UjjP1e7+eTj9d+6e5e6D425ffAkWkcPWq1f9ph+uE044gYKCgsrHTz31FPn5+eTn57NixQo+/PDDLyzTpk0bzjnnHACGDBlS2auubtKkSV+Y580332Ty5MkA5OXlMWDAgBqXnTt3LoWFheTl5fHXv/6VDz74gK1bt7J582a+/vWvA8GHjtq2bcsbb7zBVVddRZs2bQDo0qVLnc97/PjxdO7cGQg6yrfeeiu5ubmMHz+eNWvWsHnzZubNm8fFF19cub7Yz6uvvrpyKOuJJ55gypQpdW4vFXQJBJGImDYN2ratOq1t22B6QzjqqKMq769atYoHH3yQefPmsWzZMiZMmFDjud4tW7asvN+iRYuEwxatWrWqc56alJeXc/311/P888+zbNkyrrrqqkP6VHFmZiYHDgTnjVRfPv55z5w5k23btrFkyRKWLl1K165da93eyJEjWblyJfPnzycrK4tTTjml3rUdCgW9SEQUFcGMGdC7N5gFP2fMOPQDsfWxfft22rdvT4cOHSgtLeW1115L+TbOOOMMnnnmGQCWL19e4zuG3bt3k5GRQdeuXdmxYwfPPfccAJ07d6Zbt27MmTMHCMK7vLyccePG8fjjj7N7924AysrKAOjTpw+LFy8G4NlnEx9e3LZtG0cffTSZmZm8/vrrrF0bnKcyZswYnn766cr1xX4CXHrppRQVFTVabx4U9CKRUlQExcVw4EDwszFCHiA/P5+cnBxOOeUULr/8cs4444yUb+OGG25g7dq15OTk8NOf/pScnBw6duxYZZ7s7GyuuOIKcnJyOOeccxg2bFhl26xZs7jvvvvIzc1l+PDhbNq0ia997WtMmDCBgoICBg8ezAMPPADAzTffzIMPPkh+fj5bt25NWNNll13GW2+9xaBBg5g9ezYnnXQSEAwt3XLLLYwYMYLBgwdz8803Vy5TVFTEtm3buPjii1O5e2plHh6RbioKCgp80aJF6S5DpElYsWIF/fv3T3cZTUJFRQUVFRW0bt2aVatWMX78eFatWtVsTnGMmT17Nq+99lpSp50mUtPfhZktdveCmuZvXntIRI5YO3fuZOzYsVRUVODuPProo80u5K+99lreeOMNXn311UbdbvPaSyJyxOrUqVPluHlz9cgjj6RluxqjFxGJOAW9iEjEKehFRCJOQS8iEnEKehFJaPTo0V/48NP06dO59tpra12uXbt2AKxbt44LLrigxnlGjRpFXadST58+nfK4K7V95Stf4bPPPkumdImjoBeRhC655BJmz55dZdrs2bO55JJLklr+S1/6Uq2fLK1L9aB/+eWX6dSp+XwbqbtXXkohnRT0Is3F4u/CG6NSe1v83Vo3ecEFF/CnP/2p8ktGiouLWbduHWeeeWblee35+fkMGjSIF1544QvLFxcXM3DgQCC4PMHkyZPp378/5513XuVlByA4vzx2ieM77rgDgF/+8pesW7eO0aNHM3r0aCC4NMHmzZsBuP/++xk4cCADBw6svMRxcXEx/fv355prrmHAgAGMHz++ynZi5syZw7Bhwzj11FM566yz2LBhAxCcqz9lyhQGDRpEbm5u5SUUXn31VfLz88nLy2Ps2LFAcH3+e++9t3KdAwcOpLi4mOLiYvr168fll1/OwIEDWbNmTY3PD2DhwoV8+ctfJi8vj8LCQnbs2MGIESOqXH55+PDhvJI/md0AAAlGSURBVPfee7X+nuqi8+hFJKEuXbpQWFjIK6+8wrnnnsvs2bO56KKLMDNat27N888/T4cOHdi8eTOnnXYaEydOTPidpo888ght27ZlxYoVLFu2jPz8/Mq2adOm0aVLF/bv38/YsWNZtmwZN954I/fffz/z58+na9euVda1ePFinnjiCd555x3cnWHDhjFy5Eg6d+7MqlWreOqpp/j1r3/NRRddxHPPPcell15aZfnhw4fz9ttvY2Y89thj/OIXv+C+++7jrrvuomPHjixfvhwIrhm/adMmrrnmGhYsWEDfvn2rXLcmkVWrVvHkk09y2mmnJXx+p5xyChdffDFPP/00Q4cOZfv27bRp04Z///d/57e//S3Tp09n5cqV7Nmzh7y8vHr93qpT0Is0F0Omp2WzseGbWND/5je/AYJhiR/+8IcsWLCAjIwM1q5dy4YNG+jevXuN61mwYAE33ngjALm5ueTm5la2PfPMM8yYMYOKigpKS0v58MMPq7RX9+abb3LeeedVXkly0qRJ/O1vf2PixIn07duXwYMHA4kvhVxSUsLFF19MaWkpe/fupW/fvgC88cYbVYaqOnfuzJw5cxgxYkTlPMlcyrh3796VIZ/o+ZkZxx57LEOHDgWgQ4cOAFx44YXcdddd3HPPPTz++ONceeWVdW6vLpEZukn1d2WKSODcc89l7ty5LFmyhPLycoYMGQIEFwnbtGkTixcvZunSpRxzzDGHdEngjz/+mHvvvZe5c+eybNkyvvrVrx7SemJilziGxJc5vuGGG7j++utZvnw5jz766GFfyhiqXs44/lLG9X1+bdu2Zdy4cbzwwgs888wzFKXgynSRCPrYd2V+8knwnTqx78pU2Iscvnbt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\n", 415 | "text/plain": [ 416 | "
" 417 | ] 418 | }, 419 | "metadata": { 420 | "needs_background": "light" 421 | }, 422 | "output_type": "display_data" 423 | } 424 | ], 425 | "source": [ 426 | "plot_accuracy(range(1, len(loss) + 1), acc, val_acc)" 427 | ] 428 | }, 429 | { 430 | "cell_type": "code", 431 | "execution_count": 17, 432 | "metadata": {}, 433 | "outputs": [], 434 | "source": [ 435 | "y_pred = custom_vgg_model.predict(test_flow)\n", 436 | "y_test = test_flow.classes" 437 | ] 438 | }, 439 | { 440 | "cell_type": "code", 441 | "execution_count": 18, 442 | "metadata": {}, 443 | "outputs": [ 444 | { 445 | "name": "stdout", 446 | "output_type": "stream", 447 | "text": [ 448 | "ROC-AUC Score: 0.9600932210254477\n", 449 | "AP Score: 0.9325796549056171\n", 450 | "\n", 451 | " precision recall f1-score support\n", 452 | "\n", 453 | " 0 0.97 0.92 0.94 10735\n", 454 | " 1 0.93 0.97 0.95 10856\n", 455 | "\n", 456 | " accuracy 0.95 21591\n", 457 | " macro avg 0.95 0.95 0.95 21591\n", 458 | "weighted avg 0.95 0.95 0.95 21591\n", 459 | "\n" 460 | ] 461 | } 462 | ], 463 | "source": [ 464 | "print(\"ROC-AUC Score:\", metrics.roc_auc_score(y_test, y_pred))\n", 465 | "print(\"AP Score:\", metrics.average_precision_score(y_test, y_pred))\n", 466 | "print()\n", 467 | "print(metrics.classification_report(y_test, y_pred > 0.5))" 468 | ] 469 | }, 470 | { 471 | "cell_type": "code", 472 | "execution_count": null, 473 | "metadata": {}, 474 | "outputs": [], 475 | "source": [] 476 | } 477 | ], 478 | "metadata": { 479 | "kernelspec": { 480 | "display_name": "Tensorflow 2.1/Keras Py3.7", 481 | "language": "python", 482 | "name": "tensorflow210_py37" 483 | }, 484 | "language_info": { 485 | "codemirror_mode": { 486 | "name": "ipython", 487 | "version": 3 488 | }, 489 | "file_extension": ".py", 490 | "mimetype": "text/x-python", 491 | "name": "python", 492 | "nbconvert_exporter": "python", 493 | "pygments_lexer": "ipython3", 494 | "version": "3.7.5" 495 | } 496 | }, 497 | "nbformat": 4, 498 | "nbformat_minor": 4 499 | } 500 | -------------------------------------------------------------------------------- /custom-arch/custom_cnn.ipynb: -------------------------------------------------------------------------------- 1 | {"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"#!pip install keras-vggface","execution_count":3,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!pip install opencv-python\n#!pip install --user tqdm","execution_count":5,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%matplotlib inline\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport numpy as np\nimport math\nimport copy\nimport numpy as np\n\nfrom keras.models import Sequential, Model\nfrom keras.layers import Input, Dense, Flatten, Dropout, Activation, Lambda, Permute, Reshape\nfrom keras.layers import Convolution2D, ZeroPadding2D, MaxPooling2D\nfrom keras_vggface.vggface import VGGFace\nfrom keras_vggface import utils\nfrom keras.preprocessing import image\nfrom keras.preprocessing.image import ImageDataGenerator\n\nfrom sklearn.datasets import load_files \nfrom keras.utils import np_utils\nimport numpy as np\nfrom glob import glob\nimport pandas as pd\nimport cv2\nimport scipy.misc\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm","execution_count":6,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# load dataset\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"base_path = '/kaggle/input/140k-real-and-fake-faces/real_vs_fake/real-vs-fake/'\nimage_gen = ImageDataGenerator(rescale=1./255.)\nbatch_size = 64\ntrain_flow = image_gen.flow_from_directory(\n base_path + 'train/',\n target_size=(224, 224),\n batch_size=batch_size,\n class_mode='binary'\n)\nvalid_flow = image_gen.flow_from_directory(\n base_path + 'valid/',\n target_size=(224, 224),\n batch_size=batch_size,\n class_mode='binary'\n)\ntest_flow = image_gen.flow_from_directory(\n base_path + 'test/',\n target_size=(224, 224),\n batch_size=1,\n shuffle=False,\n class_mode='binary'\n)","execution_count":7,"outputs":[{"output_type":"stream","text":"Found 100000 images belonging to 2 classes.\nFound 20000 images belonging to 2 classes.\nFound 20000 images belonging to 2 classes.\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"# Custom Architecture"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D\nfrom keras.layers import Dropout, Flatten, Dense\nfrom keras.models import Sequential\nfrom keras.layers.normalization import BatchNormalization\n\"\"\"\n Propsoed CNN architecture.\n \n\"\"\"\n\nmodel = Sequential()\n\n# Pamameters Initialization\ninput_shape = (224,224,3)\nactivation = 'relu'\npadding = 'same'\ndroprate = 0.1\nepsilon=0.001\n\nmodel = Sequential()\nmodel.add(BatchNormalization(input_shape=input_shape))\nmodel.add(Conv2D(filters=16, kernel_size=3, activation=activation, padding=padding))\nmodel.add(MaxPooling2D(pool_size=2))\nmodel.add(BatchNormalization(epsilon=epsilon))\n\n\nmodel.add(Conv2D(filters=32, kernel_size=3, activation=activation, padding=padding))\nmodel.add(MaxPooling2D(pool_size=2))\nmodel.add(BatchNormalization(epsilon=epsilon))\nmodel.add(Dropout(droprate))\n\nmodel.add(Conv2D(filters=64, kernel_size=3, activation=activation, padding=padding))\nmodel.add(MaxPooling2D(pool_size=2))\nmodel.add(BatchNormalization(epsilon=epsilon))\nmodel.add(Dropout(droprate))\n\nmodel.add(Conv2D(filters=128, kernel_size=3, activation=activation, padding=padding))\nmodel.add(MaxPooling2D(pool_size=2))\nmodel.add(BatchNormalization(epsilon=epsilon))\nmodel.add(Dropout(droprate))\n\nmodel.add(Conv2D(filters=256, kernel_size=3, activation=activation, padding=padding))\nmodel.add(MaxPooling2D(pool_size=2))\nmodel.add(BatchNormalization(epsilon=epsilon))\nmodel.add(Dropout(droprate))\n\nmodel.add(Conv2D(filters=512, kernel_size=3, activation=activation, padding=padding))\nmodel.add(MaxPooling2D(pool_size=2))\nmodel.add(BatchNormalization(epsilon=epsilon))\nmodel.add(Dropout(droprate))\n\nmodel.add(GlobalAveragePooling2D())\n#model.add(Flatten())\n#model.add(Dense(256, kernel_initializer='glorot_normal', activation='relu'))\n#model.add(Dropout(0.5))\n \n#model.add(Dense(128, kernel_initializer='glorot_normal', activation='relu'))\n#model.add(Dropout(0.5))\n#model.add(Dropout(droprate))\nmodel.add(Dense(1, activation='sigmoid'))\n\nmodel.summary() # Summary of the architecture","execution_count":9,"outputs":[{"output_type":"stream","text":"Model: \"sequential_4\"\n_________________________________________________________________\nLayer (type) Output Shape Param # \n=================================================================\nbatch_normalization_8 (Batch (None, 224, 224, 3) 12 \n_________________________________________________________________\nconv2d_7 (Conv2D) (None, 224, 224, 16) 448 \n_________________________________________________________________\nmax_pooling2d_7 (MaxPooling2 (None, 112, 112, 16) 0 \n_________________________________________________________________\nbatch_normalization_9 (Batch (None, 112, 112, 16) 64 \n_________________________________________________________________\nconv2d_8 (Conv2D) (None, 112, 112, 32) 4640 \n_________________________________________________________________\nmax_pooling2d_8 (MaxPooling2 (None, 56, 56, 32) 0 \n_________________________________________________________________\nbatch_normalization_10 (Batc (None, 56, 56, 32) 128 \n_________________________________________________________________\ndropout_6 (Dropout) (None, 56, 56, 32) 0 \n_________________________________________________________________\nconv2d_9 (Conv2D) (None, 56, 56, 64) 18496 \n_________________________________________________________________\nmax_pooling2d_9 (MaxPooling2 (None, 28, 28, 64) 0 \n_________________________________________________________________\nbatch_normalization_11 (Batc (None, 28, 28, 64) 256 \n_________________________________________________________________\ndropout_7 (Dropout) (None, 28, 28, 64) 0 \n_________________________________________________________________\nconv2d_10 (Conv2D) (None, 28, 28, 128) 73856 \n_________________________________________________________________\nmax_pooling2d_10 (MaxPooling (None, 14, 14, 128) 0 \n_________________________________________________________________\nbatch_normalization_12 (Batc (None, 14, 14, 128) 512 \n_________________________________________________________________\ndropout_8 (Dropout) (None, 14, 14, 128) 0 \n_________________________________________________________________\nconv2d_11 (Conv2D) (None, 14, 14, 256) 295168 \n_________________________________________________________________\nmax_pooling2d_11 (MaxPooling (None, 7, 7, 256) 0 \n_________________________________________________________________\nbatch_normalization_13 (Batc (None, 7, 7, 256) 1024 \n_________________________________________________________________\ndropout_9 (Dropout) (None, 7, 7, 256) 0 \n_________________________________________________________________\nconv2d_12 (Conv2D) (None, 7, 7, 512) 1180160 \n_________________________________________________________________\nmax_pooling2d_12 (MaxPooling (None, 3, 3, 512) 0 \n_________________________________________________________________\nbatch_normalization_14 (Batc (None, 3, 3, 512) 2048 \n_________________________________________________________________\ndropout_10 (Dropout) (None, 3, 3, 512) 0 \n_________________________________________________________________\nglobal_average_pooling2d_2 ( (None, 512) 0 \n_________________________________________________________________\ndense_2 (Dense) (None, 1) 513 \n=================================================================\nTotal params: 1,577,325\nTrainable params: 1,575,303\nNon-trainable params: 2,022\n_________________________________________________________________\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"# Model Compile"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Parameters Initialization\nfrom keras.optimizers import rmsprop,SGD,Adam,Adadelta\n\n#opt = rmsprop(lr=0.0001, decay=1e-6)\n\nmodel.compile(loss='binary_crossentropy',optimizer=Adam(0.0001), metrics=['accuracy'])","execution_count":10,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train Custom Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_steps = 40000//batch_size\nvalid_steps = 5000//batch_size\nhistory = model.fit_generator(\n train_flow,\n epochs=10,\n steps_per_epoch = train_steps,\n validation_data = valid_flow,\n validation_steps = valid_steps\n)","execution_count":11,"outputs":[{"output_type":"stream","text":"Epoch 1/10\n625/625 [==============================] - 335s 537ms/step - loss: 0.5635 - accuracy: 0.7061 - val_loss: 0.6069 - val_accuracy: 0.6843\nEpoch 2/10\n625/625 [==============================] - 328s 524ms/step - loss: 0.4633 - accuracy: 0.7843 - val_loss: 0.5487 - val_accuracy: 0.7542\nEpoch 3/10\n625/625 [==============================] - 295s 471ms/step - loss: 0.3997 - accuracy: 0.8206 - val_loss: 0.5823 - val_accuracy: 0.8015\nEpoch 4/10\n625/625 [==============================] - 266s 425ms/step - loss: 0.3469 - accuracy: 0.8475 - val_loss: 0.3706 - val_accuracy: 0.8456\nEpoch 5/10\n625/625 [==============================] - 264s 422ms/step - loss: 0.3057 - accuracy: 0.8696 - val_loss: 0.1914 - val_accuracy: 0.8522\nEpoch 6/10\n625/625 [==============================] - 264s 422ms/step - loss: 0.2637 - accuracy: 0.8910 - val_loss: 0.4618 - val_accuracy: 0.7891\nEpoch 7/10\n625/625 [==============================] - 254s 406ms/step - loss: 0.2326 - accuracy: 0.9047 - val_loss: 0.2124 - val_accuracy: 0.9002\nEpoch 8/10\n625/625 [==============================] - 257s 410ms/step - loss: 0.2049 - accuracy: 0.9173 - val_loss: 0.1553 - val_accuracy: 0.9165\nEpoch 9/10\n625/625 [==============================] - 260s 417ms/step - loss: 0.1826 - accuracy: 0.9264 - val_loss: 0.2844 - val_accuracy: 0.9181\nEpoch 10/10\n625/625 [==============================] - 256s 409ms/step - loss: 0.1716 - accuracy: 0.9322 - val_loss: 0.2426 - val_accuracy: 0.9109\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save(\"custom_model.h5\") # save model","execution_count":12,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\"\"\"\nPlot the training and validation loss\nepochs - list of epoch numbers\nloss - training loss for each epoch\nval_loss - validation loss for each epoch\n\"\"\"\ndef plot_loss(epochs, loss, val_loss):\n plt.plot(epochs, loss, 'bo', label='Training Loss')\n plt.plot(epochs, val_loss, 'orange', label = 'Validation Loss')\n plt.title('Training and Validation Loss')\n plt.legend()\n plt.show()\n\"\"\"\nPlot the training and validation accuracy\nepochs - list of epoch numbers\nacc - training accuracy for each epoch\nval_acc - validation accuracy for each epoch\n\"\"\"\ndef plot_accuracy(epochs, acc, val_acc):\n plt.plot(epochs, acc, 'bo', label='Training accuracy')\n plt.plot(epochs, val_acc, 'orange', label = 'Validation accuracy')\n plt.title('Training and Validation Accuracy')\n plt.legend()\n plt.show()","execution_count":13,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"acc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']","execution_count":15,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_loss(range(1, len(loss) + 1), loss, val_loss)\nplot_accuracy(range(1, len(loss) + 1), acc, val_acc)","execution_count":16,"outputs":[{"output_type":"display_data","data":{"text/plain":"
","image/png":"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\n"},"metadata":{"needs_background":"light"}},{"output_type":"display_data","data":{"text/plain":"
","image/png":"iVBORw0KGgoAAAANSUhEUgAAAXoAAAEICAYAAABRSj9aAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO3deXyU1dXA8d9JwhYCYUdkC1sBCQmEsAiIKIrQCiguYIMLvsrrhlZbl6ottpXa1xVb0YoKak1F1CJoEVcUrUVZZZEdAoR938KW5Lx/3EmYhCyTMMkzmZzv5zOfmWc/82Ry5s597nOvqCrGGGPCV4TXARhjjClbluiNMSbMWaI3xpgwZ4neGGPCnCV6Y4wJc5bojTEmzFmir2REJFJEjohIi2Cu6yURaSsiZdJOOP++ReRTEUkpizhE5Hci8vfSbm9MYSzRhzhfos15ZIvIMb/pAhNOUVQ1S1VjVHVzMNcNVSLyhYj8voD5V4nIVhEp0f+Aqg5U1dQgxHWJiKTl2/efVPW2s913McdUEbmvrI5hQpMl+hDnS7QxqhoDbAaG+M07I+GISFT5RxnSXgeuL2D+9cBbqppdvuF46kZgn++5XNnn0luW6Cs4EXlcRN4RkbdF5DAwSkTOF5F5InJARLaLyF9FpIpv/ShfqS7ON/2Wb/nHInJYRP4rIq1Kuq5v+WARWSMiB0XkbyLyHxG5qZC4A4nxf0VknYjsF5G/+m0bKSLPicheEVkPDCriFP0LOEdEevttXx/4OfCmb3qoiCzxvafNIvK7Is73tznvqbg4ROQWEVnp2+96EbnFNz8W+BBo4ffrrJHvb/m63/ZXiMgK3zn6UkTa+y1LF5H7RGSZ73y/LSLViog7BhgO3A6cJyJd8i3v5/t7HBSRLSJyvW9+tO89bvYtmysi1Qr6ReKLqb/vdYk+l75tOovI5yKyT0R2iMgDItJURDJEpI7fej19y+3LI1Cqao8K8gDSgEvyzXscOAkMwX1x1wC6Az2BKKA1sAa4y7d+FKBAnG/6LWAPkAxUAd7BlXRLum4j4DAwzLfsPuAUcFMh7yWQGGcAsUAcriR6iW/5XcAKoBlQH5jrPsqFnrcpwN/9pu8EFvhNXwzE+85fou89Xu5b1tZ/38C3Oe+puDh8f5PWgPiOcQxI8C27BEgr4G/5uu91R+CIb7sqwMO+c1TFtzwdmAec4zv2GuCWIs7BaN82EcDHwLN+y1r5/nbX+s59A6CLb9nLwBdAEyAS6OuLp6D404H+pfxcxgI7gXuAakBtoIdv2afArX7H+RvwnNf/jxXp4XkA9ijBH6vwRP9lMdv9BnjX97qg5O2fBIcCy0ux7s3AN37LBNhOIYk+wBh7+S3/F/Ab3+u5/kkNVzrXIvbdH/dFUc03/T0wtoj1XwCe8r0uKtGXNI6PgDt9r4tL9H8A/um3LALYAfT1TacDI/2WPwu8UMSxvwKe9r2+3pdUo3zTv8s59/m2iQROAJ0KWBZIoi/J5/J6/L58862XAnzt99nYBSQF+/8rnB9WdRMetvhPiEgHEfm37+ftIeCPuFJaYXb4vc4AYkqx7rn+caj7r0wvbCcBxhjQsYBNRcQL8DVwEBgiIj8DugJv+8Vyvoh8JSK7ReQgcEsBsRSkyDhE5HIR+d5XFXEAGBjgfnP2nbs/ddcS0oGmfusE9HfzVb31A3Ku6Uz3rZtT1dQcWF/Apo2BqoUsC0RJPpfNgXWF7Gc6kCiu9dcgYLeqLiplTJWSJfrwkL9J38vAcqCtqtYGfo8rYZel7bgqDABERMiblPI7mxi34xJDjiKbf/q+dP4B3IArOc5S1T1+q0wF3geaq2os8GqAsRQah4jUAN4DngAaq2odXBVEzn6La4a5DWjpt78I3PndGkBc+d3gO+7HIrIDl1Cr+uaDS8htCthuJ676paBlR4Fov/iicFVI/kryuSwsBlQ1A/f3ScH9/f5R0HqmcJbow1MtXAn2qIh0BP63HI75EZAkIkN8//T3AA3LKMZpwK98F+rqAw8GsM0buNLgzb7X+WPZp6rHRaQXMDIIcVTDJdPdQJaIXA4M8Fu+E2ggIrWK2PdQEenvu2B5P64e/fsAY/N3Ay6pdvF7jPDtvy6uSm6QuCanUSLSQEQSVTUL12ppgoic47v43McXzyqglohc5pseh6u7L0pRf/OZuIvTd4lIVRGpLSI9/Ja/ifvb/cIXrykBS/Th6de4JnSHcaWod8r6gKq6E5c8ngX24kpni3F1vMGO8SXcBcJlwHxcybm4+NYDPwDVgX/nW3w78ISvdcjDuCR7VnGo6gHgXly1wz7gatyXYc7y5bhSapqvFUqjfPGuwJ2fl3BfFoOAoap6KsDYABCRvrhqoImquiPn4YsrDRihqhtxF00f9MW6COjs28W9wEpgoW/ZnwFR1f3AWNyX5lbfMv+qpIIU+jdX1YPApcBVuDr4NcCFftvOxV0z+F5VC60SNAUT3wUOY4JKRCJx1Q9Xq+o3XsdjKj4RmQtMVtXXvY6lorESvQkaERkkIrG+9ty/AzJxpWhjzoqvSi0eeNfrWCoiS/QmmPoCG3Dt0AcBV6hqYVU3xgRERFKB2cA9qnrU63gqIqu6McaYMGclemOMCXMh2VdEgwYNNC4uzuswjDGmwli4cOEeVS2wSXNIJvq4uDgWLFjgdRjGGFNhiEihd4hb1Y0xxoQ5S/TGGBPmLNEbY0yYC8k6+oKcOnWK9PR0jh8/7nUoJkRUr16dZs2aUaVKcV2sGFO5VZhEn56eTq1atYiLi8N1jGgqM1Vl7969pKen06pVq+I3MKYSqzBVN8ePH6d+/fqW5A0AIkL9+vXtF54JC6mpEBcHERHuOfWsh5/Pq8KU6AFL8iYP+zyYcJCaCmPGQEaGm960yU0DpKQE5xgVpkRvjDHh6JFHTif5HBkZbn6wWKIPwN69e+nSpQtdunThnHPOoWnTprnTJ0+eDGgfo0ePZvXq1UWuM3HiRFKD/ZvNGBPSNm8u2fzSqFBVNyWRmuq+ETdvhhYtYPz40v8Mql+/PkuWLAHgscceIyYmht/85jd51skdhDei4O/OKVOmFHucO++8s3QBeigzM5OoqLD9GBlT5lq0cNU1Bc0PlrAs0efUeW3aBKqn67yCXVhet24d8fHx3HbbbSQlJbF9+3bGjBlDcnIynTp14o9//GPuun379mXJkiVkZmZSp04dHnroIRITEzn//PPZtWsXAI8++igTJkzIXf+hhx6iR48etG/fnu+++w6Ao0ePctVVV5GYmMh1111HcnJy7peQv3HjxtG9e/fc+HJ6KV2zZg0XX3wxiYmJJCUlkZaWBsCf//xnOnfuTGJiIo/4fjPmxAywY8cO2rZtC8Crr77KyJEjufzyyxk8eDCHDh3i4osvJikpiYSEBD76KHcgJaZMmUJCQgKJiYmMHj2aAwcO0Lp1azIzMwE4cOAArVq1IisrK2h/F2MCVdYXQQMxfjxER+edFx3t5gdNTkk0lB7dunXT/H766acz5hWmZUtVl+LzPlq2DHgXhRo3bpw+9dRTqqq6du1aFRH94Ycfcpfv3btXVVVPnTqlffv21RUrVqiqap8+fXTx4sV66tQpBXTWrFmqqnrvvffqE088oaqqjzzyiD733HO56z/wwAOqqjpjxgy97LLLVFX1iSee0DvuuENVVZcsWaIRERG6ePHiM+LMiSM7O1tHjhyZe7ykpCSdOXOmqqoeO3ZMjx49qjNnztS+fftqRkZGnm1zYlZV3b59u7Zp00ZVVV955RVt0aKF7tu3T1VVT548qYcOHVJV1Z07d2rbtm1z42vfvn3u/nKeR40apR9++KGqqk6cODH3fZZGST4Xxvh76y3V6Oi8OSI62s33IpaWLVVF3HNpYgAWaCE5NSxL9OVR55WjTZs2dO/ePXf67bffJikpiaSkJFauXMlPP/10xjY1atRg8ODBAHTr1i23VJ3f8OHDz1jn22+/ZeRIN3Z1YmIinTp1KnDbL774gh49epCYmMjXX3/NihUr2L9/P3v27GHIkCGAu+EoOjqazz//nJtvvpkaNWoAUK9evWLf98CBA6lbty7gCgsPPvggCQkJDBw4kC1btrBnzx6+/PJLRowYkbu/nOdbbrkltyprypQpjB49utjjGRNs5XERNFApKZCWBtnZ7jlYrW1yhGWiL6xuK5h1Xjlq1qyZ+3rt2rU8//zzfPnllyxdupRBgwYV2M67atWqua8jIyNzqzHyq1at2hnraAADxWRkZHDXXXcxffp0li5dys0335wbR0FNElW1wPlRUVFkZ2cDnPE+/N/3m2++ycGDB1m0aBFLliyhQYMGHD9+vND9XnjhhaxZs4Y5c+ZQpUoVOnToUOx7MibYyrNA6LWwTPTlUudVgEOHDlGrVi1q167N9u3b+eSTT4J+jL59+zJt2jQAli1bVuAvhmPHjhEREUGDBg04fPgw77//PgB169alQYMGfPjhh4BL3hkZGQwcOJDXXnuNY8eOAbBv3z7AdRe9cOFCAN57771CYzp48CCNGjUiKiqKzz77jK1btwJwySWXMHXq1Nz95TwDjBo1ipSUFCvNG8+UZ4HQa2GZ6FNSYNIkaNkSRNzzpEnB/zmUX1JSEueddx7x8fHceuut9OnTJ+jHGDt2LFu3biUhIYFnnnmG+Ph4YmNj86xTv359brzxRuLj47nyyivp2bNn7rLU1FSeeeYZEhIS6Nu3L7t37+byyy9n0KBBJCcn06VLF5577jkA7r//fp5//nl69+7N/v37C43p+uuv57vvviM5OZl3332Xdu3aAZCQkMADDzxAv3796NKlC/fff3/uNikpKRw8eJARI0YE8/QYEzCvCoReCMkxY5OTkzX/wCMrV66kY8eOHkUUOjIzM8nMzKR69eqsXbuWgQMHsnbt2grXxHHq1Kl88sknATU7LYp9LszZCGYzbK+JyEJVTS5oWcXKDoYjR44wYMAAMjMzUVVefvnlCpfkb7/9dj7//HNmz57tdSjGQ6GQZFNSKm5iL4mKlSEMderUya03r6heeuklr0MwHiuP/l1yqUL2Scg8ClkZkJlx5jMKtTtATBuICL+0GH7vyBgT8nKaNopkU73KcaKrZhBdLYPJEzJIGZzhknJBCTkrgGUFzdfswAKLqAaxHSE2HurEn36ObuEu+FVQluiNMeUrO4uOdT7jyaGTGZo0k+pVT+RdXlyNnkRAZE2IiobI6LzP1RudOS/nOapm4cuyM+HQSji4HA4sh11fQdpbp48ZVQtiO+VN/rHx7ngV4AvAEr0xpnwcXgcbXocNr/PxA1vZc7g+r339P2za05KME9FknIymZu1o/vZiIUk553VE1bJJrg165J0+eQAOrnCJP+cLIH06rH/19DrVGpxZ+o/tBFXrBD++s2CJ3hhTdjKPwub3YcNk2PW1K403GcTcjOcZev8QDh4+ffNgdLRrBk0z78LNo2odaNjHPXKowvFdpxN/zvOG1yHzyOn1opud+QVQu6P7svJAWLajLwv9+/c/4waoCRMmcMcddxS5XUxMDADbtm3j6quvLnTf+ZuT5jdhwgQy/O7X/vnPf86BAwcCCd2Y8qUKe+bB92PgX01g3o2QsRUS/wzDNkP/f9Mv5SomvlS13O91OWsiUKMxnDMAOtwDPV+By/4L1xyCYWlw4UfQ5S/QqD8c3wGr/wbzboLZyTAtBma2g7nDYenvYdM0OPgTZJ8q87CtRB+g6667jqlTp3LZZZflzps6dSpPPfVUQNufe+65Rd5dWpwJEyYwatQoon13eMyaNavU+/JCbudKhXTjbMLAsZ2Q9g9YP9nVd0dGQ8trofXN0LDvGdUtYdW0UQRqtnSPpr84PT87E46sz1v6P7gcts4E9fXYGlHFtfiJ7QR1OsN5vw161ZT91wXo6quv5qOPPuLECXfhKC0tjW3bttG3b9/ctu1JSUl07tyZGTNmnLF9Wloa8fHxgOuiYOTIkSQkJDBixIjcrgfAtTHP6eZ43LhxAPz1r39l27ZtXHTRRVx00UWA655gz549ADz77LPEx8cTHx+f281xWloaHTt25NZbb6VTp04MHDgwz3FyfPjhh/Ts2ZOuXbtyySWXsHPnTsC11x89ejSdO3cmISEhtxuF2bNnk5SURGJiIgMGDABcH/1PP/107j7j4+NJS0vLjeGOO+4gKSmJLVu2FPj+AObPn0/v3r1JTEykR48eHD58mAsuuCBPF8x9+vRh6dKlJfq7mTKWfQrSZ8DXw+CDprD4fqhaF3q+CsN3QK8p0OiCCnHBskxEREHt9tDiKug8Di54Fy5fCdcegcFL4Py3oMOvIbql+xW0/rUyOVcVs0S/8Few/8w+2M9K3S7QbUKhi+vXr0+PHj2YPXs2w4YNY+rUqYwYMQIRoXr16kyfPp3atWuzZ88eevXqxdChQwsd0/Sll14iOjqapUuXsnTpUpKSknKXjR8/nnr16pGVlcWAAQNYunQpd999N88++yxz5syhQYMGefa1cOFCpkyZwvfff4+q0rNnTy688ELq1q3L2rVrefvtt3nllVe49tpref/99xk1alSe7fv27cu8efMQEV599VWefPJJnnnmGf70pz8RGxvLsmXLANi/fz+7d+/m1ltvZe7cubRq1SpP3zWFWb16NVOmTOHFF18s9P116NCBESNG8M4779C9e3cOHTpEjRo1uOWWW3j99deZMGECa9as4cSJEyQkJBR7TFMODq509e4b33R11tUbu4TVejTEWid1xYqsDnUT3cNf1omC1z9LVqIvgZzqG3DVNtdddx3gqiUefvhhEhISuOSSS9i6dWtuybggc+fOzU24CQkJeZLXtGnTSEpKomvXrqxYsaLATsv8ffvtt1x55ZXUrFmTmJgYhg8fzjfffANAq1at6NKlC1B4d8jp6elcdtlldO7cmaeeeooVK1YA8Pnnn+cZ8apu3brMmzePfv360apVKyCw7oxbtmxJr169inx/q1evpkmTJrndPdeuXZuoqCiuueYaPvroI06dOsXkyZO56aabij2eKV6pB9s4dQjWvQKfnA//Pg9WTYAGvaHfTLhiC3T9P0vyZyuyWpnstmKW6IsoeZelK664gvvuu49FixZx7Nix3JJ4amoqu3fvZuHChVSpUoW4uLgCuyf2V1Bpf+PGjTz99NPMnz+funXrctNN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\n"},"metadata":{"needs_background":"light"}}]},{"metadata":{},"cell_type":"markdown","source":"# Predict and Evaluate"},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred = model.predict(test_flow)\ny_test = test_flow.classes","execution_count":17,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn import metrics\nprint(\"ROC AUC Score:\", metrics.roc_auc_score(y_test, y_pred))\nprint(\"AP Score:\", metrics.average_precision_score(y_test, y_pred))\nprint()\nprint(metrics.classification_report(y_test, y_pred > 0.5))","execution_count":19,"outputs":[{"output_type":"stream","text":"ROC AUC Score: 0.9858290600000001\nAP Score: 0.9852092682720586\n\n precision recall f1-score support\n\n 0 0.87 0.97 0.92 10000\n 1 0.97 0.85 0.91 10000\n\n accuracy 0.91 20000\n macro avg 0.92 0.91 0.91 20000\nweighted avg 0.92 0.91 0.91 20000\n\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4} --------------------------------------------------------------------------------