{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":63103,"databundleVersionId":6877691,"sourceType":"competition"},{"sourceId":6997842,"sourceType":"datasetVersion","datasetId":4022720}],"dockerImageVersionId":30588,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom keras.layers import Input, Lambda, Dense, Flatten\nfrom keras.models import Model\nfrom keras.applications.vgg16 import VGG16\nfrom keras.applications.vgg16 import preprocess_input\nfrom keras.preprocessing import image\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential\nfrom sklearn.metrics import classification_report, confusion_matrix\nfrom sklearn.model_selection import train_test_split\nimport numpy as np\nimport random\nimport glob\nfrom glob import glob\nimport matplotlib.pyplot as plt\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2023-11-19T11:52:23.898032Z","iopub.execute_input":"2023-11-19T11:52:23.89857Z","iopub.status.idle":"2023-11-19T11:52:37.049299Z","shell.execute_reply.started":"2023-11-19T11:52:23.898543Z","shell.execute_reply":"2023-11-19T11:52:37.04831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"root_path = '/kaggle/input/face-classification-deep-learning-cs-405/dataset/train'","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:06.049941Z","iopub.execute_input":"2023-11-18T20:24:06.050338Z","iopub.status.idle":"2023-11-18T20:24:06.054156Z","shell.execute_reply.started":"2023-11-18T20:24:06.050301Z","shell.execute_reply":"2023-11-18T20:24:06.053334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folders = glob('/kaggle/input/face-classification-deep-learning-cs-405/dataset/train/*')\nlen(folders)","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:06.522529Z","iopub.execute_input":"2023-11-18T20:24:06.522934Z","iopub.status.idle":"2023-11-18T20:24:06.657246Z","shell.execute_reply.started":"2023-11-18T20:24:06.522896Z","shell.execute_reply":"2023-11-18T20:24:06.656185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install git+https://github.com/rcmalli/keras-vggface.git","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:06.879261Z","iopub.execute_input":"2023-11-18T20:24:06.879624Z","iopub.status.idle":"2023-11-18T20:24:18.069683Z","shell.execute_reply.started":"2023-11-18T20:24:06.879591Z","shell.execute_reply":"2023-11-18T20:24:18.068717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras_vggface.vggface import VGGFace\nfrom keras.engine import  Model\nfrom keras.layers import Input","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:29.917963Z","iopub.execute_input":"2023-11-18T20:24:29.918348Z","iopub.status.idle":"2023-11-18T20:24:29.928117Z","shell.execute_reply.started":"2023-11-18T20:24:29.918311Z","shell.execute_reply":"2023-11-18T20:24:29.92739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg = VGGFace(include_top=False, weights='vggface',input_tensor=None, input_shape=[224, 224, 3]) ","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:30.202276Z","iopub.execute_input":"2023-11-18T20:24:30.202651Z","iopub.status.idle":"2023-11-18T20:24:34.452168Z","shell.execute_reply.started":"2023-11-18T20:24:30.202609Z","shell.execute_reply":"2023-11-18T20:24:34.451168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in vgg.layers:\n  layer.trainable = False","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:34.454455Z","iopub.execute_input":"2023-11-18T20:24:34.454751Z","iopub.status.idle":"2023-11-18T20:24:34.459093Z","shell.execute_reply.started":"2023-11-18T20:24:34.45472Z","shell.execute_reply":"2023-11-18T20:24:34.458182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = Flatten()(vgg.output)\nx = Dense(1000, activation='relu')(x)\nx = Dense(1000, activation='relu')(x)\nprediction = Dense(len(folders), activation='softmax')(x)","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:34.46052Z","iopub.execute_input":"2023-11-18T20:24:34.460832Z","iopub.status.idle":"2023-11-18T20:24:34.500748Z","shell.execute_reply.started":"2023-11-18T20:24:34.46079Z","shell.execute_reply":"2023-11-18T20:24:34.499955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Model(inputs=vgg.input, outputs=prediction)","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:34.502118Z","iopub.execute_input":"2023-11-18T20:24:34.502444Z","iopub.status.idle":"2023-11-18T20:24:34.506937Z","shell.execute_reply.started":"2023-11-18T20:24:34.502393Z","shell.execute_reply":"2023-11-18T20:24:34.50604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:34.578922Z","iopub.execute_input":"2023-11-18T20:24:34.579188Z","iopub.status.idle":"2023-11-18T20:24:34.588146Z","shell.execute_reply.started":"2023-11-18T20:24:34.579162Z","shell.execute_reply":"2023-11-18T20:24:34.587435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(\n  loss='categorical_crossentropy',\n  optimizer='adam',\n  metrics=['accuracy']\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:48.451711Z","iopub.execute_input":"2023-11-18T20:24:48.45209Z","iopub.status.idle":"2023-11-18T20:24:48.492705Z","shell.execute_reply.started":"2023-11-18T20:24:48.452054Z","shell.execute_reply":"2023-11-18T20:24:48.491891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport random\nfrom shutil import copyfile\n\ndef img_train_test_split(img_source_dir, train_size):\n    if not (isinstance(img_source_dir, str)):\n        raise AttributeError('img_source_dir must be a string')\n        \n    if not os.path.exists(img_source_dir):\n        raise OSError('img_source_dir does not exist')\n        \n    if not (isinstance(train_size, float)):\n        raise AttributeError('train_size must be a float')\n        \n    if not os.path.exists('data'):\n        os.makedirs('data')\n    else:\n        if not os.path.exists('data/train'):\n            os.makedirs('data/train')\n        if not os.path.exists('data/validation'):\n            os.makedirs('data/validation')\n            \n    subdirs = [subdir for subdir in os.listdir(img_source_dir) if os.path.isdir(os.path.join(img_source_dir, subdir))]\n\n    for subdir in subdirs:\n        subdir_fullpath = os.path.join(img_source_dir, subdir)\n        if len(os.listdir(subdir_fullpath)) == 0:\n            print(subdir_fullpath + ' is empty')\n            break\n\n        train_subdir = os.path.join('data/train', subdir)\n        validation_subdir = os.path.join('data/validation', subdir)\n\n        if not os.path.exists(train_subdir):\n            os.makedirs(train_subdir)\n\n        if not os.path.exists(validation_subdir):\n            os.makedirs(validation_subdir)\n\n        train_counter = 0\n        validation_counter = 0\n\n        for filename in os.listdir(subdir_fullpath):\n            if filename.endswith(\".jpg\") or filename.endswith(\".png\"): \n                fileparts = filename.split('.')\n\n                if random.uniform(0, 1) <= train_size:\n                    copyfile(os.path.join(subdir_fullpath, filename), os.path.join(train_subdir, str(train_counter) + '.' + fileparts[1]))\n                    train_counter += 1\n                else:\n                    copyfile(os.path.join(subdir_fullpath, filename), os.path.join(validation_subdir, str(validation_counter) + '.' + fileparts[1]))\n                    validation_counter += 1\n                    \n        print('Copied ' + str(train_counter) + ' images to data/train/' + subdir)\n        print('Copied ' + str(validation_counter) + ' images to data/validation/' + subdir)","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:49.268089Z","iopub.execute_input":"2023-11-18T20:24:49.268444Z","iopub.status.idle":"2023-11-18T20:24:49.288384Z","shell.execute_reply.started":"2023-11-18T20:24:49.268391Z","shell.execute_reply":"2023-11-18T20:24:49.287302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_train_test_split(root_path, 0.7)","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:24:50.356505Z","iopub.execute_input":"2023-11-18T20:24:50.35685Z","iopub.status.idle":"2023-11-18T20:32:59.73088Z","shell.execute_reply.started":"2023-11-18T20:24:50.35682Z","shell.execute_reply":"2023-11-18T20:32:59.729827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = glob('data/train/*')\nprint(len(train))\nvalidation = glob('data/validation/*')\nprint(len(validation))","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:39:18.485935Z","iopub.execute_input":"2023-11-18T20:39:18.48636Z","iopub.status.idle":"2023-11-18T20:39:18.546571Z","shell.execute_reply.started":"2023-11-18T20:39:18.486324Z","shell.execute_reply":"2023-11-18T20:39:18.545789Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\ntrain_datagen = ImageDataGenerator(rescale = 1./255,)\n#                                    shear_range = 0.2,\n#                                    zoom_range = 0.2,)\n#                                    horizontal_flip = True)\n\ntest_datagen = ImageDataGenerator(rescale = 1./255)\n\ntraining_set = train_datagen.flow_from_directory('data/train',\n                                                 target_size = (224, 224),\n                                                 batch_size = 128,\n                                                 class_mode = 'categorical')\n\ntest_set = test_datagen.flow_from_directory('data/validation',\n                                            target_size = (224, 224),\n                                            batch_size = 128,\n                                            class_mode = 'categorical')\ntest_steps_per_epoch = np.math.ceil(test_set.samples / test_set.batch_size)","metadata":{"execution":{"iopub.status.busy":"2023-11-18T20:39:23.60361Z","iopub.execute_input":"2023-11-18T20:39:23.603966Z","iopub.status.idle":"2023-11-18T20:39:36.6121Z","shell.execute_reply.started":"2023-11-18T20:39:23.603936Z","shell.execute_reply":"2023-11-18T20:39:36.611238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit_generator(\n  training_set,\n  validation_data=test_set,\n  epochs=15,\n  steps_per_epoch=len(training_set),\n  validation_steps=len(test_set)\n)","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-11-18T20:39:39.165681Z","iopub.execute_input":"2023-11-18T20:39:39.166014Z","iopub.status.idle":"2023-11-18T23:51:13.195504Z","shell.execute_reply.started":"2023-11-18T20:39:39.165986Z","shell.execute_reply":"2023-11-18T23:51:13.194182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_loss = history.history['loss']\nvalidation_loss = history.history['val_loss']","metadata":{"execution":{"iopub.status.busy":"2023-11-18T23:51:20.532703Z","iopub.execute_input":"2023-11-18T23:51:20.53318Z","iopub.status.idle":"2023-11-18T23:51:20.540474Z","shell.execute_reply.started":"2023-11-18T23:51:20.533133Z","shell.execute_reply":"2023-11-18T23:51:20.539719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_accuracy = history.history['accuracy']\nvalidation_accuracy = history.history['val_accuracy']","metadata":{"execution":{"iopub.status.busy":"2023-11-18T23:51:22.047376Z","iopub.execute_input":"2023-11-18T23:51:22.047867Z","iopub.status.idle":"2023-11-18T23:51:22.052245Z","shell.execute_reply.started":"2023-11-18T23:51:22.047825Z","shell.execute_reply":"2023-11-18T23:51:22.051369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(training_loss, label='Training Loss')\nplt.plot(validation_loss, label='Validation Loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.title('Training and Validation Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-18T23:51:22.900219Z","iopub.execute_input":"2023-11-18T23:51:22.900555Z","iopub.status.idle":"2023-11-18T23:51:23.155383Z","shell.execute_reply.started":"2023-11-18T23:51:22.900522Z","shell.execute_reply":"2023-11-18T23:51:23.154324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(training_accuracy, label='Training Accuracy')\nplt.plot(validation_accuracy, label='Validation Accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.title('Training and Validation Accuracy')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-18T23:51:37.164251Z","iopub.execute_input":"2023-11-18T23:51:37.16459Z","iopub.status.idle":"2023-11-18T23:51:37.349169Z","shell.execute_reply.started":"2023-11-18T23:51:37.164562Z","shell.execute_reply":"2023-11-18T23:51:37.348387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save(\"my_model\")","metadata":{"execution":{"iopub.status.busy":"2023-11-18T23:51:50.163304Z","iopub.execute_input":"2023-11-18T23:51:50.163655Z","iopub.status.idle":"2023-11-18T23:51:51.069962Z","shell.execute_reply.started":"2023-11-18T23:51:50.163625Z","shell.execute_reply":"2023-11-18T23:51:51.068952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"modelnew = keras.models.load_model(\"/kaggle/working/my_model\")","metadata":{"execution":{"iopub.status.busy":"2023-11-18T23:52:09.010717Z","iopub.execute_input":"2023-11-18T23:52:09.011047Z","iopub.status.idle":"2023-11-18T23:52:10.102911Z","shell.execute_reply.started":"2023-11-18T23:52:09.011018Z","shell.execute_reply":"2023-11-18T23:52:10.102153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"modelnew.evaluate(test_set)","metadata":{"execution":{"iopub.status.busy":"2023-11-18T23:55:48.545541Z","iopub.execute_input":"2023-11-18T23:55:48.54601Z","iopub.status.idle":"2023-11-18T23:59:14.384408Z","shell.execute_reply.started":"2023-11-18T23:55:48.545956Z","shell.execute_reply":"2023-11-18T23:59:14.383513Z"},"trusted":true},"execution_count":null,"outputs":[]}]}