{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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\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 read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## IMPORTS:"},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\ntf.test.gpu_device_name()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n%matplotlib inline \nimport cv2\nimport os\nfrom tqdm import tqdm","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Checking Out Inception"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.inception_v3 import InceptionV3\nmodel = InceptionV3()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Getting Tensorflow Read"},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import load_img\nfrom tensorflow.keras.preprocessing.image import img_to_array\nfrom tensorflow.keras.applications.inception_v3 import preprocess_input\nfrom tensorflow.keras.applications.inception_v3 import decode_predictions","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Loading Images:"},{"metadata":{"trusted":true},"cell_type":"code","source":"N = 224","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"chair = []\n\nfor filepath in tqdm(sorted(os.listdir('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/train/chair/'))):\n    src = cv2.imread('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/train/chair/{0}'.format(filepath),1)\n    src = cv2.resize(src, (N, N))\n    chair.append(src)\n\nchair = np.array(chair)\n\nbed = []\n\nfor filepath in tqdm(sorted(os.listdir('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/train/bed/'))):\n    src = cv2.imread('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/train/table/{0}'.format(filepath),1)\n    src = cv2.resize(src, (N, N))\n    bed.append(src)\n\nbed = np.array(bed)\n\ntable = []\n\nfor filepath in tqdm(sorted(os.listdir('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/train/table/'))):\n    src = cv2.imread('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/train/table/{0}'.format(filepath),1)\n    src = cv2.resize(src, (N, N))\n    table.append(src)\n\ntable = np.array(table)\n\nsofa = []\n\nfor filepath in tqdm(sorted(os.listdir('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/train/sofa/'))):\n    src = cv2.imread('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/train/sofa/{0}'.format(filepath),1)\n    src = cv2.resize(src, (N, N))\n    sofa.append(src)\n\nsofa = np.array(sofa)\n\nswivle_chair = []\n\nfor filepath in tqdm(sorted(os.listdir('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/train/swivelchair/'))):\n    src = cv2.imread('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/train/swivelchair/{0}'.format(filepath),1)\n    src = cv2.resize(src, (N, N))\n    swivle_chair.append(src)\n\nswivle_chair = np.array(swivle_chair)\n\n\nprint(chair.shape, table.shape, bed.shape, swivle_chair.shape, sofa.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Trying out Inception V3"},{"metadata":{"trusted":true},"cell_type":"code","source":"image = chair[0]\n\nplt.imshow(image)\n\nimage = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))\n\nimage = preprocess_input(image)\n\nmodel = InceptionV3()\n\nyhat = model.predict(image)\n\nlabel = decode_predictions(yhat)\n\nlabel = label[0][0]\nprint('%s (%.5f%%)' % (label[1], label[2]*100))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Let's take a look at the yhat raw"},{"metadata":{"trusted":true},"cell_type":"code","source":"print(yhat.shape, '\\n', yhat)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Well the model already gives results let's take a look at more interesting facts about the challenge and Inception:"},{"metadata":{"trusted":true},"cell_type":"code","source":"def label_image(images):\n\n    images = preprocess_input(images)\n\n    model = InceptionV3()\n\n    yhat = model.predict(images, verbose=1)\n    \n    return yhat\n    \nyhat_chair = label_image(chair)\nyhat_bed = label_image(bed)\nyhat_sofa = label_image(sofa)\nyhat_swivel_chair = label_image(swivle_chair)\nyhat_table = label_image(table)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Checking Validity of Inception using RF:"},{"metadata":{"trusted":true},"cell_type":"code","source":"x_inception = np.array([i for i in yhat_chair] + [i for i in yhat_swivel_chair] + [i for i in yhat_table] + [i for i in yhat_bed] + [i for i in yhat_sofa])\ny_inception = np.array([1 for _ in range(yhat_chair.shape[0])] + [3 for _ in range(yhat_swivel_chair.shape[0])] + [4 for _ in range(yhat_table.shape[0])] + [0 for _ in range(yhat_bed.shape[0])] + [2 for _ in range(yhat_sofa.shape[0])])\n\nnp.random.seed(0)\nindexes = np.arange(x_inception.shape[0])\nnp.random.shuffle(indexes)\n\nx_inception = x_inception[indexes]\ny_inception = y_inception[indexes]\n\nprint(x_inception.shape)\nprint(y_inception.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.ensemble import RandomForestClassifier\nclf = RandomForestClassifier(random_state=0, n_estimators=500) #for reproducibility\nclf.fit(x_inception[:int(0.85*x_inception.shape[0])], y_inception[:int(0.85*x_inception.shape[0])])\ny_rf = clf.predict(x_inception)\nprint('Validation',clf.score(x_inception[int(0.85*x_inception.shape[0]):], y_inception[int(0.85*x_inception.shape[0]):]))\nprint('Training',clf.score(x_inception[:int(0.85*x_inception.shape[0])], y_inception[:int(0.85*x_inception.shape[0])]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Looking at who went wrong?"},{"metadata":{"trusted":true},"cell_type":"code","source":"groups = {0:[], 1:[], 2:[], 3:[], 4:[]}\nfor i,j in zip(y_inception, y_rf):\n    groups[i].append(j)\n    \np_error = {0:[], 1:[], 2:[], 3:[], 4:[]}\nfor key, item in groups.items():\n    for i in range(5):\n        p_error[key].append(item.count(i))\n    total = sum(p_error[key])\n    p_error[key] = [round(i/total, 5) for i in p_error[key]]\n\n_ = [print(key,':',item) for key, item in p_error.items()]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Kind of interesting that, swivel chair and chair can be classified. But table and bed cannot"},{"metadata":{"trusted":true},"cell_type":"code","source":"import networkx as nx \n\ndef error_graph(p_error):\n    \n    G = nx.DiGraph() \n    for i in range(5):\n        G.add_node(i)\n    \n    for key, item in p_error.items():\n        for i,x in enumerate(item):\n            x = round(x, 3)\n            if i!=key and x>0.01:\n                G.add_edge(key, i, weight=x)\n    \n    plt.figure(figsize =(4, 4)) \n    nx.draw_networkx(G, with_label = True, node_color ='green')\n    \nerror_graph(p_error)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Building The Training Set:"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = np.array([i for i in chair[:int(0.9*chair.shape[0])]] + [i for i in table[:int(0.9*table.shape[0])]] + [i for i in bed[:int(0.9*bed.shape[0])]] + [i for i in swivle_chair[:int(0.9*swivle_chair.shape[0])]] + [i for i in sofa[:int(0.9*sofa.shape[0])]] + [i for i in chair[int(0.9*chair.shape[0]):]] + [i for i in table[int(0.9*table.shape[0]):]] + [i for i in bed[int(0.9*bed.shape[0]):]] + [i for i in swivle_chair[int(0.9*swivle_chair.shape[0]):]] + [i for i in sofa[int(0.9*sofa.shape[0]):]])\ny_sparse = np.array([1 for _ in range(int(0.9*chair.shape[0]))] + [4 for _ in range(int(0.9*table.shape[0]))] + [0 for _ in range(int(0.9*bed.shape[0]))] + [3 for _ in range(int(0.9*swivle_chair.shape[0]))] + [2 for _ in range(int(0.9*sofa.shape[0]))] + [1 for _ in range(chair.shape[0]-int(0.9*chair.shape[0]))] + [4 for _ in range(table.shape[0]-int(0.9*table.shape[0]))] + [0 for _ in range(bed.shape[0]-int(0.9*bed.shape[0]))] + [3 for _ in range(swivle_chair.shape[0] - int(0.9*swivle_chair.shape[0]))] + [2 for _ in range(sofa.shape[0] - int(0.9*sofa.shape[0]))])\ny_encoded = []\n\nfor i in y_sparse:\n    a = [0 for _ in range(5)]\n    a[i] = 1\n    y_encoded.append(a)\ny_encoded = np.array(y_encoded)\n\nprint(x.shape, y_encoded.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Building The Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Dense, BatchNormalization\nfrom tensorflow.keras.layers import Flatten, GlobalAveragePooling2D, Concatenate, Dropout\nimport tensorflow as tf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = InceptionV3(include_top=False, input_shape=(N, N, 3))\nmodel.trainable = True\n\ngap1 = GlobalAveragePooling2D()(model.layers[-1].output)\nflat1 = Flatten()(gap1)\nbn = BatchNormalization()(flat1)\nclass1 = Dense(1024, activation='relu')(bn)\nclass2 = Dense(256, activation='relu')(class1)\nclass3 = Dense(32, activation='relu')(class2)\noutput = Dense(5, activation='softmax')(class3)\n\nmodel = Model(inputs=model.inputs, outputs=output)\n\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Training it"},{"metadata":{"trusted":true},"cell_type":"code","source":"reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(\n    monitor='val_loss', factor=0.75, patience=4, verbose=1, mode='auto',\n    min_delta=0.0001, cooldown=0, min_lr=5*1e-5,\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"early_stop = tf.keras.callbacks.EarlyStopping(\n    monitor='val_acc', min_delta=0, patience=15, verbose=0, mode='auto',\n    baseline=None, restore_best_weights=True\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.fit(x[:int(0.9*x.shape[0])], y_encoded[:int(0.9*x.shape[0])], epochs=25, shuffle=True, callbacks=[reduce_lr, early_stop], validation_data=(x[x.shape[0]-int(0.9*x.shape[0]):], y_encoded[x.shape[0]-int(0.9*x.shape[0]):]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Preparing Submission:"},{"metadata":{"trusted":true},"cell_type":"code","source":"test = []\nfiles = sorted(os.listdir('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/test/'))\nfor filepath in tqdm(files):\n    src = cv2.imread('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/test/{0}'.format(filepath),1)\n    src = cv2.resize(src, (N, N))\n    test.append(src)\n\ntest = np.array(test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred = model.predict(test, verbose=1)\ny_pred = [np.argmax(i) for i in y_pred]\nsubmission = pd.DataFrame({'image': files, 'target':y_pred})\nsubmission.to_csv('submission_basic.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Skipping connections:"},{"metadata":{"trusted":true},"cell_type":"code","source":"model1 = InceptionV3(include_top=False, input_shape=(N, N, 3))\nmodel1.trainable = True\n\ngap1 = GlobalAveragePooling2D()(model1.layers[-1].output)\nflat1 = Flatten()(gap1)\nflat1 = BatchNormalization()(flat1)\n\nout1 = Dense(1024, activation='relu')(flat1)\n\ninput2 = tf.keras.layers.Input([N, N, 3])\nx = tf.keras.applications.inception_v3.preprocess_input(input2)\nmodel2 = tf.keras.applications.InceptionV3()\nout2 = model2(x)\nout2 = BatchNormalization()(out2)\n\nmergedOut = Concatenate()([out1,out2])\nclass1 = Dense(1228, activation='relu')(mergedOut)\nclass1 = Dense(1024, activation='relu')(class1)\nclass1 = Dense(516, activation='relu')(class1)\nclass2 = Dense(256, activation='relu')(class1)\nclass3 = Dense(32, activation='relu')(class2)\noutput = Dense(5, activation='softmax')(class3)\n\n\nmodel = Model(inputs=[model1.inputs, input2], outputs=[output])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = np.array([i for i in chair[:int(0.9*chair.shape[0])]] + [i for i in table[:int(0.9*table.shape[0])]] + [i for i in bed[:int(0.9*bed.shape[0])]] + [i for i in swivle_chair[:int(0.9*swivle_chair.shape[0])]] + [i for i in sofa[:int(0.9*sofa.shape[0])]] + [i for i in chair[int(0.9*chair.shape[0]):]] + [i for i in table[int(0.9*table.shape[0]):]] + [i for i in bed[int(0.9*bed.shape[0]):]] + [i for i in swivle_chair[int(0.9*swivle_chair.shape[0]):]] + [i for i in sofa[int(0.9*sofa.shape[0]):]])\ny_sparse = np.array([1 for _ in range(int(0.9*chair.shape[0]))] + [4 for _ in range(int(0.9*table.shape[0]))] + [0 for _ in range(int(0.9*bed.shape[0]))] + [3 for _ in range(int(0.9*swivle_chair.shape[0]))] + [2 for _ in range(int(0.9*sofa.shape[0]))] + [1 for _ in range(chair.shape[0]-int(0.9*chair.shape[0]))] + [4 for _ in range(table.shape[0]-int(0.9*table.shape[0]))] + [0 for _ in range(bed.shape[0]-int(0.9*bed.shape[0]))] + [3 for _ in range(swivle_chair.shape[0] - int(0.9*swivle_chair.shape[0]))] + [2 for _ in range(sofa.shape[0] - int(0.9*sofa.shape[0]))])\ny_encoded = []\n\nfor i in y_sparse:\n    a = [0 for _ in range(5)]\n    a[i] = 1\n    y_encoded.append(a)\ny_encoded = np.array(y_encoded)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(x.shape, y_encoded.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.0025), loss='categorical_crossentropy', metrics=['acc'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.fit([x, x], y_encoded, epochs=5, validation_split=0.1, shuffle=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## The model is slow, but it does not require data augmentation, which is an area I did not want to use. On the other hand it was my first chance to implement any type of skipping networks \n(https://link.springer.com/chapter/10.1007%2F978-3-658-14577-4_8)"},{"metadata":{"trusted":true},"cell_type":"code","source":"test = []\nfiles = sorted(os.listdir('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/test/'))\nfor filepath in tqdm(files):\n    src = cv2.imread('/kaggle/input/day-3-kaggle-competition/data_comp/data_comp/test/{0}'.format(filepath),1)\n    src = cv2.resize(src, (N, N))\n    test.append(src)\n\ntest = np.array(test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred = model.predict([test, test], verbose=1)\ny_peed = [np.argmax(i) for i in y_pred]\nsubmission = pd.DataFrame({'image': files, 'target':y_peed})\nsubmission.to_csv('submission_skipped.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Used the main model as well, since, the skipping connection model had only run for 2 epochs and wasn't promising. It showed signs of underfitting. So, the following was done to correct anything possible. However, it gives better results after running for more epochs"},{"metadata":{"trusted":true},"cell_type":"code","source":"for index in range(10):\n    \n    np.random.shuffle(chair)\n    np.random.shuffle(table)\n    np.random.shuffle(bed)\n    np.random.shuffle(sofa)\n    np.random.shuffle(swivle_chair)\n\n    x = np.array([i for i in chair[:int(0.9*chair.shape[0])]] + [i for i in table[:int(0.9*table.shape[0])]] + [i for i in bed[:int(0.9*bed.shape[0])]] + [i for i in swivle_chair[:int(0.9*swivle_chair.shape[0])]] + [i for i in sofa[:int(0.9*sofa.shape[0])]] + [i for i in chair[int(0.9*chair.shape[0]):]] + [i for i in table[int(0.9*table.shape[0]):]] + [i for i in bed[int(0.9*bed.shape[0]):]] + [i for i in swivle_chair[int(0.9*swivle_chair.shape[0]):]] + [i for i in sofa[int(0.9*sofa.shape[0]):]])\n    y_sparse = np.array([1 for _ in range(int(0.9*chair.shape[0]))] + [4 for _ in range(int(0.9*table.shape[0]))] + [0 for _ in range(int(0.9*bed.shape[0]))] + [3 for _ in range(int(0.9*swivle_chair.shape[0]))] + [2 for _ in range(int(0.9*sofa.shape[0]))] + [1 for _ in range(chair.shape[0]-int(0.9*chair.shape[0]))] + [4 for _ in range(table.shape[0]-int(0.9*table.shape[0]))] + [0 for _ in range(bed.shape[0]-int(0.9*bed.shape[0]))] + [3 for _ in range(swivle_chair.shape[0] - int(0.9*swivle_chair.shape[0]))] + [2 for _ in range(sofa.shape[0] - int(0.9*sofa.shape[0]))])\n    y_encoded = []\n\n    for i in y_sparse:\n        a = [0 for _ in range(5)]\n        a[i] = 1\n        y_encoded.append(a)\n    y_encoded = np.array(y_encoded)\n    \n    model = InceptionV3(include_top=False, input_shape=(N, N, 3))\n    model.trainable = True\n\n    gap1 = GlobalAveragePooling2D()(model.layers[-1].output)\n    flat1 = Flatten()(gap1)\n    bn = BatchNormalization()(flat1)\n    class1 = Dense(1024, activation='relu')(bn)\n    class2 = Dense(256, activation='relu')(class1)\n    class3 = Dense(32, activation='relu')(class2)\n    output = Dense(5, activation='softmax')(class3)\n\n    model = Model(inputs=model.inputs, outputs=output)\n    \n    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])\n    \n    model.fit(x[:int(0.9*x.shape[0])], y_encoded[:int(0.9*x.shape[0])], epochs=20, shuffle=True, callbacks=[reduce_lr, early_stop], validation_data=(x[x.shape[0]-int(0.9*x.shape[0]):], y_encoded[x.shape[0]-int(0.9*x.shape[0]):]))\n    \n    y_pred = model.predict(test, verbose=1)\n    y_pred = [np.argmax(i) for i in y_pred]\n    submission = pd.DataFrame({'image': files, 'target':y_pred})\n    submission.to_csv('submission_basic_'+str(index)+'.csv', index=False)\n    \n    del model    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## The above code is actually repeated 100 times totally, but the output would be too large and the results are consistent so, I did it only 10 times here"},{"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}