{"cells":[{"metadata":{"_uuid":"79b34d822742085a4447676b08b6573587d2fe93"},"cell_type":"markdown","source":"# **EXZEO Hiring Challenge Solutions**"},{"metadata":{"_uuid":"1ada52c81997756f0dfddbac7dbd54d9c68d3f4a"},"cell_type":"markdown","source":"## By Anubhav Kesari"},{"metadata":{"trusted":true,"_uuid":"239e8464a47560d6add88ef1ae081375eaa64f1d"},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input/exzeodata/sample/train\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ecc4da08b02cd16731adcc27a69af5c5263778b3"},"cell_type":"markdown","source":"## **Steps Involved** \n"},{"metadata":{"_uuid":"b6c2cdfba67b7b510add355918db0abe6a899d9b"},"cell_type":"markdown","source":"### 1. Getting the required imports in the environment"},{"metadata":{"trusted":true,"_uuid":"f8e69cbcadb38cad515d6ca8649882adb0313669"},"cell_type":"code","source":"import sys\nimport os\nfrom os.path import isfile, join\nfrom os import listdir\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import optimizers\nfrom keras.models import Sequential, Model\nfrom keras.layers import Dropout, Flatten, Dense, Activation\nfrom keras.layers.convolutional import Conv2D, MaxPooling2D\nfrom keras import callbacks\nimport pandas as pd\nimport numpy as np\nimport keras\nimport matplotlib.pyplot as plt\nfrom keras.layers import Dense, GlobalAveragePooling2D\nfrom keras.applications import MobileNet\nfrom keras.preprocessing import image\nfrom keras.applications.mobilenet import preprocess_input\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Model\nfrom keras.optimizers import Adam\nfrom keras.applications.resnet50 import ResNet50\nfrom keras.preprocessing import image\nfrom keras.preprocessing.image import load_img, img_to_array\nfrom keras.applications.resnet50 import preprocess_input\nfrom sklearn.metrics import accuracy_score, f1_score\nfrom keras.optimizers import Adam, SGD","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"627548ee53dc80d52d65ce49b395a51fd726193c"},"cell_type":"code","source":"# dataset=\"../input/exzeodata/sample\"\ntrain_data_dir=\"../input/exzeodata/sample/train\"\ntest=\"../input/exzeodata/sample/test\"","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"320982380ee6b5794679e5c8d9c4227a811c1a68"},"cell_type":"markdown","source":"## **Creating our custom CNN Model for Classification**"},{"metadata":{"_uuid":"daa580f7fd0572f399881de85c3030030a9c3bea"},"cell_type":"markdown","source":"## The Hyperparams that we have here -"},{"metadata":{"trusted":true,"_uuid":"286a42574ba7f7a68bf9829470f89abbc56f8cd4"},"cell_type":"code","source":"img_width, img_height = 150, 150\nnb_train_samples = 350\nnb_validation_samples = 150\nnb_filters1 = 32\nnb_filters2 = 64\nconv1_size = 3\nconv2_size = 2\npool_size = 2\nclasses_num = 2\nbatch_size = 32\nlr = 0.0001\nepochs = 5","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8683a412daffb3112af351ad1874114dc573a783"},"cell_type":"markdown","source":"## Creating the CNN Model - Model1"},{"metadata":{"trusted":true,"_uuid":"64596d3d18e35123d6d289d40215a70ba8d0915f"},"cell_type":"code","source":"def img_to_tensor(image_path, target_size):\n    img = load_img(image_path, target_size=target_size)\n    tensor = img_to_array(img)\n    tensor = np.expand_dims(tensor, axis=0)\n    print(\"Image \"\"\" + str(image_path) +\n          \" \"\" converted to tensor with shape \" + str(tensor.shape))\n    return tensor","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"dbe8107748fcd0ad91e94421f9cf733e0fbdddb1"},"cell_type":"markdown","source":"## **Our Architecture of Custom CNN:**"},{"metadata":{"trusted":true,"_uuid":"ab38b8eb0bc5ff94c69de1774c61ace1d6111024"},"cell_type":"code","source":"def getCustommodel():\n    model1 = Sequential()\n    model1.add(Conv2D(32, (3, 3), padding=\"same\", input_shape=(img_width, img_height, 3), activation='relu'))\n    model1.add(Conv2D(32, (3, 3), activation='relu'))\n    model1.add(MaxPooling2D(pool_size=(2, 2)))\n    model1.add(Dropout(0.2))\n\n    model1.add(Conv2D(64, (3, 3), padding=\"same\", activation='relu'))\n    model1.add(Conv2D(64, (3, 3), activation='relu'))\n    model1.add(MaxPooling2D(pool_size=(2, 2)))\n\n    model1.add(Flatten())\n    model1.add(Dense(512, activation='relu'))\n    model1.add(Dropout(0.2))\n    model1.add(Dense(2, activation='softmax'))\n\n    model1.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.01, momentum=0.9, nesterov=True), \n                  metrics=['accuracy'])\n    model1.summary()\n    \n    return model1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e908db158cf34a36d20fa1ab9774ec7b01177614"},"cell_type":"code","source":"m=getCustommodel()\nm.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ce0324e97126d81dbae4ddee5ec421b07ca16f98"},"cell_type":"markdown","source":"##  **PreTrained MobileNet Architecture as Transfer Learning**"},{"metadata":{"trusted":true,"_uuid":"933bdf5554cadf7ad1861acf39b02b4fd47eddc0"},"cell_type":"code","source":"def getpretrainedmodel():\n    base_model = MobileNet(weights='imagenet', include_top=False)\n    x = base_model.output\n    x = GlobalAveragePooling2D()(x)\n    x = Dense(1024, activation='relu')(x)\n    x = Dense(1024, activation='relu')(x)  # dense layer 2\n    x = Dense(512, activation='relu')(x)  # dense layer 3\n    preds = Dense(2, activation='softmax')(x)\n    model = Model(inputs=base_model.input, outputs=preds)\n    for layer in model.layers[:20]:\n        layer.trainable = False\n    for layer in model.layers[20:]:\n        layer.trainable = True\n    model.compile(optimizer='Adam', loss='categorical_crossentropy',\n                  metrics=['accuracy'])\n\n    return model\n\np=getpretrainedmodel()\np.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d0fe4366c0458a266c3160c0ec75ef329638b27a"},"cell_type":"markdown","source":"## **Defining the DataGenerators for the Models**"},{"metadata":{"trusted":true,"_uuid":"0fc230d300bb4624a72d511787c15447efee681a"},"cell_type":"code","source":"def datagenerators(mode=\"pretrained\"):\n    \n    if mode==\"custom\":\n        train_datagen = ImageDataGenerator(\n            rescale=1. / 255,\n            shear_range=0.2,\n            zoom_range=0.2,\n            horizontal_flip=True,\n            validation_split=0.3\n            )\n    else:\n        train_datagen = ImageDataGenerator(\n            rescale=1. / 255,\n            shear_range=0.2,\n            zoom_range=0.2,\n            horizontal_flip=True,\n            validation_split=0.3,\n        preprocessing_function=preprocess_input)\n\n    train_generator = train_datagen.flow_from_directory(\n        train_data_dir,\n        target_size=(img_height, img_width),\n        batch_size=batch_size,\n        class_mode='categorical',\n        subset=\"training\")\n\n    validation_generator = train_datagen.flow_from_directory(\n        train_data_dir,\n        target_size=(img_height, img_width),\n        batch_size=batch_size,\n        class_mode='categorical',\n        subset=\"validation\")\n\n    return train_generator, validation_generator","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7efe07ac73a44ac44ce3f90d48adab9cbca62980"},"cell_type":"markdown","source":"## G**etting all images in form of tensors **"},{"metadata":{"trusted":true,"_uuid":"9c1d9a3adc0d70766954b102d5c8cb9b7c418e16"},"cell_type":"code","source":"def getTestImages(folder):\n    a = []\n    b = []\n    for f in listdir(folder):\n        temp = (join(folder, f))\n        print(temp)\n        b.append(f)\n        a.append(img_to_tensor(temp, target_size=(img_width, img_height)))\n    return (a, b)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b33d48e7ab5f35f19aa240354d986a1312bf4695"},"cell_type":"code","source":"(a,b)=getTestImages(test)\nprint(a)\nprint(b)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7e9785f63b71bc1fe51c1adf2d55ec21eea624c9"},"cell_type":"markdown","source":""},{"metadata":{"_uuid":"bfb9b731b0ee25d3fe2d66ea5604c66e51e0e813"},"cell_type":"markdown","source":"## **Using Average Based Ensembling of the two models we Defined above**"},{"metadata":{"trusted":true,"_uuid":"81fd424e93c399902be610bef167cb45e8762e75"},"cell_type":"code","source":"def ensemble_predictor(trained_ensemble, test_folder, method=\"vote\"):\n\n    test_tensors, test_images = getTestImages(test_folder)\n    # test_images = np.array(test_images)\n    # print(test_images.shape)\n\n    p1 = []\n    p3 = []\n    output = {}\n    if method == \"average\":\n        for i in range(len(test_tensors)):\n            t1 = trained_ensemble[0].predict(test_tensors[i])\n            t2 = trained_ensemble[1].predict(test_tensors[i])\n            tt = t2\n            output[test_images[i]] = np.argmax(tt, axis=1)\n\n    # for i in range(len(p1)):\n        # if(np.argmax(p1[i], axis=1) > np.argmax(p2[i], axis=1)):\n            # output[test_images[i]] = 1\n\n    return output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c75ec77e0a5a483752073708fd565094016bbd50"},"cell_type":"markdown","source":"## **Training the Ensemble and Predicting the test images**"},{"metadata":{"trusted":true,"_uuid":"176521abc6e4fecf849d8cb499d25649307940ba"},"cell_type":"code","source":"model1 = getCustommodel()\nmodel3 = getpretrainedmodel()\n\nensemble = []\nensemble.append(model1)\nensemble.append(model3)\n\ntrained_ensemble = []\nfor i in ensemble:\n    a, b = datagenerators()\n    i.fit_generator(\n        a,\n        samples_per_epoch=nb_train_samples,\n        epochs=7,\n        validation_data=b,\n        validation_steps=nb_validation_samples)\n\n    trained_ensemble.append(i)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"dd0903476cd523a3173362980627d385a79aaa80"},"cell_type":"code","source":"output = ensemble_predictor(ensemble, test, method=\"average\")\nprint(output)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"60a8759d632d97d492c5bf2584b0e92d28afc71f"},"cell_type":"code","source":"predictions={}\nfor i,j in output.items():\n    predictions[i]=j[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fb2a7d568fb3bb93d1b90549e4b86412c9b7ee18"},"cell_type":"code","source":"print(predictions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b8b1eb831cf0bc5884f6a37d3eb74b5511f24290"},"cell_type":"code","source":"df=pd.DataFrame()\ndf['filename']=predictions.keys()\ndf['label']= predictions.values()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"29866615100f3a563a2b831aadac52cc62471371"},"cell_type":"code","source":"print(df.head(3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"10a678b3e4f9efaa1abdd4e08509c5bf794cfd53"},"cell_type":"code","source":"df.T.to_csv(\"output.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"608f433f430c895e93b063b318d854a8b024089f"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}