{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":5048,"databundleVersionId":868335,"sourceType":"competition"}],"dockerImageVersionId":30674,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfrom tqdm import tqdm \npd.options.display.max_colwidth = 1000\ntqdm.pandas()\n\nimport cv2 \nimport matplotlib.pyplot as plt\n\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n\nactivity_map = {'c0': 'Safe driving', \n                'c1': 'Texting - right', \n                'c2': 'Talking on the phone - right', \n                'c3': 'Texting - left', \n                'c4': 'Talking on the phone - left', \n                'c5': 'Operating the radio', \n                'c6': 'Drinking', \n                'c7': 'Reaching behind', \n                'c8': 'Hair and makeup', \n                'c9': 'Talking to passenger'}","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Fetching Training Driver_imgs_list:-->","metadata":{}},{"cell_type":"code","source":"driver_imgs_list = pd.read_csv(\"/kaggle/input/state-farm-distracted-driver-detection/driver_imgs_list.csv\")\ndriver_imgs_list['class'] = driver_imgs_list['classname'].replace(activity_map)\ndriver_imgs_list.head(2)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Fetching The List Of the Training Images","metadata":{}},{"cell_type":"code","source":"import glob\nlist_train_img = glob.glob(os.path.join(\"/kaggle/input/state-farm-distracted-driver-detection/imgs\", \"train\", \"*\",  \"*.jpg\"))\nprint(\"Total number of Train Images is -------->\", len(list_train_img))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##  Adding Image Path  In The Data Frame :->","metadata":{}},{"cell_type":"code","source":"driver_imgs_list['ImgPath'] = driver_imgs_list['img'].progress_apply(lambda x: [i for i in  list_train_img if x in i][0])\n\ndf = driver_imgs_list.copy()\n\ndel driver_imgs_list, list_train_img","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head(1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Analysis","metadata":{}},{"cell_type":"code","source":"df['class'].value_counts().to_frame()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Creating Function which will plot image by using their class and the imagePath","metadata":{}},{"cell_type":"code","source":"def plot_from_dataframe(class_ , ImgPath):\n    img_arr = cv2.imread(ImgPath)\n    plt.imshow(img_arr)\n    plt.title(class_)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_from_dataframe(class_ = 'Talking to passenger', ImgPath = '/kaggle/input/state-farm-distracted-driver-detection/imgs/train/c9/img_9877.jpg')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Import Library","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_to_num = dict(zip(set(df['class']), range(len(set(df['class'])))))\nclass_to_num","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head(1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Train And Validation Split","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_dataset, valid_dataset = train_test_split(df ,test_size = 0.3 , random_state = 42, shuffle = True,\n                                               stratify = df['class'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ImageDataGenerator","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# Define data generators\ntrain_datagen = ImageDataGenerator(rescale=1./255)\ntest_datagen = ImageDataGenerator(rescale=1./255)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##  training_set, validation_set","metadata":{}},{"cell_type":"code","source":"training_set = train_datagen.flow_from_dataframe(\n                        dataframe = train_dataset,\n                        x_col = 'ImgPath',\n                        y_col = 'class',\n                        target_size=(299,299),\n                        class_mode = 'categorical',\n                        batch_size= 64)\n\nvalidation_set = test_datagen.flow_from_dataframe(\n                dataframe = valid_dataset,\n                x_col = 'ImgPath',\n                y_col = 'class',\n                target_size = (299, 299),\n                class_mode = 'categorical',\n                batch_size = 64)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Importing Multiple Trasffer Learning Technique","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.layers import Input, Concatenate, Flatten, Dropout, Dense\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.applications import ResNet50V2, InceptionResNetV2\n\ndef create_combined_model(input_shape=(299, 299, 3)):\n    # Input layer\n    input_tensor = Input(shape=input_shape)\n\n    # Initialize lists to store outputs of each model\n    outputs = []\n\n    # Loop through each base model and perform transfer learning\n    for base_model in [ResNet50V2, InceptionResNetV2]:\n        # Load pre-trained model without top layers\n        base_model = base_model(weights='imagenet', include_top=False, input_tensor=input_tensor)\n        # Freeze layers\n        for layer in base_model.layers[:90]:\n            layer.trainable = False\n        # Get output of the base model\n        output = base_model.output\n        # Flatten the output\n        output = Flatten()(output)\n        # Append to outputs list\n        outputs.append(output)\n\n    # Concatenate outputs vertically\n    concatenated_output = Concatenate(axis=1)(outputs)\n\n    # Apply dropout\n    output = Dropout(0.8)(concatenated_output)\n\n    # Output layer\n    output = Dense(10, activation='softmax')(output)\n\n    # Combine models\n    combine_model = Model(inputs=[input_tensor], outputs=output)\n\n    return combine_model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create and compile the model\ncombine_model = create_combined_model()\ncombine_model.compile(optimizer='adam', loss='categorical_crossentropy', \n                      metrics=['accuracy'])\nprint(\"Total number of layers in the model:---> \", len(combine_model.layers))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# combine_model.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping\n\n#learning_rate reduce module\nlr_reduce = ReduceLROnPlateau('val_loss', patience=3, \n                                              factor=0.5, min_lr=1e-6)\n\n# Stop early if model doesn't improve after n epochs\nearly_stopper = EarlyStopping(monitor='val_loss', patience=4,\n                              verbose=0, restore_best_weights=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = combine_model.fit(training_set,\n                         batch_size = 512,\n                         epochs=40,\n                         validation_data=validation_set,\n                         callbacks = [lr_reduce, early_stopper],\n                         verbose=1, shuffle=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Plot Accuracy Loss","metadata":{}},{"cell_type":"code","source":"# Create subplots with 1 row and 2 columns\nfig, axs = plt.subplots(1, 2, figsize=(15, 5))\n\n# Plot training and validation accuracy values\naxs[0].plot(history.history['accuracy'], label='Training Accuracy')\naxs[0].plot(history.history['val_accuracy'], label='Validation Accuracy')\naxs[0].set_title('Training and Validation Accuracy')\naxs[0].set_xlabel('Epoch')\naxs[0].set_ylabel('Accuracy')\naxs[0].legend()\n\n# Plot training and validation loss values\naxs[1].plot(history.history['loss'], label='Training Loss')\naxs[1].plot(history.history['val_loss'], label='Validation Loss')\naxs[1].set_title('Training and Validation Loss')\naxs[1].set_xlabel('Epoch')\naxs[1].set_ylabel('Loss')\naxs[1].legend()\n\n# Show the plots\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Creating A Model Prediction Function","metadata":{}},{"cell_type":"code","source":"from PIL import Image\nfrom IPython.display import display\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Class Indeces Are :-->\", validation_set.class_indices)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def model_prediction(img_path, model, target_size=(299, 299)):\n    # Load and preprocess the image\n    img = Image.open(img_path)\n    img = img.resize(target_size)  # Resize the image to the input size of the model\n    img_array = np.array(img) / 255.0  # Convert image to numpy array and normalize pixel values\n    \n    # Expand the dimensions of the image array to match the input shape expected by the model\n    expand_dim = np.expand_dims(img_array, axis=0)\n    \n    # Make prediction using the model\n    predictions = model.predict(expand_dim, verbose = False)\n    predicted_class_index = np.argmax(predictions)\n    \n    # Map the predicted class index to its corresponding label\n    predicted_label = next((k for k, v in validation_set.class_indices.items() if v == predicted_class_index), None)\n    \n    return predicted_label","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_dataset = valid_dataset['ImgPath class'.split()].copy().reset_index(drop=True)\nprint(\"shape_of_the_valid_dataset\", valid_dataset.shape)\nvalid_dataset.sample(1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_path = '/kaggle/input/state-farm-distracted-driver-detection/imgs/train/c8/img_61610.jpg'\nmodel_prediction(image_path , combine_model)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Prediction On The Validation DataSet","metadata":{}},{"cell_type":"code","source":"valid_dataset['prediction'] = valid_dataset['ImgPath'].progress_apply(lambda x:model_prediction(x, combine_model))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_dataset.sample(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Prediction On The Test Dataset","metadata":{}},{"cell_type":"code","source":"test_df  = pd.DataFrame(glob.glob(\"/kaggle/input/state-farm-distracted-driver-detection/imgs/test/*\"), columns = ['ImgPath'])\nprint(\"shape of test_df :->\", test_df.shape)\ntest_df['prediction'] = test_df['ImgPath'].progress_apply(lambda x:model_prediction(x, combine_model))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}