{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport pandas as pd\nimport cv2\nimport numpy as np \nimport pandas as pd \nimport time\nimport matplotlib.pyplot as plt\nfrom skimage import measure\nimport matplotlib.patches as patches\nfrom sklearn.preprocessing import LabelEncoder, OneHotEncoder\n# from sklearn.utils import resample\n# from sklearn.model_selection import train_test_split\nimport numpy as np\nfrom sklearn.utils import resample\nfrom keras.preprocessing.image import ImageDataGenerator\n#imports\nfrom keras.models import Model\nfrom keras.layers import Dense, GlobalAveragePooling2D, Dropout, Flatten,Conv2D,GlobalMaxPooling2D\nfrom keras import optimizers\nfrom keras.preprocessing import image\nfrom keras.metrics import top_k_categorical_accuracy\nfrom keras.models import Sequential\nfrom keras.layers import Input, Dense, Activation, BatchNormalization, Flatten, Conv2D\nfrom keras.layers import AveragePooling2D, MaxPooling2D, Dropout, GlobalMaxPooling2D, GlobalAveragePooling2D, Concatenate\nfrom keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom keras.applications.resnet50 import ResNet50,preprocess_input\nfrom keras.applications.xception import Xception\nfrom keras.optimizers import Adam\n\nprint(os.listdir(\"../input\"))\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3dabb6329277ba0b8ee6cd693368a31ffecab0c1"},"cell_type":"code","source":"DATA=\"../input/humpback-whale-identification\"\nTRAIN_IMG=\"../input/humpback-whale-identification/train\"\nTEST_IMG=\"../input/humpback-whale-identification/test\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fafff923a8a8d0892bb3fb401d1b6832671bb54b"},"cell_type":"code","source":"test_df= pd.DataFrame({\"Image\":  os.listdir(TEST_IMG)})\nprint(\"test images:\"+ str(len(test_df)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fdd9468ae74dca12740901ddc50c05f24bcc546d"},"cell_type":"code","source":"train_lbl = pd.read_csv(os.path.join(DATA, 'train.csv'))\nprint(\"train images:\"+ str(len(train_lbl)))\nprint(\"total unique class:\"+ str(len(np.unique(train_lbl['Id']))))\ntrain_lbl.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ed412e6d5306e3bf331345ef531aee6681ec6293"},"cell_type":"markdown","source":"**Balance training set**"},{"metadata":{"trusted":true,"_uuid":"5ca12885666f7d1e932cb072a17ad3a7edbbe53f"},"cell_type":"code","source":"train_lbl['newwhale_lbl']=np.where(train_lbl['Id']=='new_whale',1,0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d8ac451c662bf7898a06119ca2bbbe8bba456e5f"},"cell_type":"code","source":"#take out whales with less than 2 examples\ndf=train_lbl.groupby(['Id']).size().reset_index(\n    name='train_examples')\ndf=df[df['train_examples']>=2]\n\nprint(\"number of classes with more than 2 examples:\"+ str(len(df)))\ntrain_lbl=train_lbl[train_lbl['Id'].isin(df['Id'])]\nprint(\"number of train instances :\"+ str(len(train_lbl)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"648780227d8fb1220b8e35445d872de3c1ffc7de"},"cell_type":"code","source":"#define accuracy metric\ndef top_5_accuracy(y_true, y_pred):\n    return top_k_categorical_accuracy(y_true, y_pred, k=5)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4d788f5a4ca3c0f4b85f45cfd6c2edfca0d5ae0f"},"cell_type":"markdown","source":"Train model without new whale"},{"metadata":{"trusted":true,"_uuid":"60cfe5e40f6dcbe72778182b68f07767b434e6e1"},"cell_type":"code","source":"train_no_new_whale=train_lbl[train_lbl['newwhale_lbl']!=1]\nprint(\"number of train instances :\"+ str(len(train_no_new_whale)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c8c986f6e1e20c1fdff1d32d8eba9f17889f6562"},"cell_type":"code","source":"image_size=100\nbatch_size=32\n\ndatagen=image.ImageDataGenerator(rescale=1./255,\n                                 validation_split = 0.2,\n#                                  preprocessing_function=preprocess_input,\n#                                  check augmentation options on training:\n                                 rotation_range=20,\n#                                  zoom_range=2,\n                                 shear_range=0.2,\n                                 horizontal_flip=True,\n#                                  rescale=1./255, \n                                 fill_mode='nearest')\n\n#training set\ntrain_generator=datagen.flow_from_dataframe(dataframe=train_no_new_whale, \n                                            directory=TRAIN_IMG, \n                                            x_col=\"Image\", y_col=\"Id\", \n                                            has_ext=True, seed = 42,\n                                            class_mode=\"categorical\", \n                                            shuffle=True,\n                                            target_size=(image_size,image_size),\n                                            batch_size=batch_size,\n                                            subset = \"training\")\n\nvalidation_generator = datagen.flow_from_dataframe(dataframe=train_no_new_whale,\n                                                   directory=TRAIN_IMG, \n                                                   x_col=\"Image\", y_col=\"Id\", \n                                                   has_ext=True, seed = 42,shuffle=True,\n                                                   class_mode=\"categorical\", \n                                                   target_size=(image_size,image_size), \n                                                   batch_size=1, subset = \"validation\")\n\ntest_datagen = image.ImageDataGenerator(rescale=1./255\n#                                         preprocessing_function=preprocess_input\n                                       )\ntest_generator = test_datagen.flow_from_dataframe(dataframe=test_df,\n                                                  directory=TEST_IMG, \n                                                  x_col=\"Image\",y_col=None,\n                                                  seed = 42, class_mode=None, \n                                                  target_size=(image_size,image_size), \n                                                  batch_size=1,shuffle = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2d48cec4a26c5f939618f1cd0deff556a84805bd"},"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ModelCheckpoint,ReduceLROnPlateau\nfrom keras.utils.vis_utils import plot_model\nfrom PIL import Image as pil_image\n\ndef cnn():\n    CLASSES = len(np.unique(train_no_new_whale['Id'])) \n    model = Sequential()\n    model.add(Conv2D(32, (3, 3), strides = (1, 1), input_shape = (image_size, image_size, 3)))\n    model.add(BatchNormalization(axis = 3))\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D((2, 2)))\n    model.add(Conv2D(64, (3, 3), strides = (1,1)))\n    model.add(Activation('relu'))\n    model.add(AveragePooling2D((3, 3)))\n    model.add(Flatten())\n    model.add(Dense(500, activation=\"relu\"))\n    model.add(Dropout(0.6))\n    model.add(Dense(CLASSES, activation='softmax'))\n    model.compile(loss='categorical_crossentropy', optimizer=\"adam\", metrics=['accuracy',top_5_accuracy])\n    # visualize\n    model.summary()\n    \n    return model\n\nmodel = cnn()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"39b5ef18d8d38e5805b3c6d6a37252f4088d0030"},"cell_type":"code","source":"    plot_model(model, to_file='model_plot.png', show_shapes=True, show_layer_names=True,expand_nested=True)\n    pil_image.open('model_plot.png')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"639cca703a4d0516ab7a1838434e5ee57b2d4705"},"cell_type":"code","source":"STEP_SIZE_TRAIN=train_generator.n//train_generator.batch_size\nSTEP_SIZE_VALID=validation_generator.n//validation_generator.batch_size\nepochs=100\n\ncheckpointer = ModelCheckpoint(filepath='weights_cnn_no_new_whale.hdf5', monitor='loss',\n                               verbose=1, save_best_only=True)\n# decayedlr= ReduceLROnPlateau(monitor='val_loss',patience=10,min_lr=1e-9,verbose=1,mode='min')\n\nmodel.save('cnn_no_new_whale.h5')\n\nhistory = model.fit_generator(generator=train_generator,\n                    steps_per_epoch=STEP_SIZE_TRAIN,\n                    validation_data=validation_generator,\n                    validation_steps=STEP_SIZE_VALID,\n                    epochs=epochs, callbacks = [checkpointer])\n\nmodel.save('cnn_no_new_whale.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"72dbd8432f9c5bb231725f0fad6b5c3f21401c71"},"cell_type":"code","source":"# model.evaluate_generator(generator=validation_generator)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d53cc1808de9a3348133555f5c57e16bfbc5becd"},"cell_type":"code","source":"plt.plot(history.history['top_5_accuracy'])\nplt.plot(history.history['val_top_5_accuracy'])\nplt.title('model top 5 accuracy')\nplt.ylabel('top 5 accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d705ef958f6ba061e672eead5cdf7e5baee2e9cb"},"cell_type":"code","source":"plt.plot(history.history['acc'])\nplt.plot(history.history['val_acc'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"02439fcd02dcc8422e100eb49bccf96bf5697591"},"cell_type":"code","source":"# # from keras.models import model_from_json, load_model\n# # model=load_model(\"../input/pretrained-model/cnn_no_new_whale.h5\",custom_objects={\"top_5_accuracy\": top_5_accuracy})\n# history = model.fit_generator(generator=train_generator,\n#                     steps_per_epoch=STEP_SIZE_TRAIN,\n#                     validation_data=validation_generator,\n#                     validation_steps=STEP_SIZE_VALID,\n#                     epochs=epochs, callbacks = [checkpointer])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8c09c2d0ceddd012ae4df250a575dc3c87d1b3a2"},"cell_type":"code","source":"# model.save('cnn_no_new_whale.h5')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"82cbb031397e9a336ecd442eb13c5a2f35cf8a6a"},"cell_type":"markdown","source":"# Submission"},{"metadata":{"trusted":true,"_uuid":"4877e8763ab48eedc412a8c50068605e4afe7f92"},"cell_type":"code","source":"#submission\nSTEP_SIZE_TEST=test_generator.n\ntest_generator.reset()\npred = model.predict_generator(test_generator,verbose = 1,steps=STEP_SIZE_TEST,workers=1)\npred_sorted = np.argsort(-pred, axis = 1)[:,:5]\npred_sorted_big = np.argsort(-pred, axis = 1)[:,:100]\ntop_pred=np.sort(-pred, axis = 1)[:,:1]\ntop_5_pred=np.sort(-pred, axis = 1)[:,:5]\n# pred_sorted","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c7e02899ca7abf2d9f99deec52525bfdc5421c79"},"cell_type":"code","source":"labels = (train_generator.class_indices)\nlabels = dict((v,k) for k,v in labels.items())\ntest_filenames=test_generator.filenames","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"dcc3156fbddec106d212de49c507872d2433373d"},"cell_type":"code","source":"from tqdm import tqdm\n#create empty list\npred_ids = list()\nfor i,row in enumerate(tqdm(pred_sorted)):\n    #create a temporary list to store the ids for a given image\n    temp_list = []\n    for j,predlabel in enumerate(row):\n        #for each index in pred_sorted, append the real Id in temp_list\n        temp_list.append(labels[predlabel])\n    pred_ids.append(temp_list)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0809a3ece8fcc5032c78a122897406e48dd96472"},"cell_type":"code","source":"### for pred big file\npred_ids_big = list()\nfor i,row in enumerate(tqdm(pred_sorted_big)):\n    #create a temporary list to store the ids for a given image\n    temp_list = []\n    for j,value in enumerate(row):\n        #for each index in pred_sorted, append the real Id in temp_list\n        temp_list.append(labels[value])\n    #append all 5 ids for a given image to pred_ids\n    #effectively creating a similar list to pred_sorted\n    #but with the real ids\n    pred_ids_big.append(temp_list)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"68194d99dc17caca2b5dface467de65902e78bbd"},"cell_type":"code","source":"final_preds = []\nfor i,top_5_ids in enumerate(pred_ids):\n    final_preds.append(' '.join(pred_ids[i]))\n    \nimport shutil\nshutil.rmtree('test_folder', ignore_errors=True)\n\nsubmission = pd.DataFrame({\"Image\": test_filenames, \"Id\": final_preds})\nsubmission.to_csv(\"submission.csv\", index = False) #disabled to not override current submission\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c87fd858eca3ad95abb48f488674bb8af8f1f228"},"cell_type":"code","source":"### for pred big file\nfinal_preds = []\n\nfor i,top_5_ids in enumerate(pred_ids_big):\n    final_preds.append(' '.join(pred_ids_big[i]))\n    \nimport shutil\nshutil.rmtree('test_folder', ignore_errors=True)\n\ntop_pred=-1*top_pred\ntop_5_pred=-1*top_5_pred\n\nsubmission_top100 = pd.DataFrame({\"Image\": test_filenames,\"top_score\":list(top_pred), \"Id\": final_preds})\nsubmission_top100.to_csv(\"submission_top100.csv\", index = False)\nsubmission_top100.head(50)\n\nsubmission_scores=  pd.DataFrame({\"Image\": test_filenames,\"1_score\":list(top_5_pred[:,0]),\"2_score\":list(top_5_pred[:,1]),\"3_score\":list(top_5_pred[:,2]),\"4_score\":list(top_5_pred[:,3]),\"5_score\":list(top_5_pred[:,4])})\nsubmission_scores.to_csv(\"submission_scores_top5.csv\", index = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4edcaa9ad5490193449ed51b87fab909d4ae3408"},"cell_type":"code","source":"submission_top100.head(50)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7a2d3a1b259ef963ecf2cc5c4a4fba4533813d4a"},"cell_type":"code","source":"# import the modules we'll need\nfrom 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 = \"data.csv\"):  \n    csv = df.to_csv(index = False)\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)\n\n# create a random sample dataframe\n\n\n# create a link to download the dataframe\ncreate_download_link(submission)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"22241835a670ec6b40fed26a6441fc6d0a874875"},"cell_type":"code","source":"create_download_link(submission_scores)","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}