{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras \nfrom tensorflow.keras import layers\n\nfrom keras.models import Sequential, Model\nfrom keras.layers.core import Flatten, Dense, Dropout\nfrom keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D\nfrom keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization, GlobalAveragePooling2D\nfrom keras.optimizers import SGD\nfrom keras.applications.vgg16 import VGG16\n\nfrom keras.utils import np_utils\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.preprocessing import image\nfrom keras.callbacks import ModelCheckpoint, EarlyStopping\n\nfrom IPython.display import FileLink,display, Image\nfrom PIL import Image as I\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.datasets import load_files     \nfrom sklearn.utils import shuffle\nfrom sklearn.metrics import log_loss\n\nfrom random import sample\nimport random\n\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport seaborn as sns\n\nimport numpy as np\nimport pandas as pd\n\nfrom tqdm import tqdm\nfrom glob import glob\nimport pickle\nimport zipfile\nimport os\nimport cv2\nimport timeit\nimport time\nimport h5py\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create folder\nmodels_dir = \"saved_models\"\nif not os.path.exists(models_dir):\n    os.makedirs(models_dir)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# check if CUDA is available\nif tf.test.is_gpu_available(cuda_only=True):\n     print('CUDA is available!  Training on GPU ...')\n\nIMG_SIZE   = 244 if  tf.test.is_gpu_available(cuda_only=True) else 160\nCOLOR_TYPE = 3\nCLASSES    = 10\nEPOCHS     = 50\nBATCHES    = 50\nIMG_SIZE   = 224\nTEST_SIZE  = 10\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv(\"../input/state-farm-distracted-driver-detection/driver_imgs_list.csv\")\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.set()\n\nplt.figure(figsize = (10,5))\n# Count the number of images per category\nsns.countplot(x = 'classname', color = '#169DE3',data = df)\n\nplt.title('Categories Distribution'.title(),size=22 , color = '#169DE3')\nplt.xlabel('classname',size=17 , color = '#169DE3')\nplt.ylabel('Count',size=17 , color = '#169DE3')\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load the dataset from Kaggle\ndef get_cv2_image(path, img_size, color_type):\n    # Loading as Grayscale image\n    if color_type == 1:\n        img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)\n    # Loading as color image\n    elif color_type == 3:\n        img = cv2.imread(path, cv2.IMREAD_COLOR)\n    # Reduce size\n    img = cv2.resize(img[:500], (img_size, img_size)) \n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_trainning_data(img_size , color_type):\n    start_time = time.time()\n    training_images = []\n    training_labels = []\n\n    # Loop over the training folder \n    for class_ in tqdm(range(CLASSES)):\n        \n        print('Loading directory c{}'.format(class_))\n        \n        files = glob(os.path.join('../input/state-farm-distracted-driver-detection/imgs/train', 'c' + str(class_), '*.jpg'))\n        \n        for file in files:\n            img = get_cv2_image(file, img_size , color_type)\n            training_images.append(img)\n            training_labels.append(class_) \n    \n    print(\"Data Loaded in {} Min\".format((time.time() - start_time)/60))\n    return training_images, training_labels \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X, y = load_trainning_data( IMG_SIZE , COLOR_TYPE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X[0].shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Convert Categorical data to numerical\ny = np_utils.to_categorical(y, CLASSES)\ny[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# splitting train data to train and validation\nX_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.15,shuffle=True, random_state=2021)\nprint(X_train[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# convert data to numpy array\nX_train = np.array(X_train, dtype=np.uint8).reshape(-1,IMG_SIZE,IMG_SIZE,COLOR_TYPE)\nX_valid = np.array(X_valid, dtype=np.uint8).reshape(-1,IMG_SIZE,IMG_SIZE,COLOR_TYPE)\n\nprint('Train shape :', X_train.shape)\nprint('Number of train samples : ',X_train.shape[0])\n\nprint('Validation shape :', X_valid.shape)\nprint('Number of Validation samples : ',X_valid.shape[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#shffle training data \n\nrandom.shuffle(X_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_testing_data(test_size,img_size, color_type):\n\n    files = sorted(glob(os.path.join('../input/state-farm-distracted-driver-detection/imgs/test', '*.jpg')))\n    testing_image = []\n    testing_image_id = []\n    \n    total = 0\n    files_size = len(files)\n    \n    for file in tqdm(files):\n        \n        if total == test_size:\n            break\n            \n        file_base = os.path.basename(file)\n        img = get_cv2_image(file, img_size, color_type)\n        testing_image.append(img)\n        testing_image_id.append(file_base)\n        \n        total += 1\n    return testing_image, testing_image_id\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_data, test_ids = load_testing_data(TEST_SIZE, IMG_SIZE, COLOR_TYPE)\ntest_data = np.array(test_data, dtype=np.uint8)\ntest_data = test_data.reshape(-1,IMG_SIZE,IMG_SIZE,COLOR_TYPE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Test shape:', test_data.shape)\nprint(test_data.shape[0], 'Test samples')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# mapping categotical\nCAT_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'}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (12, 20))\n#image_count = 1\nDIR = '../input/state-farm-distracted-driver-detection/imgs/train/'\n\nfor directory in os.listdir(DIR):\n    \n    if directory[0] != '.':\n        for i, file in enumerate(os.listdir(DIR + directory)):\n            if i == 2:\n                break\n            else:\n                #fig = plt.subplot(2, 2, image_count)\n                #image_count += 1\n                image = mpimg.imread(DIR + directory + '/' + file)\n                plt.imshow(image)\n                plt.title(CAT_MAP[directory])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(X_train.shape,y_train.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"ResNet-Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"base_model  = tf.keras.applications.resnet.ResNet50(include_top = False,\n                                                  weights = 'imagenet',\n                                                  input_shape = (224,224,3))\nbase_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = base_model.output\nx = tf.keras.layers.Flatten()(x)\nx = tf.keras.layers.Dropout(0.5)(x)\n\noutput =tf.keras.layers.Dense(CLASSES,activation = tf.nn.softmax)(x)\nmodel = tf.keras.models.Model(inputs=base_model.inputs, outputs=output)\n\nmodel.compile(optimizer=tf.keras.optimizers.Adam(0.0001),\n              loss=tf.keras.losses.CategoricalCrossentropy(from_logits = False),\n              metrics=['accuracy'])\n\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"num_epochs = 50\ndef lr_schedule(epoch,lr):\n    # Learning Rate Schedule\n\n    lr = lr\n    total_epochs = num_epochs\n\n    check_1 = int(total_epochs * 0.9)\n    check_2 = int(total_epochs * 0.8)\n    check_3 = int(total_epochs * 0.6)\n    check_4 = int(total_epochs * 0.4)\n\n    if epoch > check_1:\n        lr *= 1e-4\n    elif epoch > check_2:\n        lr *= 1e-3\n    elif epoch > check_3:\n        lr *= 1e-2\n    elif epoch > check_4:\n        lr *= 1e-1\n\n    print(\"[+] Current Lr rate : {} \".format(lr))\n    return lr\nlr_callback = tf.keras.callbacks.LearningRateScheduler(lr_schedule)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(\n      x = X_train,y=y_train,\n      validation_data=(X_valid,y_valid),\n      steps_per_epoch=16,\n      batch_size = 8,\n      epochs=num_epochs,\n    \n    callbacks = [lr_callback],\n      verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(1, 2, figsize=(15, 5))\n\nax[0].set_title('Training Loss')\nax[0].plot(history.history['accuracy'])\nax[0].plot(history.history['val_accuracy'])\n\nax[1].set_title('Validation Loss')\nax[1].plot(history.history['loss'])\nax[1].plot(history.history['val_loss'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Preparing data augmentation\n'''Generate batches of tensor image data with real-time data augmentation.\n   The data will be looped over (in batches).'''\n\ntrain_gen = ImageDataGenerator(rescale = 1.0/255,\n                               height_shift_range=0.5,\n                               width_shift_range = 0.5,\n                               rotation_range=30,\n                               validation_split = 0.2)\n\nvalid_gen = ImageDataGenerator(rescale=1.0/ 255, validation_split = 0.2)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''Takes the dataframe and the path to a directory + generates batches.\n\n   The generated batches contain => augmented/normalized data.'''\nBATCHES = 50\n\ntraining_generator = train_gen.flow_from_directory('../input/state-farm-distracted-driver-detection/imgs/train', \n                                                 target_size = (IMG_SIZE, IMG_SIZE), \n                                                 batch_size = BATCHES,\n                                                 shuffle=True,\n                                                 class_mode='categorical', subset=\"training\")\n\n\nvalidation_generator = valid_gen.flow_from_directory('../input/state-farm-distracted-driver-detection/imgs/train', \n                                                   target_size = (IMG_SIZE, IMG_SIZE), \n                                                   batch_size = BATCHES,\n                                                   shuffle=False,\n                                                   class_mode='categorical', subset=\"validation\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_samples = 17943\nvalid_samples = 4481","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_samples","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_samples","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validation_generator","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_train_history(history):\n    # Summarize history for accuracy\n    plt.figure(figsize = (8, 5))\n    #plt.xticks(np.arange(0, 10))\n    #plt.yticks(np.arange(0, 100))\n    plt.plot(history.history['accuracy'])\n    plt.plot(history.history['val_accuracy'])\n    plt.title('Model Accuracy')\n    plt.ylabel('Accuracy')\n    plt.xlabel('Epoch')\n    plt.legend(['train', 'validation'], loc='upper left')\n    plt.show()\n\n    # Summarize history for loss\n    plt.figure(figsize = (8, 5))\n    #plt.xticks(np.arange(0, 10))\n    #plt.yticks(np.arange(0, 100))\n    plt.plot(history.history['loss'])\n    plt.plot(history.history['val_loss'])\n    plt.title('Model loss')\n    plt.ylabel('loss')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'validation'], loc='lower left')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"VGG16-Model "},{"metadata":{"trusted":true},"cell_type":"code","source":"def VGG16_MODEL(img_rows=IMG_SIZE, img_cols=IMG_SIZE, color_type=3):\n    # Remove fully connected layer and replace\n    # with softmax for classifying 10 classes\n    vgg16_model_2 = VGG16(weights=\"imagenet\", include_top=False)\n\n    # Freeze all layers of the pre-trained model\n    for layer in vgg16_model_2.layers:\n        layer.trainable = False\n        \n    x = vgg16_model_2.output\n    x = GlobalAveragePooling2D()(x)\n    x = Dense(1024, activation='relu')(x)\n    predictions = Dense(CLASSES, activation = 'softmax')(x)\n\n    model = Model(inputs = vgg16_model_2.input, outputs = predictions)\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Loading network...\")\nmodel_vgg16_2 = VGG16_MODEL(img_rows=IMG_SIZE, img_cols=IMG_SIZE)\n\nmodel_vgg16_2.summary()\n\nmodel_vgg16_2.compile(loss='categorical_crossentropy',\n                         optimizer='rmsprop',\n                         metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Model weights are saved at the end of every epoch\nearly_stopping = EarlyStopping(monitor='val_loss', patience=10, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"checkpoint = ModelCheckpoint(filepath='saved_models/weights_best_vgg16_model2.hdf5', \n                               verbose=1, save_best_only=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model_vgg16_2.fit_generator(training_generator,\n                         steps_per_epoch = 17943/50,\n                         epochs = EPOCHS, \n                         callbacks=[early_stopping, checkpoint],\n                         verbose = 1,\n                         validation_data = validation_generator,\n                         validation_steps = 4481/50)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_train_history(history)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def prediction():\n    for i in np.arange(10):\n        img_brute = test_data[i]\n\n        im = cv2.resize(cv2.cvtColor(img_brute, cv2.COLOR_BGR2RGB), (IMG_SIZE,IMG_SIZE)).astype(np.float32) / 255.0\n        im = np.expand_dims(im, axis =0)\n\n        img_display = cv2.resize(img_brute,(IMG_SIZE,IMG_SIZE))\n        plt.imshow(img_display, cmap='gray')\n\n        y_preds = model_vgg16_2.predict(im, batch_size=BATCHES, verbose=1)\n        print(y_preds)\n        y_prediction = np.argmax(y_preds)\n        print('Y Prediction: {}'.format(y_prediction))\n        print('Predicted as: {}'.format(CAT_MAP.get('c{}'.format(y_prediction))))\n\n        plt.show()\nprediction()","execution_count":null,"outputs":[]},{"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}