{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt\nfrom keras.preprocessing.image import load_img,img_to_array,array_to_img\nimport keras\nfrom keras.applications.xception import Xception\nfrom keras import layers\nfrom keras.models import Model\nfrom keras.optimizers import Adam\nfrom sklearn.model_selection import train_test_split\nfrom keras.callbacks import ModelCheckpoint\nimport scipy\nfrom tqdm import tqdm_notebook","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_curve(history):\n    fig,axs = plt.subplots(1,2,figsize=(15,5))\n    axs[0].plot(history.history['accuracy'])\n    axs[0].plot(history.history['val_accuracy'])\n    axs[0].set_title('model accuracy')\n    axs[0].set_ylabel('accuracy')\n    axs[0].set_xlabel('epoch')\n    axs[0].legend(['train', 'test'], loc='upper left')\n    # summarize history for loss\n    axs[1].plot(history.history['loss'])\n    axs[1].plot(history.history['val_loss'])\n    axs[1].set_title('model loss')\n    axs[1].set_ylabel('loss')\n    axs[1].set_xlabel('epoch')\n    axs[1].legend(['train', 'test'], loc='upper left')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/understanding_cloud_organization/train.csv')\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['Image'] = train_df['Image_Label'].apply(lambda x:x.split('_')[0])\ntrain_df['label'] = train_df['Image_Label'].apply(lambda x:x.split('_')[1])\ntrain = pd.DataFrame({'Image':train_df['Image'][::4]})\ntrain['e1'] = train_df['EncodedPixels'][::4].values\ntrain['e2'] = train_df['EncodedPixels'][1::4].values\ntrain['e3'] = train_df['EncodedPixels'][2::4].values\ntrain['e4'] = train_df['EncodedPixels'][3::4].values\n\ntrain.set_index('Image',inplace=True,drop=True)\n\ntrain.fillna('',inplace=True)\n\ncategoty = ['c1','c2','c3','c4']\ntrain[categoty] = (train[['e1','e2','e3','e4']]!='').astype('int8')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### SOME HELPER FUNCTION"},{"metadata":{"trusted":true},"cell_type":"code","source":"def rle2maskX(mask_rle, shape=(2100,1400), shrink=1):\n    # Converts rle to mask size shape then downsamples by shrink\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n    starts -= 1\n    ends = starts + lengths\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape).T[::shrink,::shrink]\ndef mask2rle(img, shape=(525,350)):    \n    pixels= img.T.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)\n\nclass DataGenerator(keras.utils.Sequence):\n    'Generates data for Keras'\n    def __init__(self, list_IDs, batch_size=8, shuffle=False, width=512, height=352, scale=1/128., sub=1., mode='train',\n                 path='../input/understanding_cloud_organization/train_images/', flips=False):\n        'Initialization'\n        self.list_IDs = list_IDs\n        self.shuffle = shuffle\n        self.batch_size = batch_size\n        self.path = path\n        self.scale = scale\n        self.sub = sub\n        self.path = path\n        self.width = width\n        self.height = height\n        self.mode = mode\n        self.flips = flips\n        self.on_epoch_end()\n        \n    def __len__(self):\n        'Denotes the number of batches per epoch'\n        ct = int(np.floor( len(self.list_IDs) / self.batch_size))\n        if len(self.list_IDs)>ct*self.batch_size: ct += 1\n        return int(ct)\n\n    def __getitem__(self, index):\n        'Generate one batch of data'\n        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n        X, y = self.__data_generation(indexes)\n        if (self.mode=='train')|(self.mode=='validate'): return X, y\n        else: return X\n\n    def on_epoch_end(self):\n        'Updates indexes after each epoch'\n        self.indexes = np.arange(int( len(self.list_IDs) ))\n        if self.shuffle: np.random.shuffle(self.indexes)\n\n    def __data_generation(self, indexes):\n        'Generates data containing batch_size samples' \n        # Initialization\n        lnn = len(indexes)\n        X = np.empty((lnn,self.height,self.width,3),dtype=np.float32)\n        y = np.zeros((lnn,4),dtype=np.int8)\n        \n        # Generate data\n        for k in range(lnn):\n            img = cv2.imread(self.path + self.list_IDs[indexes[k]])\n            img = cv2.resize(img,(self.width,self.height),interpolation = cv2.INTER_AREA)\n            # AUGMENTATION FLIPS\n            hflip = False; vflip = False\n            if (self.flips):\n                if np.random.uniform(0,1)>0.5: hflip=True\n                if np.random.uniform(0,1)>0.5: vflip=True\n            if vflip: img = cv2.flip(img,0) # vertical\n            if hflip: img = cv2.flip(img,1) # horizontal\n            # NORMALIZE IMAGES\n            X[k,] = img*self.scale - self.sub      \n            # LABELS\n            if (self.mode=='train')|(self.mode=='validate'):\n                y[k,] = train.loc[self.list_IDs[indexes[k]],['c1','c2','c3','c4']].values\n        return X, y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"id_train,id_val = train_test_split(train.index,random_state=21,test_size=0.2)\ntrain_gen = DataGenerator(id_train,shuffle=True,flips=True)\nval_gen = DataGenerator(id_val,mode='validate')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plotImages(images_arr):\n    fig, axes = plt.subplots(1, 5, figsize=(20,20))\n    axes = axes.flatten()\n    for img, ax in zip( images_arr, axes):\n        ax.imshow(img)\n    plt.tight_layout()\n    plt.show()\naugmented_images = [train_gen[0][0][0] for i in range(5)]\nplotImages(augmented_images)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''xception_model = Xception(weights='imagenet',include_top=False,input_shape=(None,None,3))\nfor layer in xception_model.layers:\n    if not isinstance(layer,layers.BatchNormalization):\n        layer.trainable = False\nx = xception_model.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(4,activation='sigmoid')(x)\n\nmodel = Model(inputs=xception_model.input,outputs=x)\n\nmodel.compile(optimizer=Adam(learning_rate=0.001),loss='binary_crossentropy',metrics=['accuracy'])\nmodel.summary()'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''checkpoint = ModelCheckpoint('best_xception_model.h5', monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')\ncallbacks_list = [checkpoint]'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''history1 = model.fit_generator(train_gen,epochs=5,verbose=1,validation_data=val_gen,callbacks=callbacks_list)'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''plot_curve(history1)'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.models import load_model\nmodel = load_model('../input/xception-model/best_xception_model.h5')\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train1 = train.loc[train.index.isin(id_val)].copy()\ntest_local_gen = DataGenerator(train1.index.values, mode='predict')\npred= model.predict_generator(test_local_gen, verbose=2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val_gen = DataGenerator(id_val,mode='validate')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv('../input/understanding_cloud_organization/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.head()\ntest_df['Image'] = test_df['Image_Label'].apply(lambda x:x.split('_')[0])\ntest_df['label'] = test_df['Image_Label'].apply(lambda x:x.split('_')[1])\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = pd.DataFrame({'Image':test_df['Image'][::4]})\ntest.set_index('Image',inplace=True,drop=True)\ntest.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_layer_weights = model.layers[-1].get_weights()[0]\ncam_model = Model(inputs=model.input, \n        outputs=(model.layers[-3].output, model.layers[-1].output))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cam_model.output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(1,5): test['p'+str(i)] = ''\nfor i in range(1,5): test['pp'+str(i)] = 0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PATH='../input/understanding_cloud_organization/test_images/'\nfor i,f in tqdm_notebook(enumerate(test.index.values),total=len(test)):\n    img = cv2.resize( cv2.imread(PATH+f), (512, 352))\n    x = np.expand_dims(img, axis=0)/128. -1.\n    last_conv_output, pred_vec = cam_model.predict(x) \n    last_conv_output = np.squeeze(last_conv_output)\n    \n    for pred in [0,1,2,3]:\n        # CREATE FOUR MASKS FROM ACTIVATION MAPS\n        layer_weights = all_layer_weights[:, pred]  \n        final_output = np.dot(last_conv_output.reshape((16*11, 2048)), layer_weights).reshape(11,16) \n        final_output = scipy.ndimage.zoom(final_output, (32, 32), order=1)\n        mx = np.round( np.max(final_output),1 )\n        mn = np.round( np.min(final_output),1 )\n        final_output = (final_output-mn)/(mx-mn)\n        final_output = cv2.resize(final_output,(525,350))\n        test.loc[f,'p'+str(pred+1)] = mask2rle( (final_output>0.3).astype(int) )\n        test.loc[f,'pp'+str(pred+1)] = pred_vec[0,pred]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df  = pd.DataFrame(columns=['Image_Label','EncodedPixels'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"im=[]\npi=[]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for id_,row in enumerate(test.itertuples()):\n        #-----------------\n        label = 'Fish'\n        im.append(row.Index+'_'+label)\n        if row.pp1>0.75:\n            pi.append(row.p1)\n        else:\n            pi.append(np.nan)\n        #-----------------\n        label = 'Flower'\n        im.append(row.Index+'_'+label)\n        if row.pp2>0.75:\n            pi.append(row.p2)\n        else:\n            pi.append(np.nan)\n        #-----------------\n        label = 'Gravel'\n        im.append(row.Index+'_'+label)\n        if row.pp3>0.75:\n            pi.append(row.p3)\n        else:\n            pi.append(np.nan)\n        #-----------------\n        label = 'Sugar'\n        im.append(row.Index+'_'+label)\n        if row.pp4>0.75:\n            pi.append(row.p4)\n        else:\n            pi.append(np.nan)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['Image_Label'] = im\ndf['EncodedPixels'] = pi","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import HTML\nimport pandas as pd\nimport numpy as np\nimport base64\n\n# function that takes in a dataframe and creates a text link to  \n# download it (will only work for files < 2MB or so)\ndef create_download_link(df, title = \"Download CSV file\", filename = \"submit.csv\"):  \n    csv = df.to_csv(index=None)\n    b64 = base64.b64encode(csv.encode())\n    payload = b64.decode()\n    html = '<a download=\"{filename}\" href=\"data:text/csv;base64,{payload}\" target=\"_blank\">{title}</a>'\n    html = html.format(payload=payload,title=title,filename=filename)\n    return HTML(html)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"create_download_link(df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.to_csv(r'submit.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import FileLink\nFileLink(r'submit.csv')","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":1}