{"cells":[{"metadata":{"trusted":true,"collapsed":true,"_uuid":"760bca6a11d7e6da6811cc6198e26bb3f4aea626"},"cell_type":"code","source":"# This is based on Fujisan's kernel on Invasive Species Monitoring","execution_count":null,"outputs":[]},{"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 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\"))\nimport glob\nfrom glob import glob\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true,"collapsed":true},"cell_type":"code","source":"train_path = '../input/train'\npath_name = train_path + '/**/*.jpg'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8def37969a203fcb8698760bddc69663c5aea1a6","collapsed":true},"cell_type":"code","source":"train_image_paths = glob(path_name, recursive=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"023d54bc4deaff195400e1762cddf9c976c44621"},"cell_type":"code","source":"train_image_paths[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"db49fe8ad486cf0db848172328bd8888150e20d8","collapsed":true},"cell_type":"code","source":"train_categories = list(map(os.path.basename,train_image_paths))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d7baa552567cf6027baa3e72cff10f0200a9178d"},"cell_type":"code","source":"train_categories[:3]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"17d857c7fb888f7b73d3092d7627322c22e25421","collapsed":true},"cell_type":"code","source":"labels =[]\nfor category in train_categories:\n    labels.append(category[:3])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d51fa97141586627f5e66d31e529f29a220f9abb"},"cell_type":"code","source":"labels[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1d07b05904f3c068fcf4935b5fe2a66b07476b0a"},"cell_type":"code","source":"len(labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6a30958c3c81795c9848636a02b869441c636537"},"cell_type":"code","source":"len(train_image_paths)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7a9e477c71d90eb8bf292760345cfbfba90df274"},"cell_type":"code","source":"num_classes = len(np.unique(labels))\nnum_classes","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"da6b3356f9c159dc344904e0e5a85558dbef86da"},"cell_type":"markdown","source":"# Labels Data Preparation"},{"metadata":{"_uuid":"4d871df8f40700875da4ce4b4e3a17a1a48a4bae"},"cell_type":"markdown","source":"## Encoding labels"},{"metadata":{"trusted":true,"_uuid":"b417f70b0dd09fb9422891414282ebe0d297b116","collapsed":true},"cell_type":"code","source":"#Encode labels with value between 0 and n_classes-1.\nfrom sklearn.preprocessing import LabelEncoder\nencoder = LabelEncoder()\nloadedLabels = np.asarray(labels)\nencoder.fit(loadedLabels)\nencoded_loadedLabels = encoder.transform(loadedLabels)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ab9ac9caf8f409eaa825985ceb892aa5ef17b4aa"},"cell_type":"markdown","source":"## Convert to One Hot Encoding Labels"},{"metadata":{"trusted":true,"_uuid":"f03141a399fbdba17f082c5caf56313c4cbf1fa8"},"cell_type":"code","source":"# Encode labels to hot vectors (ex : 2 -> [0,0,1,0,0,0,0,0,0,0])\nfrom keras.utils.np_utils import to_categorical\nlabels_Hot = to_categorical(encoded_loadedLabels, num_classes = num_classes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c57aece4da2baa34b98e64231bca53aa44f9a751"},"cell_type":"code","source":"labels_Hot[:3]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9f41b6d71c7932190d3c1e08ea9654bd8e4bda08"},"cell_type":"code","source":"labels[:3]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7e651181494e468066ce8760746ff6dfd75bf3ba"},"cell_type":"markdown","source":"# Create the Dataframe for Datagenerators"},{"metadata":{"trusted":true,"_uuid":"af03ad93e116a4554d4e3e5e8f11f132b644cc26","collapsed":true},"cell_type":"code","source":"df= pd.DataFrame()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"da9f3fc280f3d9abee5edd6e70350d01c1080a26"},"cell_type":"code","source":"df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1e2e7dfd2909fcaa26756e0cb12d44d438eac15b","collapsed":true},"cell_type":"code","source":"df['path']=train_image_paths","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"304f14ae7f4c69fc92a03b6bb3bdc0a8bcd62631"},"cell_type":"code","source":"df['path'].head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"97537b312352dfd254a36e2c8acf234c9fca3447","collapsed":true},"cell_type":"code","source":"df['labels'] = list(labels_Hot)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"85a3cc29a71ca7204c75611ffabc018e62403b6f"},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"26aa26b3e09165a4195fb75326219fd54cf58562"},"cell_type":"markdown","source":"# Create Data Generators"},{"metadata":{"trusted":true,"_uuid":"397fb3c708834ec01b259aa7c9816cc8303a2853","collapsed":true},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\nIMG_SIZE = (128, 128)\ncore_idg = ImageDataGenerator()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"863207aa9f1d037a2a84a3b6be2f7d2a32b6f082","collapsed":true},"cell_type":"code","source":"def flow_from_dataframe(img_data_gen, in_df, path_col, y_col, **dflow_args):\n    base_dir = os.path.dirname(in_df[path_col].values[0])\n    print('## Ignore next message from keras, values are replaced anyways')\n    df_gen = img_data_gen.flow_from_directory(base_dir, \n                                     class_mode = 'sparse',\n                                    **dflow_args)\n    df_gen.filenames = in_df[path_col].values\n    df_gen.classes = np.stack(in_df[y_col].values)\n    df_gen.samples = in_df.shape[0]\n    df_gen.n = in_df.shape[0]\n    df_gen._set_index_array()\n    df_gen.directory = '' # since we have the full path\n    print('Reinserting dataframe: {} images'.format(in_df.shape[0]))\n    return df_gen","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e156bb89a204d959f113d7b548abf90b3b9251e4","collapsed":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_df, valid_df = train_test_split(df, \n                                   test_size = 0.25, \n                                   random_state = 2018)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ffba0db2c9d92cbc4ba47ed35158cc29d303ab0e"},"cell_type":"code","source":"len(train_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"605ec9c2cd3aa48a9dc0a90064f4324e57aea97e"},"cell_type":"code","source":"len(valid_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e4768e576dbdb9e2700c4dfe537760a99e9f8b84"},"cell_type":"code","source":"train_gen = flow_from_dataframe(core_idg, train_df, \n                             path_col = 'path',\n                            y_col = 'labels', \n                            target_size = IMG_SIZE,\n                            batch_size = 64)\n\nvalid_gen = flow_from_dataframe(core_idg, valid_df, \n                             path_col = 'path',\n                            y_col = 'labels', \n                            target_size = IMG_SIZE,\n                            batch_size = 64) # we can use much larger batches for evaluation\n# used a fixed dataset for evaluating the algorithm\ntest_X, test_Y = next(flow_from_dataframe(core_idg, \n                               valid_df, \n                             path_col = 'path',\n                            y_col = 'labels', \n                            target_size = IMG_SIZE,\n                            batch_size = 64)) # one big batch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"45fff71b8728dc988bc2193fc245f41148604806","collapsed":true},"cell_type":"code","source":"t_x, t_y = next(train_gen)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d55abb6d30f9ce02772e815140e7866f4bf22136"},"cell_type":"code","source":"t_x.shape[1:]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"79b876e4c86a064bbcbb627ee88c29d535335f96"},"cell_type":"markdown","source":"# Vgg16"},{"metadata":{"trusted":true,"_uuid":"c4b21dcb79e8ab392c47ab284be91c1edc5cfe77","collapsed":true},"cell_type":"code","source":"from keras.applications import VGG16\nfrom keras.applications.vgg16 import preprocess_input\n\nimport keras\nfrom keras import backend as K\nfrom keras.callbacks import Callback, EarlyStopping, ReduceLROnPlateau, ModelCheckpoint\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.utils.np_utils import to_categorical\nfrom keras.models import Model,Sequential, model_from_json\nfrom keras.optimizers import SGD, RMSprop, Adam, Adagrad, Adadelta\nfrom keras.layers import Dense, Dropout, Activation, Flatten, BatchNormalization, Conv2D, MaxPool2D, MaxPooling2D\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"60449b9dee0f4966602419240930763783f67e3f"},"cell_type":"code","source":"pretrained_model_1 = VGG16(include_top=False, input_shape=t_x.shape[1:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"61e0511c357954c89e6a65ad1f084854ef583baa"},"cell_type":"code","source":"from keras import optimizers\nbase_model = pretrained_model_1 # Topless\n\nadd_model = Sequential()\nadd_model.add(Flatten(input_shape=base_model.output_shape[1:]))\nadd_model.add(Dense(256, activation='relu'))\nadd_model.add(Dense(num_classes, activation='softmax'))\n\nmodel = Model(inputs=base_model.input, outputs=add_model(base_model.output))\nmodel.compile(loss='categorical_crossentropy', optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),\n              metrics=['accuracy'])\n\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4e99d9000b0105ac5a5a487105f1f60ccdc70a5d"},"cell_type":"code","source":"model.fit_generator(train_gen,steps_per_epoch=100,validation_data = (test_X, test_Y), \n                                  epochs = 30)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a473b70ac0365483dd607e088b590b232dd49307"},"cell_type":"markdown","source":"# Test Data Preparation"},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"90d02111e5133398e364d2520a134478996e5b5d"},"cell_type":"code","source":"test_image_paths = glob('../input/test/*.jpg', recursive=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"173b66522027c3cbeb00ce6e3e03a9a2ff06e3e1","collapsed":true},"cell_type":"code","source":"test_image_paths[0:3]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a6ed92bf5281da81824d293647b2aa26ae02d410","collapsed":true},"cell_type":"code","source":"X_test = pd.DataFrame()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"788a08e1dd29450db8b8c43fe74cee254cc49051"},"cell_type":"code","source":"X_test['path'] = test_image_paths","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"0270e260ef25bdc258d31e803918e39c8e5efad6"},"cell_type":"code","source":"X_test['labels'] = X_test['path'].map(lambda x: os.path.splitext(os.path.basename(x))[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"13e7b46f0b892ce875221cb00f9b1814a0637d55","collapsed":true},"cell_type":"code","source":"X_test[0:3]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"14d7b4f90c3ee4123cebb4272421fb85c190f1db","collapsed":true},"cell_type":"code","source":"test_gen = flow_from_dataframe(core_idg, X_test, \n                             path_col = 'path',\n                            y_col = 'labels', \n                            target_size = IMG_SIZE,\n                            batch_size = 256) # we can use much larger batches for evaluation","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4b545a673c314eb434d8c65d9505f26d0626384a","collapsed":true},"cell_type":"code","source":"len(X_test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ef25b465a77685a1ea09834e2a50e2cb3b1a874b","collapsed":true},"cell_type":"code","source":"pred_Y =  model.predict_generator(test_gen,verbose = 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"28b0872e7b4e00afc170199eed07e14906863fbb","collapsed":true},"cell_type":"code","source":"len(test_image_paths)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"52e151e8b96f44007946dbaaa0e40e54d5b6a7a8","collapsed":true},"cell_type":"code","source":"len(pred_Y)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a11aeac579e67c4cd8a0daff3348cc3259b3ea76","collapsed":true},"cell_type":"code","source":"predictions = pred_Y[:,1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"47e6cfd0b946fefeaef35d6784c4b722eb6fb3d6","collapsed":true},"cell_type":"code","source":"predictions[0:3]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"508fa1c6c7f57933f45422540d9f8392be818c5c","collapsed":true},"cell_type":"code","source":"len(predictions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"2afc27d94f4b38c8cab74e37cdbfb1673619bdb3"},"cell_type":"code","source":"submission=pd.DataFrame()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"9b2414ff3cd2798cf5600ba139394ed67352482b"},"cell_type":"code","source":"submission[\"id\"]=X_test[\"labels\"]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"b0f6dc77796e3849b8ba81f18113b76ebc7aae09"},"cell_type":"code","source":"submission[\"label\"] = predictions","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"824961ecd21de2ce8f1ca29c15ca41f943e786ff"},"cell_type":"code","source":"submission.to_csv(\"predictions.csv\",index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"a5585ca2168802ce05dd2840e69d04b0c7144f41"},"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.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}