{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","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)\nimport cv2 #opencv library\nimport glob\nimport matplotlib.pyplot as plt  #plotting library\nimport matplotlib.image as mpimg\nfrom sklearn.model_selection import train_test_split\nimport tensorflow\nimport random\nfrom keras.callbacks import EarlyStopping\nfrom PIL import Image\nimport h5py\nimport os\nimport gc\nprint(os.listdir(\"../input/state-farm-distracted-driver-detection/imgs\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"directory = '../input/state-farm-distracted-driver-detection/imgs/train'\ntest_directory = '../input/state-farm-distracted-driver-detection/imgs/test/'\n# random_test = '../input/driver/'\nclasses = ['c0','c1','c2','c3','c4','c5','c6','c7','c8','c9']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"training_data = []\ntesting_data = []","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Create Training dataset**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_training_data():\n    for category in classes:\n        print(category + \"folder.....\")      \n        path = os.path.join(directory,category)\n        class_num = classes.index(category)\n        \n        for img in os.listdir(path):\n            img_array = cv2.imread(os.path.join(path,img),cv2.IMREAD_GRAYSCALE)\n            new_img = cv2.resize(img_array,(240,240))\n            \n            training_data.append([\n                new_img,class_num])\n    print(\"created training data array...\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Create Testing dataset**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_testing_data():        \n    for img in os.listdir(test_directory):\n        img_array = cv2.imread(os.path.join(test_directory,img),cv2.IMREAD_GRAYSCALE)\n        new_img = cv2.resize(img_array,(240,240))\n        testing_data.append([img,\n            new_img])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in classes:\n    path = os.path.join(directory,i)\n    for img in os.listdir(path):\n        img_array = cv2.imread(os.path.join(path,img),cv2.IMREAD_GRAYSCALE)\n        img_array = cv2.resize(img_array,(240,240))\n        print(img_array.shape)\n#         RGB_img = cv2.cvtColor(img_array, cv2.COLOR_BGR2RGB) # BGR to RGB conversion\n        plt.imshow(img_array)\n        plt.show()\n        break\n    break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"create_training_data()\n# create_testing_data()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"random.shuffle(training_data)\nx = []\ny = []\nfor features, label in training_data:\n    x.append(features)\n    y.append(label)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"training_data.clear()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(x))\nx[0].shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y[0:13]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.utils import np_utils\ny_cat = np_utils.to_categorical(y,num_classes=10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_cat[0:14] # array of encodings","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X1 = np.array(x).reshape(-1,240,240,1)\nX = X1.astype('float32') / 255.0\nX[0].shape\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del X1\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train,X_test,y_train,y_test = train_test_split(X,y_cat,test_size=0.3,random_state=50)\n# X_train = X_train.astype('float32') / 255\n# X_test = X_test.astype('float32') / 255","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del X\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del y_cat\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Shape of train images is:\", X_train.shape)\nprint(\"Shape of validation images is:\", X_test.shape)\nprint(\"Shape of labels is:\", y_train.shape)\nprint(\"Shape of labels is:\", y_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"callbacks = [EarlyStopping(monitor='val_acc',patience=5)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"timg = testing_data[3][1]\nplt.imshow(timg)\nplt.show()\ntest_img = np.array(timg).reshape(-1,240,240,1) / 255.0\npreds = model.predict(test_img)\nclass_idx = np.argmax(preds[0])\nclass_output = model.output[:, class_idx]\nclass_idx","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# testing_data.clear()\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Resnet-50**"},{"metadata":{},"cell_type":"markdown","source":"Package imports"},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nfrom keras import layers\nfrom keras.layers import Input, Add, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D, GlobalMaxPooling2D\nfrom keras.models import Model, load_model\nfrom keras.preprocessing import image\nfrom keras.utils import layer_utils\nfrom keras.utils.data_utils import get_file\nfrom keras.applications.imagenet_utils import preprocess_input\nimport pydot\nfrom IPython.display import SVG\nfrom keras.utils.vis_utils import model_to_dot\nfrom keras.utils import plot_model\n\nfrom keras.initializers import glorot_uniform\nimport scipy.misc\nfrom matplotlib.pyplot import imshow\n\nfrom keras.initializers import glorot_uniform\nfrom keras.layers import Input, Add, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D, GlobalMaxPooling2D","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Identity Block"},{"metadata":{"trusted":true},"cell_type":"code","source":"# x is input, y=F(x)\n# identity block simply means input should be equal to output. \n#  y = x + F(x)   the layers in a traditional network are learning the true output H(x)\n# F(x) = y - x   the layers in a residual network are learning the residual F(x)\n# Hence, the name: Residual Block.\n\n\n\ndef identity_block(X, f, filters, stage, block):\n    \"\"\"\n   \n    Arguments:\n    X -- input of shape (m, height, width, channel)\n    f -- shape of the middle CONV's window for the main path\n    filters -- python list of integers, defining the number of filters in the CONV layers of the main path\n    stage -- integer, used to name the layers, depending on their position in the network\n    block -- string/character, used to name the layers, depending on their position in the network\n    \n    Returns:\n    X -- output of the identity block, tensor of shape (n_H, n_W, n_C)\n    \"\"\"\n    \n    # defining name basis\n    conv_name_base = 'res' + str(stage) + block + '_branch'\n    bn_name_base = 'bn' + str(stage) + block + '_branch'\n    \n    # Retrieve Filters\n    F1, F2, F3 = filters\n    \n    # Saving the input value.we need this later to add to the output. \n    X_shortcut = X\n    \n    # First component of main path\n    X = Conv2D(filters = F1, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2a')(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2a')(X)\n    X = Activation('relu')(X)\n\n    \n    # Second component of main path (≈3 lines)\n    X = Conv2D(filters = F2, kernel_size = (f, f), strides = (1,1), padding = 'same', name = conv_name_base + '2b')(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2b')(X)\n    X = Activation('relu')(X)\n\n    # Third component of main path (≈2 lines)\n    X = Conv2D(filters = F3, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2c')(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2c')(X)\n\n    # Final step: Add shortcut value to main path, and pass it through a RELU activation \n    X = Add()([X, X_shortcut])\n    X = Activation('relu')(X)\n    \n    \n    return X","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Convolutional Block"},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndef convolutional_block(X, f, filters, stage, block, s = 2):\n    \n    # defining name basis\n    conv_name_base = 'res' + str(stage) + block + '_branch'\n    bn_name_base = 'bn' + str(stage) + block + '_branch'\n    \n    # Retrieve Filters\n    F1, F2, F3 = filters\n    \n    # Save the input value\n    X_shortcut = X\n\n\n    # First layer \n    X = Conv2D(F1, (1, 1), strides = (s,s), name = conv_name_base + '2a')(X) # 1,1 is filter size\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2a')(X)  # normalization on channels\n    X = Activation('relu')(X)\n\n      \n    # Second layer  (f,f)=3*3 filter by default\n    X = Conv2D(filters = F2, kernel_size = (f, f), strides = (1,1), padding = 'same', name = conv_name_base + '2b')(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2b')(X)\n    X = Activation('relu')(X)\n\n\n    # Third layer\n    X = Conv2D(filters = F3, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2c')(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2c')(X)\n\n\n    ##### SHORTCUT PATH #### \n    X_shortcut = Conv2D(filters = F3, kernel_size = (1, 1), strides = (s,s), padding = 'valid', name = conv_name_base + '1')(X_shortcut)\n    X_shortcut = BatchNormalization(axis = 3, name = bn_name_base + '1')(X_shortcut)\n\n    # Final step: Add shortcut value here, and pass it through a RELU activation \n    X = Add()([X, X_shortcut])\n    X = Activation('relu')(X)\n    \n    \n    return X","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"ResNet compilation"},{"metadata":{"trusted":true},"cell_type":"code","source":"#Each ResNet block is either 2 layer deep\ndef ResNet50(input_shape=(240, 240, 1), classes=10):\n    \"\"\"\n    Implementation of the ResNet50 architecture:\n    CONV2D -> BATCHNORM -> RELU -> MAXPOOL -> CONVBLOCK -> IDBLOCK*2 -> CONVBLOCK -> IDBLOCK*3\n    -> CONVBLOCK -> IDBLOCK*5 -> CONVBLOCK -> IDBLOCK*2 -> AVGPOOL -> TOPLAYER\n\n    \"\"\"\n\n    # Define the input as a tensor with shape input_shape\n    X_input = Input(input_shape)\n\n    # Zero-Padding\n    X = ZeroPadding2D((3, 3))(X_input) #3,3 padding\n\n    # Stage 1\n    X = Conv2D(64, (7, 7), strides=(2, 2), name='conv1')(X) #64 filters of 7*7 \n    X = BatchNormalization(axis=3, name='bn_conv1')(X) #batchnorm applied on channels\n    X = Activation('relu')(X)\n    X = MaxPooling2D((3, 3), strides=(2, 2))(X) #window size is 3*3\n\n    # Stage 2\n    X = convolutional_block(X, f=3, filters=[64, 64, 256], stage=2, block='a', s=1)\n    # convolutional_block is a function defined above. Convolutional_block have 3 layers.\n    #filters=[64, 64, 256] first 64 is for 1st layer and 2nd 64 is for 2nd layer and 256 is for 3rd layer of convultional block   \n    # below are the conv layers from convolutional_block function\n    #X = Conv2D(F1, (1, 1), strides = (s,s), name = conv_name_base + '2a')(X)\n    #X = Conv2D(F2, kernel_size = (f, f), strides = (1,1), padding = 'same', name = conv_name_base + '2b')(X)\n    #X = Conv2D(F3, (1, 1), strides = (s,s), name = conv_name_base + '2a')(X)\n   \n    X = identity_block(X, 3, [64, 64, 256], stage=2, block='b') \n    #X = Conv2D(filters = F1, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2a')(X)\n    #X = Conv2D(filters = F2, kernel_size = (f, f), strides = (1,1), padding = 'same', name = conv_name_base + '2b')(X)\n    #X = Conv2D(filters = F3, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2c')(X)\n  \n    X = identity_block(X, 3, [64, 64, 256], stage=2, block='c')\n    #X = Conv2D(filters = F1, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2a')(X)\n    #X = Conv2D(filters = F2, kernel_size = (f, f), strides = (1,1), padding = 'same', name = conv_name_base + '2b')(X)\n    #X = Conv2D(filters = F3, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2c')(X)\n\n\n    ### START CODE HERE ###\n\n    # Stage 3 \n    X = convolutional_block(X, f = 3, filters = [128, 128, 512], stage = 3, block='a', s = 2)\n    X = identity_block(X, 3, [128, 128, 512], stage=3, block='b')\n    X = identity_block(X, 3, [128, 128, 512], stage=3, block='c')\n    X = identity_block(X, 3, [128, 128, 512], stage=3, block='d')\n\n    # Stage 4 \n    X = convolutional_block(X, f = 3, filters = [256, 256, 1024], stage = 4, block='a', s = 2)\n    X = identity_block(X, 3, [256, 256, 1024], stage=4, block='b')\n    X = identity_block(X, 3, [256, 256, 1024], stage=4, block='c')\n    X = identity_block(X, 3, [256, 256, 1024], stage=4, block='d')\n    X = identity_block(X, 3, [256, 256, 1024], stage=4, block='e')\n    X = identity_block(X, 3, [256, 256, 1024], stage=4, block='f')\n\n    # Stage 5 \n    X = convolutional_block(X, f = 3, filters = [512, 512, 2048], stage = 5, block='a', s = 2)\n    X = identity_block(X, 3, [512, 512, 2048], stage=5, block='b')\n    X = identity_block(X, 3, [512, 512, 2048], stage=5, block='c')\n\n    # AVGPOOL \n    X = AveragePooling2D((2,2), name=\"avg_pool\")(X)\n\n    ### END CODE HERE ###\n\n    # output layer\n    X = Flatten()(X)\n    X = Dense(classes, activation='softmax', name='fc' + str(classes), kernel_initializer = glorot_uniform(seed=0))(X)\n    \n    \n    # Create model\n    model = Model(inputs = X_input, outputs = X, name='ResNet50')\n\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"model = ResNet50(input_shape = (240, 240, 1), classes = 10)"},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# resnet_train = model.fit(X_train, y_train, epochs = 6, verbose = 1,batch_size = 32, validation_data=(X_test,y_test),callbacks=callbacks) \nresnet_train = model.fit(X_train, y_train, epochs = 6, verbose = 1,batch_size = 32, validation_data=(X_test,y_test)) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"### Plot train and validation curves\nloss = resnet_train.history['loss']\nv_loss = resnet_train.history['val_loss']\n\nacc = resnet_train.history['accuracy']\nv_acc = resnet_train.history['val_accuracy']\n\nepochs = range(len(loss))\n\nfig = plt.figure(figsize=(9, 5))\nplt.subplot(1, 2, 1)\nplt.yscale('log')\nplt.plot(epochs, loss, linestyle='--', linewidth=3, color='orange', alpha=0.7, label='Train Loss')\nplt.plot(epochs, v_loss, linestyle='-.', linewidth=2, color='lime', alpha=0.8, label='Valid Loss')\nplt.ylim(0, 100)\nplt.xlabel('Epochs', fontsize=11)\nplt.ylabel('Loss', fontsize=12)\nplt.legend(fontsize=12)\nplt.subplot(1, 2, 2)\nplt.plot(epochs, acc, linestyle='--', linewidth=3, color='orange', alpha=0.7, label='Train Acc')\nplt.plot(epochs, v_acc, linestyle='-.', linewidth=2, color='lime', alpha=0.8, label='Valid Acc') \nplt.xlabel('Epochs', fontsize=11)\nplt.ylabel('Accuracy', fontsize=12)\nplt.legend(fontsize=12)\nplt.tight_layout()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del X_train\ndel X_test\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"create_testing_data()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class_names = {\n        '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'\n    }\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path2img = testing_data[9][0]\nimg_array = cv2.imread(os.path.join(test_directory,path2img))\nnew_img = cv2.resize(img_array,(240,240))\nnew_img = cv2.cvtColor(new_img, cv2.COLOR_BGR2RGB) # BGR to RGB conversion\nplt.imshow(new_img)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"timg = testing_data[9][1]\nplt.imshow(timg)\nplt.show()\ntest_img = np.array(timg).reshape(-1,240,240,1) / 255.0\npreds = model.predict(test_img)\nclass_idx = np.argmax(preds[0])\n\n# class_output = model.output[:, class_idx]\n# class_output\nind = 'c' + str(class_idx)\nprint(class_names[ind] + ' | Class index: ' + str(class_idx))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# preds = model.evaluate(test_x, test_y)\n# print (\"Loss = \" + str(preds[0]))\n# print (\"Test Accuracy = \" + str(preds[1]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Save Model and weights\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"# serialize model to JSON\nmodel_json = model.to_json()\nwith open(\"Model_v2.json\", \"w\") as json_file:\n    json_file.write(model_json)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save_weights(\"custom_resnet50_v2.h5\")","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}