{"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":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ⚙️ Install libs","metadata":{}},{"cell_type":"code","source":"from IPython.display import clear_output\n\n!pip install dlib -vvv\n!pip install face_recognition\n\nclear_output()","metadata":{"execution":{"iopub.status.busy":"2023-08-28T19:52:15.773581Z","iopub.execute_input":"2023-08-28T19:52:15.773976Z","iopub.status.idle":"2023-08-28T19:59:34.469883Z","shell.execute_reply.started":"2023-08-28T19:52:15.773943Z","shell.execute_reply":"2023-08-28T19:59:34.468810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# work with data\nimport os\nimport shutil\nfrom sklearn.model_selection import train_test_split\nimport numpy as np\nimport pandas as pd\nfrom sklearn.manifold import TSNE\n\n# visualization \nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n\n# DL\nfrom sklearn import svm\nimport face_recognition\nfrom sklearn.ensemble import RandomForestClassifier","metadata":{"execution":{"iopub.status.busy":"2023-08-28T20:28:46.237319Z","iopub.execute_input":"2023-08-28T20:28:46.237808Z","iopub.status.idle":"2023-08-28T20:28:46.244785Z","shell.execute_reply.started":"2023-08-28T20:28:46.237772Z","shell.execute_reply":"2023-08-28T20:28:46.243633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 📊 Check dataset out","metadata":{}},{"cell_type":"code","source":"source_dir = \"/kaggle/input/face-recognition-xt122/Train\"","metadata":{"execution":{"iopub.status.busy":"2023-08-28T19:59:37.161916Z","iopub.execute_input":"2023-08-28T19:59:37.162293Z","iopub.status.idle":"2023-08-28T19:59:37.170606Z","shell.execute_reply.started":"2023-08-28T19:59:37.162249Z","shell.execute_reply":"2023-08-28T19:59:37.168953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_names = os.listdir(source_dir)\nclass_names","metadata":{"execution":{"iopub.status.busy":"2023-08-28T19:59:37.175020Z","iopub.execute_input":"2023-08-28T19:59:37.175419Z","iopub.status.idle":"2023-08-28T19:59:37.210642Z","shell.execute_reply.started":"2023-08-28T19:59:37.175387Z","shell.execute_reply":"2023-08-28T19:59:37.209311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def count(class_name):\n    path = os.path.join(source_dir, class_name)\n    file_names = os.listdir(path)\n    \n    return len(file_names)\n    \n\ncounts = [count(class_name) for class_name in class_names]\ncounts","metadata":{"execution":{"iopub.status.busy":"2023-08-28T19:59:37.211897Z","iopub.execute_input":"2023-08-28T19:59:37.212530Z","iopub.status.idle":"2023-08-28T19:59:37.389947Z","shell.execute_reply.started":"2023-08-28T19:59:37.212500Z","shell.execute_reply":"2023-08-28T19:59:37.389334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.bar(class_names, counts)\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-28T19:59:37.392016Z","iopub.execute_input":"2023-08-28T19:59:37.392529Z","iopub.status.idle":"2023-08-28T19:59:37.745619Z","shell.execute_reply.started":"2023-08-28T19:59:37.392490Z","shell.execute_reply":"2023-08-28T19:59:37.744533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axes = plt.subplots(1, len(class_names), figsize=(15, 5))\n\nfor i, class_name in enumerate(class_names):\n    class_dir = os.path.join(source_dir, class_name)\n    \n    # read first image\n    for file in os.listdir(class_dir):\n        image = mpimg.imread(os.path.join(class_dir, file))\n        break\n    \n    axes[i].imshow(image)\n    axes[i].set_title(class_name)\n    axes[i].axis('off')\n    \nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-28T19:59:37.747137Z","iopub.execute_input":"2023-08-28T19:59:37.747485Z","iopub.status.idle":"2023-08-28T19:59:39.060181Z","shell.execute_reply.started":"2023-08-28T19:59:37.747458Z","shell.execute_reply":"2023-08-28T19:59:39.059106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 👾 Pipeline implentations\n\nWe are going to use the face_recognizer to encode each picture, and after that, we will train an SVM for classifying the classes","metadata":{}},{"cell_type":"code","source":"encodings = []\nencodings_classes = []\n\ndef image_iterator(base_dir):\n    \"\"\" The iterator that will go through entire dataset \"\"\"\n    \n    class_names = os.listdir(base_dir)\n    \n    for class_name in class_names:\n        pictures = os.listdir(os.path.join(base_dir, class_name))\n        \n        for picture in pictures:\n            yield { \n                \"class\": class_name, \n                \"path\": os.path.join(base_dir, class_name, picture)\n            }","metadata":{"execution":{"iopub.status.busy":"2023-08-28T19:59:39.061487Z","iopub.execute_input":"2023-08-28T19:59:39.061855Z","iopub.status.idle":"2023-08-28T19:59:39.068924Z","shell.execute_reply.started":"2023-08-28T19:59:39.061826Z","shell.execute_reply":"2023-08-28T19:59:39.067629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 1️⃣ Face recognition model's encoder","metadata":{}},{"cell_type":"code","source":"for picture in tqdm(image_iterator(source_dir), total=sum(counts)):\n    \n    face = face_recognition.load_image_file(picture[\"path\"])\n    face_bounding_boxes = face_recognition.face_locations(face)\n    \n    if len(face_bounding_boxes) == 1:\n        face_enc = face_recognition.face_encodings(face)[0]\n        \n        encodings.append(face_enc)\n        encodings_classes.append(picture[\"class\"])","metadata":{"execution":{"iopub.status.busy":"2023-08-28T19:59:39.070581Z","iopub.execute_input":"2023-08-28T19:59:39.070919Z","iopub.status.idle":"2023-08-28T20:09:29.389696Z","shell.execute_reply.started":"2023-08-28T19:59:39.070889Z","shell.execute_reply":"2023-08-28T20:09:29.388062Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 2️⃣ Sklearn SVM model train","metadata":{}},{"cell_type":"code","source":"clf = RandomForestClassifier()\nclf.fit(encodings, encodings_classes)","metadata":{"execution":{"iopub.status.busy":"2023-08-28T20:11:48.782483Z","iopub.execute_input":"2023-08-28T20:11:48.783527Z","iopub.status.idle":"2023-08-28T20:11:49.168787Z","shell.execute_reply.started":"2023-08-28T20:11:48.783491Z","shell.execute_reply":"2023-08-28T20:11:49.166892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 🎲 Observing the Distribution of Classes","metadata":{}},{"cell_type":"code","source":"encodings = np.array(encodings)\nencodings_classes = np.array(encodings_classes)","metadata":{"execution":{"iopub.status.busy":"2023-08-28T20:13:06.862325Z","iopub.execute_input":"2023-08-28T20:13:06.862754Z","iopub.status.idle":"2023-08-28T20:13:06.868483Z","shell.execute_reply.started":"2023-08-28T20:13:06.862723Z","shell.execute_reply":"2023-08-28T20:13:06.867480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tsne = TSNE(n_components=2)\ntsne_encodings = tsne.fit_transform(encodings)","metadata":{"execution":{"iopub.status.busy":"2023-08-28T20:13:08.802464Z","iopub.execute_input":"2023-08-28T20:13:08.803349Z","iopub.status.idle":"2023-08-28T20:13:11.366376Z","shell.execute_reply.started":"2023-08-28T20:13:08.803307Z","shell.execute_reply":"2023-08-28T20:13:11.364912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10, 7))\nfor i, class_name in enumerate(class_names):\n    idx = np.where(class_name == encodings_classes)\n    plt.scatter(tsne_encodings[idx, 0], tsne_encodings[idx, 1], label=class_name)\n    \nplt.title(\"t-SNE Visualization of Encodings\")\nplt.xlabel(\"t-SNE Component 1\")\nplt.ylabel(\"t-SNE Component 2\")\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-28T20:13:33.873399Z","iopub.execute_input":"2023-08-28T20:13:33.873760Z","iopub.status.idle":"2023-08-28T20:13:34.257239Z","shell.execute_reply.started":"2023-08-28T20:13:33.873731Z","shell.execute_reply":"2023-08-28T20:13:34.256363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 🐍 Submit","metadata":{}},{"cell_type":"code","source":"test_dir = \"/kaggle/input/face-recognition-xt122/Test\"\n\nclass_map = pd.read_csv(\"/kaggle/input/face-recognition-xt122/ClassMap.csv\")\nsample_submission = pd.read_csv(\"/kaggle/input/face-recognition-xt122/SampleSubmission.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-08-28T20:57:41.913854Z","iopub.execute_input":"2023-08-28T20:57:41.914262Z","iopub.status.idle":"2023-08-28T20:57:41.928806Z","shell.execute_reply.started":"2023-08-28T20:57:41.914231Z","shell.execute_reply":"2023-08-28T20:57:41.926232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_class_label(classe: str):\n    idx = class_map[class_map[\"classe_name\"] == classe][\"label_num\"]\n    return int(idx)\n\ndef get_path(image_name: str, ext: str = \".jpg\"):\n    return os.path.join(test_dir, image_name + ext)","metadata":{"execution":{"iopub.status.busy":"2023-08-28T21:26:02.000973Z","iopub.execute_input":"2023-08-28T21:26:02.001420Z","iopub.status.idle":"2023-08-28T21:26:02.008316Z","shell.execute_reply.started":"2023-08-28T21:26:02.001367Z","shell.execute_reply":"2023-08-28T21:26:02.006940Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for idx, row in tqdm(sample_submission.iterrows(), total=len(sample_submission)):\n    # Face recognition encoder\n    image = face_recognition.load_image_file(get_path(row[\"filename\"]))\n    face_locations = face_recognition.face_locations(image) \n    try:\n        image_enc = face_recognition.face_encodings(image)[0]\n        # Random Forest model\n        proba = clf.predict_proba([image_enc])\n        predicted_class = clf.classes_[np.argmax(proba)]\n    except IndexError:\n        predicted_class = \"Others\"\n        \n    sample_submission.at[idx, \"label\"] = get_class_label(predicted_class)","metadata":{"execution":{"iopub.status.busy":"2023-08-28T21:26:28.824444Z","iopub.execute_input":"2023-08-28T21:26:28.824852Z","iopub.status.idle":"2023-08-28T21:28:04.988219Z","shell.execute_reply.started":"2023-08-28T21:26:28.824822Z","shell.execute_reply":"2023-08-28T21:28:04.986561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-08-28T21:26:22.974687Z","iopub.execute_input":"2023-08-28T21:26:22.975046Z","iopub.status.idle":"2023-08-28T21:26:22.989146Z","shell.execute_reply.started":"2023-08-28T21:26:22.975022Z","shell.execute_reply":"2023-08-28T21:26:22.987390Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}