{"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!pip install git+https://github.com/qubvel/efficientnet\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":"import efficientnet.keras as efn \nmodel = efn.EfficientNetB0(weights=None, classes=10, input_shape=(IMG_HEIGHT,IMG_WIDTH,1)) \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":{"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}