{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n# visulization\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n%matplotlib inline\n\nimport os\nimport gc # garbage collection\nimport glob # extract path via pattern matching\nfrom tqdm.notebook import tqdm # progressbar\nimport random\nimport math\nimport cv2 # read image\n# store to disk\nimport pickle\nimport h5py # like numpy array\n\n\nfrom sklearn.model_selection import train_test_split\nfrom keras.utils import to_categorical\n\nfrom keras.models import Sequential, Model\nfrom keras.models import load_model\nfrom keras.layers import Input, Dense, Conv2D, MaxPool2D, AveragePooling2D\nfrom keras.layers import Flatten, Dropout, BatchNormalization, Activation\nfrom keras.layers import Add\nfrom keras.optimizers import SGD, RMSprop, Adam\nfrom keras import regularizers\nimport keras\n\nfrom keras.callbacks import ModelCheckpoint, EarlyStopping\n# from keras.applications.vgg16 import VGG16\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Load and Explore Data"},{"metadata":{"_cell_guid":"","_uuid":"","trusted":true},"cell_type":"code","source":"ROOT_DIR = '../input/state-farm-distracted-driver-detection/'\nTRAIN_DIR = ROOT_DIR + 'imgs/train/'\nTEST_DIR = ROOT_DIR + 'imgs/test/'\ndriver_imgs_list = pd.read_csv(ROOT_DIR + \"driver_imgs_list.csv\")\nsample_submission = pd.read_csv(ROOT_DIR + \"sample_submission.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"random_list = np.random.permutation(len(driver_imgs_list))[:50]\ndf_copy = driver_imgs_list.iloc[random_list]\nimage_paths = [TRAIN_DIR+row.classname+'/'+row.img \n                   for (index, row) in df_copy.iterrows()]\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Prepare Training Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"img_path_list = []\nlabel_list = []\nfor index, row in driver_imgs_list.iterrows():\n    img_path_list.append('{0}{1}/{2}'.format(TRAIN_DIR, row.classname, row.img))\n    label_list.append(int(row.classname[1]))\n# One hot vector representation of labels\ny_labels_one_hot = to_categorical(label_list, dtype=np.int8)\nx_img_path = np.array(img_path_list)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"np.save('x_img_path.npy', x_img_path)\nnp.save('y_labels_one_hot.npy', y_labels_one_hot)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.utils import shuffle\n\nx_img_path_shuffled, y_labels_one_hot_shuffled = shuffle(x_img_path, y_labels_one_hot)\n\n# saving the shuffled file.\n# you can load them later using np.load().\nnp.save('y_labels_one_hot_shuffled.npy', y_labels_one_hot_shuffled)\nnp.save('x_img_path_shuffled.npy', x_img_path_shuffled)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n# Used this line as our filename array is not a numpy array.\nx_img_path_shuffled_numpy = np.array(x_img_path_shuffled)\n\nX_train_filenames, X_val_filenames, y_train, y_val = train_test_split(\n    x_img_path_shuffled_numpy, y_labels_one_hot_shuffled, test_size=0.2, random_state=1)\n\nprint(X_train_filenames.shape) # (3800,)\nprint(y_train.shape)           # (3800, 12)\n\nprint(X_val_filenames.shape)   # (950,)\nprint(y_val.shape)             # (950, 12)\n\n# You can save these files as well. As you will be using them later for training and validation of your model.\nnp.save('X_train_filenames.npy', X_train_filenames)\nnp.save('y_train.npy', y_train)\n\nnp.save('X_val_filenames.npy', X_val_filenames)\nnp.save('y_val.npy', y_val)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IMG_HEIGHT = 240\nIMG_WIDTH = 320\nCHANNEL = 1\nclass Img_Generator(keras.utils.Sequence):\n    def __init__(self, image_filenames, labels, batch_size) :\n        self.image_filenames = image_filenames\n        self.labels = labels\n        self.batch_size = batch_size\n    def __len__(self) :\n        return (np.ceil(len(self.image_filenames) / float(self.batch_size))).astype(np.int)\n    def __getitem__(self, idx) :\n        batch_x = self.image_filenames[idx * self.batch_size : (idx+1) * self.batch_size]\n        batch_y = self.labels[idx * self.batch_size : (idx+1) * self.batch_size]\n        img_list = []\n        for file_name in batch_x:\n            original_img = cv2.imread(file_name, 0)\n            im = cv2.resize(original_img, (320, 240))\n            #color = [0, 0, 0]\n            #new_im = cv2.copyMakeBorder(im, 40, 40, 0, 0, cv2.BORDER_CONSTANT, value=color)\n            #im = cv2.resize(new_im, (224, 224))\n            img_list.append(im)\n        img_batch = np.array(img_list)\n        img_batch = np.expand_dims(img_batch, axis=-1)\n        return img_batch, np.array(batch_y)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_gen = Img_Generator(X_train_filenames, y_train, 32)\nval_gen = Img_Generator(X_val_filenames, y_val, 32)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Training"},{"metadata":{"trusted":true},"cell_type":"code","source":"MODELS_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":"from keras.callbacks.callbacks import ModelCheckpoint, EarlyStopping\n\nfilepath = MODELS_DIR+'/epoch{epoch:02d}-loss{loss:.2f}-val_loss{val_loss:.2f}.hdf5'\n# checkpoint\nmodel_checkpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, \n                                   save_best_only=True, save_weights_only=False, mode='min', period=1)\n\n# early stopping: patience = epocs\nearly_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=3, verbose=1,\n                               mode='min', baseline=None, restore_best_weights=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# No need for adaptive learning alogrithms like: RmsProp, Adam\nfrom keras.callbacks.callbacks import LearningRateScheduler, ReduceLROnPlateau\n# This function keeps the learning rate at 0.01 for the first five epochs\n# and decreases it exponentially after that.\ndef learning_rate_scheduler(epoch):\n    if epoch < 5:\n        return 0.01\n    else:\n        return 0.01 * math.exp(0.1 * (5 - epoch))\n\nlr_scheduler = LearningRateScheduler(learning_rate_scheduler, verbose=1)\n# OR\n# lr_scheduler = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5, \n#                                             verbose=1, mode='min', min_delta=0.0001, min_lr=0.0001)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_model_loss(history):\n    '''\n    function to plot learning trace\n    '''\n    plt.plot(history['loss'])\n    plt.plot(history['val_loss'])\n    plt.title('Model Loss')\n    plt.ylabel('Loss')\n    plt.xlabel('Epoch')\n    plt.legend(['train', 'valid'], loc='upper left')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications import MobileNetV2, ResNet50, VGG19, MobileNet\nmodel = ResNet50(include_top=True, weights=None, input_shape=(IMG_HEIGHT, IMG_WIDTH, 1), pooling=None, classes=10)\nmodel.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"EPOCHS = 10\nhistory1 = model.fit_generator(train_gen, steps_per_epoch=None, epochs=EPOCHS, verbose=1, callbacks=[model_checkpoint, early_stopping], validation_data=val_gen,\n              validation_steps=None, validation_freq=1, class_weight=None, max_queue_size=10, workers=1, use_multiprocessing=False, shuffle=True, initial_epoch=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_model_loss(history1.history)","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}