{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.6","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":29956,"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-20T15:04:30.497342Z","iopub.execute_input":"2023-11-20T15:04:30.497837Z","iopub.status.idle":"2023-11-20T15:04:30.512922Z","shell.execute_reply.started":"2023-11-20T15:04:30.497782Z","shell.execute_reply":"2023-11-20T15:04:30.512084Z"},"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-20T15:04:30.515095Z","iopub.execute_input":"2023-11-20T15:04:30.515481Z","iopub.status.idle":"2023-11-20T15:04:30.53606Z","shell.execute_reply.started":"2023-11-20T15:04:30.515443Z","shell.execute_reply":"2023-11-20T15:04:30.535325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folders = sorted(glob('/kaggle/input/face-classification-deep-learning-cs-405/dataset/train/*'))\nlen(folders)","metadata":{"execution":{"iopub.status.busy":"2023-11-20T15:04:30.537292Z","iopub.execute_input":"2023-11-20T15:04:30.537663Z","iopub.status.idle":"2023-11-20T15:04:30.585978Z","shell.execute_reply.started":"2023-11-20T15:04:30.537625Z","shell.execute_reply":"2023-11-20T15:04:30.585082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folder_mapping = {os.path.basename(folder): idx for idx, folder in enumerate(folders)}\n\nfor folder, number in folder_mapping.items():\n    print(f\"Folder: {folder} -> Number: {number}\")","metadata":{"execution":{"iopub.status.busy":"2023-11-20T15:04:30.587034Z","iopub.execute_input":"2023-11-20T15:04:30.58733Z","iopub.status.idle":"2023-11-20T15:04:31.292609Z","shell.execute_reply.started":"2023-11-20T15:04:30.587287Z","shell.execute_reply":"2023-11-20T15:04:31.29186Z"},"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-20T15:04:31.29752Z","iopub.execute_input":"2023-11-20T15:04:31.297777Z","iopub.status.idle":"2023-11-20T15:04:40.373888Z","shell.execute_reply.started":"2023-11-20T15:04:31.297751Z","shell.execute_reply":"2023-11-20T15:04:40.372964Z"},"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-20T15:04:40.377534Z","iopub.execute_input":"2023-11-20T15:04:40.37791Z","iopub.status.idle":"2023-11-20T15:04:40.381948Z","shell.execute_reply.started":"2023-11-20T15:04:40.377875Z","shell.execute_reply":"2023-11-20T15:04:40.381065Z"},"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-20T15:04:40.383573Z","iopub.execute_input":"2023-11-20T15:04:40.383871Z","iopub.status.idle":"2023-11-20T15:04:40.548113Z","shell.execute_reply.started":"2023-11-20T15:04:40.383844Z","shell.execute_reply":"2023-11-20T15:04:40.547274Z"},"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-20T15:04:40.549223Z","iopub.execute_input":"2023-11-20T15:04:40.549503Z","iopub.status.idle":"2023-11-20T15:04:40.553167Z","shell.execute_reply.started":"2023-11-20T15:04:40.549474Z","shell.execute_reply":"2023-11-20T15:04:40.552407Z"},"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-20T15:04:40.554457Z","iopub.execute_input":"2023-11-20T15:04:40.554818Z","iopub.status.idle":"2023-11-20T15:04:40.58906Z","shell.execute_reply.started":"2023-11-20T15:04:40.554781Z","shell.execute_reply":"2023-11-20T15:04:40.588311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Model(inputs=vgg.input, outputs=prediction)","metadata":{"execution":{"iopub.status.busy":"2023-11-20T15:04:40.590195Z","iopub.execute_input":"2023-11-20T15:04:40.590549Z","iopub.status.idle":"2023-11-20T15:04:40.595284Z","shell.execute_reply.started":"2023-11-20T15:04:40.590511Z","shell.execute_reply":"2023-11-20T15:04:40.594425Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-20T15:04:40.596411Z","iopub.execute_input":"2023-11-20T15:04:40.596677Z","iopub.status.idle":"2023-11-20T15:04:40.615758Z","shell.execute_reply.started":"2023-11-20T15:04:40.59665Z","shell.execute_reply":"2023-11-20T15:04:40.615031Z"},"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-20T15:04:40.617119Z","iopub.execute_input":"2023-11-20T15:04:40.617401Z","iopub.status.idle":"2023-11-20T15:04:40.659393Z","shell.execute_reply.started":"2023-11-20T15:04:40.617374Z","shell.execute_reply":"2023-11-20T15:04:40.658755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfrom shutil import copyfile\n\ndef img_dataset_split(img_source_dir, train_size, val_size, test_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 all(isinstance(size, float) for size in [train_size, val_size, test_size]):\n        raise AttributeError('train_size, val_size, and test_size must be floats')\n        \n    if train_size + val_size + test_size != 1.0:\n        raise ValueError('The sum of train_size, val_size, and test_size must equal 1.0')\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        if not os.path.exists('data/test'):\n            os.makedirs('data/test')\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        file_list = os.listdir(subdir_fullpath)\n        total_files = len(file_list)\n        \n        train_count = int(train_size * total_files)\n        val_count = int(val_size * total_files)\n        test_count = total_files - train_count - val_count\n\n        train_files = file_list[:train_count]\n        val_files = file_list[train_count:train_count + val_count]\n        test_files = file_list[train_count + val_count:]\n\n        train_subdir = os.path.join('data/train', subdir)\n        validation_subdir = os.path.join('data/validation', subdir)\n        test_subdir = os.path.join('data/test', 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        if not os.path.exists(test_subdir):\n            os.makedirs(test_subdir)\n\n        for filename in train_files:\n            copyfile(os.path.join(subdir_fullpath, filename), os.path.join(train_subdir, filename))\n\n        for filename in val_files:\n            copyfile(os.path.join(subdir_fullpath, filename), os.path.join(validation_subdir, filename))\n\n        for filename in test_files:\n            copyfile(os.path.join(subdir_fullpath, filename), os.path.join(test_subdir, filename))\n                    \n        print(f'Copied {train_count} images to data/train/{subdir}')\n        print(f'Copied {val_count} images to data/validation/{subdir}')\n        print(f'Copied {test_count} images to data/test/{subdir}')\n","metadata":{"execution":{"iopub.status.busy":"2023-11-20T15:04:40.660632Z","iopub.execute_input":"2023-11-20T15:04:40.661018Z","iopub.status.idle":"2023-11-20T15:04:40.684116Z","shell.execute_reply.started":"2023-11-20T15:04:40.660969Z","shell.execute_reply":"2023-11-20T15:04:40.683244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_dataset_split(root_path, 0.7, 0.15, 0.15)","metadata":{"execution":{"iopub.status.busy":"2023-11-20T15:04:40.685319Z","iopub.execute_input":"2023-11-20T15:04:40.685586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = glob('data/train/*')\nprint(len(train))\nvalidation = glob('data/validation/*')\nprint(len(validation))\ntest = glob('data/test/*')\nprint(len(validation))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\ntrain_datagen = ImageDataGenerator(rescale = 1./255)\n\nvalidation_datagen = ImageDataGenerator(rescale = 1./255)\n\ntest_datagen = ImageDataGenerator(rescale = 1./255)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_set = train_datagen.flow_from_directory('data/train',\n                                                 target_size = (224, 224),\n                                                 batch_size = 128,\n                                                 class_mode = 'categorical')\n\nvalidation_set = test_datagen.flow_from_directory('data/validation',\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')\n\n\ntest_steps_per_epoch = np.math.ceil(test_set.samples / test_set.batch_size)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit_generator(\n  training_set,\n  validation_data=validation_set,\n  epochs=10,\n  steps_per_epoch=len(training_set),\n  validation_steps=len(validation_set)\n)","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_loss = history.history['loss']\nvalidation_loss = history.history['val_loss']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_accuracy = history.history['accuracy']\nvalidation_accuracy = history.history['val_accuracy']","metadata":{"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":{"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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_loss, test_accuracy = model.evaluate(test_set, verbose=1)\nprint(f\"Test Accuracy: {test_accuracy}\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save(\"my_model\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.models import load_model\n\nmodel = load_model('/kaggle/working/my_model')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import csv\n# test_dir = '/kaggle/input/face-classification-deep-learning-cs-405/dataset/test'\n\n# with open('/kaggle/working/test_labels.csv', mode='w', newline='') as file:\n#     writer = csv.writer(file)\n#     writer.writerow(['image_name'])\n\n#     for image_name in os.listdir(test_dir):\n#         print(image_name)\n#         writer.writerow([image_name])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df = pd.read_csv('/kaggle/working/test_labels.csv')\n# df = df.sort_values(by =['image_name'],ascending =True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from keras.models import load_model\n# model = load_model('/kaggle/input/vggmodel/my_model')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nfrom keras.preprocessing import image as keras_image\nfrom tqdm import tqdm\n\npredicted_labels = []\ntest_dir = '/kaggle/input/face-classification-deep-learning-cs-405/dataset/test'\n\nfor image_name in tqdm(os.listdir(test_dir)):\n    img_path = os.path.join(test_dir, image_name)\n    img = keras_image.load_img(img_path, target_size=(224, 224))\n    img_array = keras_image.img_to_array(img)\n    img_array = np.expand_dims(img_array, axis=0)\n    img_array = img_array / 255.0\n    \n    prediction = model.predict(img_array)\n    predicted_class = np.argmax(prediction)\n    \n    predicted_label = folder_mapping.get(predicted_class)\n    predicted_labels.append(predicted_label)\n\ndf = pd.DataFrame({'image_name': os.listdir(test_dir), 'predicted_label': predicted_labels})\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.to_csv('/kaggle/working/submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = model.predict(test_set)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}