{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Problem description\n\nAccording to the CDC motor vehicle safety division, one in five car accidents is caused by a distracted driver. Sadly, this translates to 425,000 people injured and 3,000 people killed by distracted driving every year.\n\nState Farm hopes to improve these alarming statistics, and better insure their customers, by testing whether dashboard cameras can automatically detect drivers engaging in distracted behaviors. Given a dataset of 2D dashboard camera images, State Farm is challenging Kagglers to classify each driver's behavior. Are they driving attentively, wearing their seatbelt, or taking a selfie with their friends in the backseat?","metadata":{}},{"cell_type":"code","source":"import os, shutil\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nimport random\n\nimport tensorflow as tf\n\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D, Dense, Dropout, Flatten, MaxPooling2D\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import optimizers","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:33:47.312970Z","iopub.execute_input":"2021-07-20T16:33:47.313374Z","iopub.status.idle":"2021-07-20T16:33:51.873541Z","shell.execute_reply.started":"2021-07-20T16:33:47.313283Z","shell.execute_reply":"2021-07-20T16:33:51.872675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_dir = \"../input/state-farm-distracted-driver-detection/\"\nimg_folder = os.path.join(base_dir, 'imgs/')\ntrain_imgs = os.path.join(img_folder, 'train/')\ntest_imgs = os.path.join(img_folder, 'test/')\ndriver_imgs_list = pd.read_csv(os.path.join(base_dir, 'driver_imgs_list.csv'))\nsample_sub = pd.read_csv(os.path.join(base_dir, 'sample_submission.csv'))","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:33:51.876770Z","iopub.execute_input":"2021-07-20T16:33:51.877048Z","iopub.status.idle":"2021-07-20T16:33:52.104548Z","shell.execute_reply.started":"2021-07-20T16:33:51.877020Z","shell.execute_reply":"2021-07-20T16:33:52.103483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"driver_imgs_list.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:33:52.108397Z","iopub.execute_input":"2021-07-20T16:33:52.108659Z","iopub.status.idle":"2021-07-20T16:33:52.142608Z","shell.execute_reply.started":"2021-07-20T16:33:52.108634Z","shell.execute_reply":"2021-07-20T16:33:52.141875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"driver_imgs_list.shape","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:33:52.144138Z","iopub.execute_input":"2021-07-20T16:33:52.144496Z","iopub.status.idle":"2021-07-20T16:33:52.149958Z","shell.execute_reply.started":"2021-07-20T16:33:52.144462Z","shell.execute_reply":"2021-07-20T16:33:52.148955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_sub.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:33:52.151403Z","iopub.execute_input":"2021-07-20T16:33:52.151747Z","iopub.status.idle":"2021-07-20T16:33:52.176832Z","shell.execute_reply.started":"2021-07-20T16:33:52.151710Z","shell.execute_reply":"2021-07-20T16:33:52.175988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"classes = ['c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9']\n\nclass_def = {'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":{"execution":{"iopub.status.busy":"2021-07-20T16:33:52.178069Z","iopub.execute_input":"2021-07-20T16:33:52.178429Z","iopub.status.idle":"2021-07-20T16:33:52.184441Z","shell.execute_reply.started":"2021-07-20T16:33:52.178394Z","shell.execute_reply":"2021-07-20T16:33:52.183536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Display 20 sample images","metadata":{}},{"cell_type":"code","source":"fig = plt.figure(figsize=(20, 18))\ncolumns = 5\nrows = 4\nfor i in range(1, columns*rows +1):\n    pic_idx = random.randint(0, driver_imgs_list.shape[0])\n    im = Image.open(r\"../input/state-farm-distracted-driver-detection/imgs/train/\"+ \n                    str(driver_imgs_list.loc[pic_idx, 'classname']) +'/' \n                    +str(driver_imgs_list.loc[pic_idx, 'img' ]))\n    fig.add_subplot(rows, columns, i)\n    plt.imshow(im)\n    plt.title('State of driving: ' + class_def[(driver_imgs_list.loc[pic_idx, 'classname'])])\n    plt.axis('off')\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:33:52.185862Z","iopub.execute_input":"2021-07-20T16:33:52.186457Z","iopub.status.idle":"2021-07-20T16:33:54.740773Z","shell.execute_reply.started":"2021-07-20T16:33:52.186420Z","shell.execute_reply":"2021-07-20T16:33:54.739841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# size of each image is (640, 480)\nim = Image.open(\"../input/state-farm-distracted-driver-detection/imgs/train/c7/img_100702.jpg\")\nw, h = im.size\nprint(w, h)","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:33:54.743507Z","iopub.execute_input":"2021-07-20T16:33:54.743886Z","iopub.status.idle":"2021-07-20T16:33:54.757356Z","shell.execute_reply.started":"2021-07-20T16:33:54.743835Z","shell.execute_reply":"2021-07-20T16:33:54.756609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(rescale=1./255)\ntest_datagen = ImageDataGenerator(rescale=1./255)","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:33:54.759190Z","iopub.execute_input":"2021-07-20T16:33:54.759717Z","iopub.status.idle":"2021-07-20T16:33:54.764130Z","shell.execute_reply.started":"2021-07-20T16:33:54.759678Z","shell.execute_reply":"2021-07-20T16:33:54.763220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_size = (256, 256)\nval_frac = 0.12\nbatch_size = 16\ntrain_dir = \"../input/state-farm-distracted-driver-detection/imgs/train/\"\n\ntrain_generator = tf.keras.preprocessing.image_dataset_from_directory(train_dir,\n                                                             labels = 'inferred',\n                                                             label_mode='categorical',\n                                                             image_size=image_size,\n                                                             batch_size=batch_size,\n                                                             seed=1,\n                                                             shuffle=True,\n                                                             validation_split=val_frac,\n                                                             subset='training')\nval_generator = tf.keras.preprocessing.image_dataset_from_directory(train_dir,\n                                                             labels = 'inferred',\n                                                             label_mode='categorical',\n                                                             image_size=image_size,\n                                                             batch_size=batch_size,\n                                                             seed=1,\n                                                             shuffle=True,\n                                                             validation_split=val_frac,\n                                                             subset='validation')","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:33:54.765415Z","iopub.execute_input":"2021-07-20T16:33:54.766027Z","iopub.status.idle":"2021-07-20T16:34:13.474793Z","shell.execute_reply.started":"2021-07-20T16:33:54.765988Z","shell.execute_reply":"2021-07-20T16:34:13.473355Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def normalize(image,label):\n    image = tf.cast(image/255. ,tf.float32)\n    return image,label\n\ntrain_generator = train_generator.map(normalize)\nval_generator = val_generator.map(normalize)","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:34:13.476089Z","iopub.execute_input":"2021-07-20T16:34:13.476454Z","iopub.status.idle":"2021-07-20T16:34:13.525481Z","shell.execute_reply.started":"2021-07-20T16:34:13.476416Z","shell.execute_reply":"2021-07-20T16:34:13.524686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for data_batch, labels_batch in train_generator:\n    print('data batch shape:', data_batch.shape)\n    print('labels batch shape:', labels_batch.shape)\n    break","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:34:13.526735Z","iopub.execute_input":"2021-07-20T16:34:13.527285Z","iopub.status.idle":"2021-07-20T16:34:14.750071Z","shell.execute_reply.started":"2021-07-20T16:34:13.527225Z","shell.execute_reply":"2021-07-20T16:34:14.749158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"callback = tf.keras.callbacks.EarlyStopping(monitor='loss', mode='min', patience=4, verbose=1)","metadata":{"execution":{"iopub.status.busy":"2021-07-17T12:00:05.112353Z","iopub.execute_input":"2021-07-17T12:00:05.112925Z","iopub.status.idle":"2021-07-17T12:00:05.121843Z","shell.execute_reply.started":"2021-07-17T12:00:05.112879Z","shell.execute_reply":"2021-07-17T12:00:05.120323Z"}}},{"cell_type":"code","source":"model = Sequential()\nmodel.add(Conv2D(32, (3, 3), activation='relu',input_shape=(256, 256, 3)))\nmodel.add(MaxPooling2D((2, 2)))\nmodel.add(Conv2D(64, (3, 3), activation='relu'))\nmodel.add(MaxPooling2D((2, 2)))\nmodel.add(Conv2D(128, (3, 3), activation='relu'))\nmodel.add(MaxPooling2D((2, 2)))\nmodel.add(Conv2D(128, (3, 3), activation='relu'))\nmodel.add(MaxPooling2D((2, 2)))\nmodel.add(Conv2D(256, (3, 3), activation='relu'))\nmodel.add(MaxPooling2D((2, 2)))\nmodel.add(Conv2D(512, (3, 3), activation='relu'))\nmodel.add(MaxPooling2D((2, 2)))\nmodel.add(Flatten())\nmodel.add(Dense(1024, activation='relu'))\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dense(10, activation='softmax'))","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:34:14.751450Z","iopub.execute_input":"2021-07-20T16:34:14.751950Z","iopub.status.idle":"2021-07-20T16:34:14.890735Z","shell.execute_reply.started":"2021-07-20T16:34:14.751910Z","shell.execute_reply":"2021-07-20T16:34:14.889932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:34:14.892005Z","iopub.execute_input":"2021-07-20T16:34:14.892347Z","iopub.status.idle":"2021-07-20T16:34:14.906655Z","shell.execute_reply.started":"2021-07-20T16:34:14.892312Z","shell.execute_reply":"2021-07-20T16:34:14.904905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile('rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:34:14.909588Z","iopub.execute_input":"2021-07-20T16:34:14.909867Z","iopub.status.idle":"2021-07-20T16:34:14.926306Z","shell.execute_reply.started":"2021-07-20T16:34:14.909839Z","shell.execute_reply":"2021-07-20T16:34:14.925440Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(\ntrain_generator,\nsteps_per_epoch=240,\nepochs=10,\nvalidation_data=val_generator,\nvalidation_steps=60)","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:34:14.927682Z","iopub.execute_input":"2021-07-20T16:34:14.928256Z","iopub.status.idle":"2021-07-20T16:37:50.365172Z","shell.execute_reply.started":"2021-07-20T16:34:14.928209Z","shell.execute_reply":"2021-07-20T16:37:50.364020Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('distracted_driver.h5')","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:37:50.368859Z","iopub.execute_input":"2021-07-20T16:37:50.369161Z","iopub.status.idle":"2021-07-20T16:37:50.458888Z","shell.execute_reply.started":"2021-07-20T16:37:50.369130Z","shell.execute_reply":"2021-07-20T16:37:50.457847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr_loss = history.history['loss']\ntr_acc = history.history['accuracy']\nval_loss = history.history['val_loss']\nval_acc = history.history['val_accuracy']\nepochs = range(1, len(tr_loss)+1)\n\nplt.clf()\nfig, (ax1, ax2) = plt.subplots(1,2, figsize=(18,5))\nfig\n\nax1.plot(epochs, tr_loss, 'b', label='Training loss')\nax1.plot(epochs, val_loss, 'r', label='Validation loss')\nax1.set_title('Training & Validation loss')\nax1.set_xlabel('epochs')\nax1.set_ylabel('loss')\nax1.legend()\n\nax2.plot(epochs, tr_acc, 'b', label='Training acc')\nax2.plot(epochs, val_acc, 'r', label='Validation acc')\nax2.set_title('Training & Validation acc')\nax2.set_xlabel('epochs')\nax2.set_ylabel('accuracy')\nax2.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:37:50.460328Z","iopub.execute_input":"2021-07-20T16:37:50.460720Z","iopub.status.idle":"2021-07-20T16:37:50.812758Z","shell.execute_reply.started":"2021-07-20T16:37:50.460680Z","shell.execute_reply":"2021-07-20T16:37:50.811805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction on test images & submission","metadata":{}},{"cell_type":"markdown","source":"img_path = \"../input/state-farm-distracted-driver-detection/imgs/\"\ntest_generator = test_datagen.flow_from_directory(\n    directory=img_path,\n    target_size=image_size,\n    color_mode=\"rgb\",\n    batch_size=1,\n    class_mode='categorical',\n    shuffle=False,\n    classes=['test']\n)","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:37:50.815844Z","iopub.execute_input":"2021-07-20T16:37:50.816223Z","iopub.status.idle":"2021-07-20T16:41:22.283653Z","shell.execute_reply.started":"2021-07-20T16:37:50.816185Z","shell.execute_reply":"2021-07-20T16:41:22.282527Z"}}},{"cell_type":"markdown","source":"preds = model.predict(test_generator, steps=79726)","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:42:06.439296Z","iopub.execute_input":"2021-07-20T16:42:06.439722Z","iopub.status.idle":"2021-07-20T16:57:51.234139Z","shell.execute_reply.started":"2021-07-20T16:42:06.439685Z","shell.execute_reply":"2021-07-20T16:57:51.233236Z"}}},{"cell_type":"markdown","source":"test_ids = sorted(os.listdir(test_imgs))\npred_df = pd.DataFrame(columns = ['img','c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9'])\nfor i in range(len(preds)):    \n    pred_df.loc[i, 'img'] = test_ids[i]\n    pred_df.loc[i, 'c0':'c9'] = preds[i]","metadata":{"execution":{"iopub.status.busy":"2021-07-20T16:58:06.332189Z","iopub.execute_input":"2021-07-20T16:58:06.332560Z","iopub.status.idle":"2021-07-20T17:07:40.285012Z","shell.execute_reply.started":"2021-07-20T16:58:06.332528Z","shell.execute_reply":"2021-07-20T17:07:40.284154Z"}}},{"cell_type":"markdown","source":"pred_df.to_csv('predictions.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-07-20T17:08:01.385692Z","iopub.execute_input":"2021-07-20T17:08:01.386030Z","iopub.status.idle":"2021-07-20T17:08:03.071752Z","shell.execute_reply.started":"2021-07-20T17:08:01.385994Z","shell.execute_reply":"2021-07-20T17:08:03.070513Z"}}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}