{"cells":[{"metadata":{},"cell_type":"markdown","source":"**Example of transfer learning from pretrained model using Keras  and Efficientnet (https://pypi.org/project/efficientnet/).**"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install git+https://github.com/qubvel/efficientnet","execution_count":1,"outputs":[{"output_type":"stream","text":"Collecting git+https://github.com/qubvel/efficientnet\n  Cloning https://github.com/qubvel/efficientnet to /tmp/pip-req-build-e16wv0b8\nBuilding wheels for collected packages: efficientnet\n  Building wheel for efficientnet (setup.py) ... \u001b[?25ldone\n\u001b[?25h  Stored in directory: /tmp/pip-ephem-wheel-cache-a7ppqvb8/wheels/64/60/2e/30ebaa76ed1626e86bfb0cc0579b737fdb7d9ff8cb9522663a\nSuccessfully built efficientnet\nInstalling collected packages: efficientnet\nSuccessfully installed efficientnet-0.0.2\n\u001b[33mYou are using pip version 19.0.3, however version 19.1.1 is available.\nYou should consider upgrading via the 'pip install --upgrade pip' command.\u001b[0m\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"from efficientnet import EfficientNetB3","execution_count":2,"outputs":[{"output_type":"stream","text":"Using TensorFlow backend.\n","name":"stderr"}]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"import os\nimport cv2\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport numpy as np\nimport json\nfrom keras.models import Sequential, Model\nfrom keras.layers import Dense, Flatten, Activation, Dropout, GlobalAveragePooling2D\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import optimizers, applications\nfrom keras.callbacks import ModelCheckpoint, LearningRateScheduler, TensorBoard, EarlyStopping\nfrom keras import backend as K ","execution_count":3,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Train data"},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"ann_file = '../input/inaturalist-2019-fgvc6/train2019.json'\nwith open(ann_file) as data_file:\n        train_anns = json.load(data_file)","execution_count":4,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_anns_df = pd.DataFrame(train_anns['annotations'])[['image_id','category_id']]\ntrain_img_df = pd.DataFrame(train_anns['images'])[['id', 'file_name']].rename(columns={'id':'image_id'})\ndf_train_file_cat = pd.merge(train_img_df, train_anns_df, on='image_id')\ndf_train_file_cat['category_id']=df_train_file_cat['category_id'].astype(str)\ndf_train_file_cat.head()","execution_count":5,"outputs":[{"output_type":"execute_result","execution_count":5,"data":{"text/plain":"   image_id     ...     category_id\n0         0     ...             400\n1         1     ...             570\n2         2     ...             167\n3         3     ...             254\n4         4     ...             739\n\n[5 rows x 3 columns]","text/html":"<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>image_id</th>\n      <th>file_name</th>\n      <th>category_id</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>0</td>\n      <td>train_val2019/Plants/400/d1322d13ccd856eb4236c...</td>\n      <td>400</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>1</td>\n      <td>train_val2019/Plants/570/15edbc1e2ef000d8ace48...</td>\n      <td>570</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2</td>\n      <td>train_val2019/Reptiles/167/c87a32e8927cbf4f06d...</td>\n      <td>167</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>3</td>\n      <td>train_val2019/Birds/254/9fcdd1d37e96d8fd94dfdc...</td>\n      <td>254</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>4</td>\n      <td>train_val2019/Plants/739/ffa06f951e99de9d220ae...</td>\n      <td>739</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(df_train_file_cat['category_id'].unique())","execution_count":6,"outputs":[{"output_type":"execute_result","execution_count":6,"data":{"text/plain":"1010"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Example of images for category_id = 400\nimg_names = df_train_file_cat[df_train_file_cat['category_id']=='400']['file_name'][:30]\n\nplt.figure(figsize=[15,15])\ni = 1\nfor img_name in img_names:\n    img = cv2.imread(\"../input/inaturalist-2019-fgvc6/train_val2019/%s\" % img_name)[...,[2, 1, 0]]\n    plt.subplot(6, 5, i)\n    plt.imshow(img)\n    i += 1\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Validation data"},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_ann_file = '../input/inaturalist-2019-fgvc6/val2019.json'\nwith open(valid_ann_file) as data_file:\n        valid_anns = json.load(data_file)","execution_count":7,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_anns_df = pd.DataFrame(valid_anns['annotations'])[['image_id','category_id']]\nvalid_anns_df.head()","execution_count":8,"outputs":[{"output_type":"execute_result","execution_count":8,"data":{"text/plain":"   image_id  category_id\n0    265213          644\n1    265214          597\n2    265215          883\n3    265216          300\n4    265217          881","text/html":"<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>image_id</th>\n      <th>category_id</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>265213</td>\n      <td>644</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>265214</td>\n      <td>597</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>265215</td>\n      <td>883</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>265216</td>\n      <td>300</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>265217</td>\n      <td>881</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_img_df = pd.DataFrame(valid_anns['images'])[['id', 'file_name']].rename(columns={'id':'image_id'})\nvalid_img_df.head()","execution_count":9,"outputs":[{"output_type":"execute_result","execution_count":9,"data":{"text/plain":"   image_id                                          file_name\n0    265213  train_val2019/Plants/644/716a69838526f3ada3b2f...\n1    265214  train_val2019/Plants/597/0942cc64d2e759c5ee059...\n2    265215  train_val2019/Plants/883/acfdbfd9fa675f1c84558...\n3    265216  train_val2019/Birds/300/5f3194ff536c7dd31d80b7...\n4    265217  train_val2019/Plants/881/76acaf0b2841f91982d21...","text/html":"<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>image_id</th>\n      <th>file_name</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>265213</td>\n      <td>train_val2019/Plants/644/716a69838526f3ada3b2f...</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>265214</td>\n      <td>train_val2019/Plants/597/0942cc64d2e759c5ee059...</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>265215</td>\n      <td>train_val2019/Plants/883/acfdbfd9fa675f1c84558...</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>265216</td>\n      <td>train_val2019/Birds/300/5f3194ff536c7dd31d80b7...</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>265217</td>\n      <td>train_val2019/Plants/881/76acaf0b2841f91982d21...</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_valid_file_cat = pd.merge(valid_img_df, valid_anns_df, on='image_id')\ndf_valid_file_cat['category_id']=df_valid_file_cat['category_id'].astype(str)\ndf_valid_file_cat.head()","execution_count":10,"outputs":[{"output_type":"execute_result","execution_count":10,"data":{"text/plain":"   image_id     ...     category_id\n0    265213     ...             644\n1    265214     ...             597\n2    265215     ...             883\n3    265216     ...             300\n4    265217     ...             881\n\n[5 rows x 3 columns]","text/html":"<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>image_id</th>\n      <th>file_name</th>\n      <th>category_id</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>265213</td>\n      <td>train_val2019/Plants/644/716a69838526f3ada3b2f...</td>\n      <td>644</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>265214</td>\n      <td>train_val2019/Plants/597/0942cc64d2e759c5ee059...</td>\n      <td>597</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>265215</td>\n      <td>train_val2019/Plants/883/acfdbfd9fa675f1c84558...</td>\n      <td>883</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>265216</td>\n      <td>train_val2019/Birds/300/5f3194ff536c7dd31d80b7...</td>\n      <td>300</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>265217</td>\n      <td>train_val2019/Plants/881/76acaf0b2841f91982d21...</td>\n      <td>881</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"nb_classes = 1010\nbatch_size = 256\nimg_size = 96\nnb_epochs = 10","execution_count":41,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\ntrain_datagen=ImageDataGenerator(rescale=1./255, \n    validation_split=0.25,\n    horizontal_flip = True,    \n    zoom_range = 0.3,\n    width_shift_range = 0.3,\n    height_shift_range=0.3\n    )\n\ntrain_generator=train_datagen.flow_from_dataframe(    \n    dataframe=df_train_file_cat,    \n    directory=\"../input/inaturalist-2019-fgvc6/train_val2019\",\n    x_col=\"file_name\",\n    y_col=\"category_id\",\n    batch_size=batch_size,\n    shuffle=True,\n    class_mode=\"categorical\",    \n    target_size=(img_size,img_size))","execution_count":40,"outputs":[{"output_type":"stream","text":"Found 25000 images belonging to 1010 classes.\nCPU times: user 316 ms, sys: 364 ms, total: 680 ms\nWall time: 2.61 s\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\nvalid_generator=test_datagen.flow_from_dataframe(    \n    dataframe=df_valid_file_cat,    \n    directory=\"../input/inaturalist-2019-fgvc6/train_val2019\",\n    x_col=\"file_name\",\n    y_col=\"category_id\",\n    batch_size=batch_size,\n    shuffle=True,\n    class_mode=\"categorical\",    \n    target_size=(img_size,img_size))","execution_count":36,"outputs":[{"output_type":"stream","text":"Found 3030 images belonging to 1010 classes.\nCPU times: user 92 ms, sys: 100 ms, total: 192 ms\nWall time: 946 ms\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"### Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"model = EfficientNetB3(weights='imagenet', include_top=False, input_shape=(img_size, img_size, 3))","execution_count":14,"outputs":[{"output_type":"stream","text":"WARNING:tensorflow:From /opt/conda/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\nInstructions for updating:\nColocations handled automatically by placer.\nWARNING:tensorflow:From /opt/conda/lib/python3.6/site-packages/tensorflow/python/framework/function.py:1007: calling Graph.create_op (from tensorflow.python.framework.ops) with compute_shapes is deprecated and will be removed in a future version.\nInstructions for updating:\nShapes are always computed; don't use the compute_shapes as it has no effect.\nWARNING:tensorflow:From /opt/conda/lib/python3.6/site-packages/efficientnet/layers.py:29: div (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\nInstructions for updating:\nDeprecated in favor of operator or tf.math.divide.\nDownloading data from https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b3_imagenet_1000_notop.h5\n43974656/43966704 [==============================] - 2s 0us/step\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.trainable = False","execution_count":15,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Freeze some layers\n# for layer in model.layers[:-4]:\n#     layer.trainable = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Adding custom layers \nx = model.output\nx = Flatten()(x)\nx = Dense(1024, activation=\"relu\")(x)\nx = Dropout(0.5)(x)\npredictions = Dense(nb_classes, activation=\"softmax\")(x)\nmodel_final = Model(input = model.input, output = predictions)\n\nmodel_final.compile(optimizers.rmsprop(lr=0.0001, decay=1e-6),loss='categorical_crossentropy',metrics=['accuracy'])","execution_count":42,"outputs":[{"output_type":"stream","text":"/opt/conda/lib/python3.6/site-packages/ipykernel_launcher.py:7: UserWarning: Update your `Model` call to the Keras 2 API: `Model(inputs=Tensor(\"in..., outputs=Tensor(\"de...)`\n  import sys\n","name":"stderr"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Callbacks\n\ncheckpoint = ModelCheckpoint(\"vgg16_1.h5\", monitor='val_loss', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1)\nearly = EarlyStopping(monitor='val_loss', min_delta=0, patience=5, verbose=1, mode='auto')","execution_count":25,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nhistory = model_final.fit_generator(generator=train_generator,  \n                                    \n                                    steps_per_epoch=5,\n                                    \n                                    validation_data=valid_generator, \n                                    \n                                    validation_steps=2,\n                                    \n                                    epochs=nb_epochs,\n                                    callbacks = [checkpoint, early],\n                                    verbose=2)","execution_count":43,"outputs":[{"output_type":"stream","text":"Epoch 1/1\n - 26s - loss: 7.2383 - acc: 0.0000e+00 - val_loss: 7.0320 - val_acc: 0.0000e+00\n\nEpoch 00001: val_loss improved from inf to 7.03203, saving model to vgg16_1.h5\nCPU times: user 3min 47s, sys: 1 s, total: 3min 48s\nWall time: 3min 40s\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"with open('history.json', 'w') as f:\n    json.dump(history.history, f)\n\nhistory_df = pd.DataFrame(history.history)\nhistory_df[['loss', 'val_loss']].plot()\nhistory_df[['acc', 'val_acc']].plot()","execution_count":44,"outputs":[{"output_type":"execute_result","execution_count":44,"data":{"text/plain":"<matplotlib.axes._subplots.AxesSubplot at 0x7f7ab7da7eb8>"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"<Figure size 432x288 with 1 Axes>","image/png":"iVBORw0KGgoAAAANSUhEUgAAAX4AAAD8CAYAAABw1c+bAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAEjdJREFUeJzt3XtwHeV5x/Hvgy1sAriAMTYgjO0OwYBVTEcQmMYmQLlOuASaGEIg0HInECAwmEBakpJJAtPQyZTiMgwJZLjY4TLjDgRKAolhQqgvFZibjTEYJG62QyCBGhP76R86pAchkI50pCPzfj8zZ7Rn993d55Fnfl69uzqKzESSVI6NGl2AJGlwGfySVBiDX5IKY/BLUmEMfkkqjMEvSYUx+CWpMAa/JBXG4JekwgxvdAHd2XrrrXPChAmNLkOSNhgLFy5clZljejN2SAb/hAkTWLBgQaPLkKQNRkSs6O1Yp3okqTAGvyQVxuCXpMIMyTl+SeV57733aG9vZ82aNY0uZUgbOXIkzc3NNDU19fkYBr+kIaG9vZ3NN9+cCRMmEBGNLmdIykxWr15Ne3s7EydO7PNxnOqRNCSsWbOG0aNHG/ofIyIYPXp0v38qMvglDRmGfs/q8T0y+CWpMAa/JFVsttlmjS5hUBj8klQYg1+SushMLrroIqZMmUJLSwuzZ88G4JVXXmH69OlMnTqVKVOm8NBDD7Fu3TpOOumkP4+9+uqrG1x9z3ycU9KQ8+3/fJKnXn6rrsfcdbtR/NPhu/Vq7J133klbWxuPPfYYq1atYs8992T69OnccsstHHzwwVx66aWsW7eOd955h7a2Njo6OnjiiScA+P3vf1/XugeCV/yS1MXDDz/Mcccdx7Bhwxg7diz77rsv8+fPZ8899+THP/4xl19+OYsXL2bzzTdn0qRJLF++nHPOOYd7772XUaNGNbr8HnnFL2nI6e2V+WCbPn068+bN4+677+akk07iggsu4MQTT+Sxxx7jvvvuY9asWcyZM4cbbrih0aV+LK/4JamLadOmMXv2bNatW8fKlSuZN28ee+21FytWrGDs2LGceuqpnHLKKSxatIhVq1axfv16jjnmGK644goWLVrU6PJ75BW/JHXxhS98gUceeYTdd9+diODKK69k3Lhx3HjjjVx11VU0NTWx2WabcdNNN9HR0cHJJ5/M+vXrAfje977X4Op7FpnZ6Bo+pLW1Nf1DLFJZnn76aXbZZZdGl7FB6O57FRELM7O1N/s71SNJhTH4JakwBr8kFcbgl6TCGPySVBiDX5IKY/BLUmEMfknqg4/77P4XXniBKVOmDGI1tTH4JakwfmSDpKHn5zPh1cX1Pea4Fjj0+x+5eebMmeywww6cffbZAFx++eUMHz6cBx98kDfeeIP33nuPK664giOPPLKm065Zs4YzzzyTBQsWMHz4cH74wx+y33778eSTT3LyySezdu1a1q9fzx133MF2223Hl770Jdrb21m3bh3f+ta3mDFjRr/a7o7BL0nAjBkzOO+88/4c/HPmzOG+++7j3HPPZdSoUaxatYq9996bI444oqY/eH7NNdcQESxevJhnnnmGgw46iKVLlzJr1iy+/vWvc/zxx7N27VrWrVvHPffcw3bbbcfdd98NwJtvvjkgvRr8koaej7kyHyh77LEHr7/+Oi+//DIrV65kyy23ZNy4cZx//vnMmzePjTbaiI6ODl577TXGjRvX6+M+/PDDnHPOOQBMnjyZHXfckaVLl7LPPvvw3e9+l/b2do4++mh22mknWlpa+MY3vsHFF1/M5z//eaZNmzYgvTrHL0kVX/ziF7n99tuZPXs2M2bM4Oabb2blypUsXLiQtrY2xo4dy5o1a+pyri9/+cvMnTuXTTbZhMMOO4wHHniAT3/60yxatIiWlhYuu+wyvvOd79TlXF15xS9JFTNmzODUU09l1apV/PrXv2bOnDlss802NDU18eCDD7JixYqajzlt2jRuvvlm9t9/f5YuXcqLL77IzjvvzPLly5k0aRLnnnsuL774Io8//jiTJ09mq6224itf+QpbbLEF119//QB0afBL0p/ttttu/OEPf2D77bdn22235fjjj+fwww+npaWF1tZWJk+eXPMxzzrrLM4880xaWloYPnw4P/nJTxgxYgRz5szhpz/9KU1NTYwbN45vfvObzJ8/n4suuoiNNtqIpqYmrr322gHo0s/jlzRE+Hn8vefn8UuSauJUjyT10eLFiznhhBM+sG7EiBE8+uijDaqodwx+SUNGZtb0jHyjtbS00NbWNqjnrMf0vFM9koaEkSNHsnr16roE2ydVZrJ69WpGjhzZr+N4xS9pSGhubqa9vZ2VK1c2upQhbeTIkTQ3N/frGAa/pCGh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\n"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"<Figure size 432x288 with 1 Axes>","image/png":"iVBORw0KGgoAAAANSUhEUgAAAYYAAAD8CAYAAABzTgP2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAEwdJREFUeJzt3X+s1fV9x/HnW6AwYouXHwrlyi5bTSoU0XpqXbdVJ/6AJfUaJ8Gm6UjXlTSzMdU0KavNdEoW7brZmjqXm7YJmG5oachYmpaAYFjW1nlxLlTUQrGGi4oIhJW2tOLe++N+a8/n9uCFe869h6PPR3Jyv9/v5/39nvfn3uS+7vfHgchMJEn6tTPa3YAk6fRiMEiSCgaDJKlgMEiSCgaDJKlgMEiSCgaDJKlgMEiSCgaDJKkwvt0NjMT06dOzp6en3W1IUkfZvn37K5k5Y7i6jgyGnp4e+vv7292GJHWUiHj+ZOq8lCRJKhgMkqSCwSBJKnTkPQZJb22vvvoqAwMDHDt2rN2tnJYmTZpEd3c3EyZMGNH+BoOkjjMwMMDb3/52enp6iIh2t3NayUwOHjzIwMAAc+fOHdExvJQkqeMcO3aMadOmGQoNRATTpk1r6mzKYJDUkQyFE2v2e2MwSJIKBoMkqWAwSJIKBoMkjcB1113HxRdfzPz58+nr6wPgu9/9Lu9973tZuHAhixYtAuDo0aN87GMfY8GCBVxwwQV861vfamfbJ8XHVSV1tL/996fY+cL/tvSY8975Dm7/0Pw3rPn617/O1KlT+cUvfsH73vc+ent7+cQnPsG2bduYO3cuhw4dAuCuu+5iypQp7NixA4DDhw+3tNfRYDBI0gjcd999rF+/HoC9e/fS19fHBz/4wdc/OzB16lQANm/ezNq1a1/fr6ura+ybPUUGg6SONtxf9qPh0UcfZfPmzXz/+99n8uTJXH755Vx44YU888wzY97LaPAegySdoiNHjtDV1cXkyZN55pln+MEPfsCxY8fYtm0bzz33HMDrl5Kuuuoq7r///tf37YRLSQaDJJ2ixYsXc/z4cc4//3xWrlzJpZdeyowZM+jr6+P6669n4cKFLFu2DIDPf/7zHD58mPe85z0sXLiQrVu3trn74XkpSZJO0cSJE/nOd77TcGzJkiXF+plnnsnq1avHoq2W8YxBklQwGCRJBYNBklQwGCRJBYNBklQwGCRJBYNBklRoSTBExOKIeDYidkfEygbjEyPioWr8sYjoGTI+JyKORsRnWtGPJJ1OzjzzzHa3cEqaDoaIGAfcDywB5gEfjoh5Q8o+DhzOzHcB9wL3DBn/R6Dxp0UkSWOqFZ98vgTYnZl7ACJiLdAL7Kyr6QXuqJbXAV+JiMjMjIjrgOeAn7WgF0lvNd9ZCS/taO0xZy6AJXefcHjlypWce+653HTTTQDccccdjB8/nq1bt3L48GFeffVVVq1aRW9v77BvdfToUXp7exvut2bNGr74xS8SEVxwwQU8+OCD7N+/n09+8pPs2bMHgAceeIAPfOADLZj0b7QiGGYDe+vWB4D3n6gmM49HxBFgWkQcAz4LXAV4GUlSR1i2bBmf/vSnXw+Ghx9+mI0bN3LzzTfzjne8g1deeYVLL72Ua6+9loh4w2NNmjSJ9evX/9Z+O3fuZNWqVXzve99j+vTpr/+jfDfffDOXXXYZ69ev57XXXuPo0aMtn1+7/62kO4B7M/PocN+8iFgBrACYM2fO6HcmqTO8wV/2o+Wiiy7i5Zdf5oUXXuDAgQN0dXUxc+ZMbrnlFrZt28YZZ5zBvn372L9/PzNnznzDY2Umn/vc535rvy1btrB06VKmT58O/Ob/d9iyZQtr1qwBYNy4cUyZMqXl82tFMOwDzq1b7662NaoZiIjxwBTgIINnFjdExBeAs4D/i4hjmfmVoW+SmX1AH0CtVssW9C1JI7Z06VLWrVvHSy+9xLJly/jGN77BgQMH2L59OxMmTKCnp4djx44Ne5yR7jeaWvFU0uPAeRExNyLeBtwIbBhSswFYXi3fAGzJQX+cmT2Z2QN8Cfi7RqEgSaebZcuWsXbtWtatW8fSpUs5cuQIZ599NhMmTGDr1q08//zzJ3WcE+13xRVX8M1vfpODBw8Cv/n/HRYtWsQDDzwAwGuvvcaRI0daPremgyEzjwOfAjYCTwMPZ+ZTEXFnRFxblX2NwXsKu4Fbgd96pFWSOsn8+fP56U9/yuzZs5k1axYf+chH6O/vZ8GCBaxZs4Z3v/vdJ3WcE+03f/58brvtNi677DIWLlzIrbfeCsCXv/xltm7dyoIFC7j44ovZuXPnGx1+RCKz867K1Gq17O/vb3cbktrk6aef5vzzz293G6e1Rt+jiNiembXh9vWTz5KkQrufSpKkt4QdO3bw0Y9+tNg2ceJEHnvssTZ1dGIGg6SOlJnDfkbgdLJgwQKefPLJMXmvZm8ReClJUseZNGkSBw8ebPoX4JtRZnLw4EEmTZo04mN4xiCp43R3dzMwMMCBAwfa3cppadKkSXR3d494f4NBUseZMGECc+fObXcbb1peSpIkFQwGSVLBYJAkFQwGSVLBYJAkFQwGSVLBYJAkFQwGSVLBYJAkFQwGSVLBYJAkFQwGSVLBYJAkFQwGSVLBYJAkFQwGSVLBYJAkFQwGSVLBYJAkFQwGSVLBYJAkFQwGSVLBYJAkFQwGSVLBYJAkFVoSDBGxOCKejYjdEbGywfjEiHioGn8sInqq7VdFxPaI2FF9vaIV/UiSRq7pYIiIccD9wBJgHvDhiJg3pOzjwOHMfBdwL3BPtf0V4EOZuQBYDjzYbD+SpOa04ozhEmB3Zu7JzF8Ba4HeITW9wOpqeR2wKCIiM/87M1+otj8F/E5ETGxBT5KkEWpFMMwG9tatD1TbGtZk5nHgCDBtSM2fAU9k5i9b0JMkaYTGt7sBgIiYz+DlpavfoGYFsAJgzpw5Y9SZJL31tOKMYR9wbt16d7WtYU1EjAemAAer9W5gPfDnmfnjE71JZvZlZi0zazNmzGhB25KkRloRDI8D50XE3Ih4G3AjsGFIzQYGby4D3ABsycyMiLOAbwMrM/M/W9CLJKlJTQdDdc/gU8BG4Gng4cx8KiLujIhrq7KvAdMiYjdwK/DrR1o/BbwL+JuIeLJ6nd1sT5KkkYvMbHcPp6xWq2V/f3+725CkjhIR2zOzNlydn3yWJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSwWCQJBUMBklSoSXBEBGLI+LZiNgdESsbjE+MiIeq8ccioqdu7K+r7c9GxDWt6EeSNHJNB0NEjAPuB5YA84APR8S8IWUfBw5n5ruAe4F7qn3nATcC84HFwD9Vx5MktUkrzhguAXZn5p7M/BWwFugdUtMLrK6W1wGLIiKq7Wsz85eZ+RywuzqeJKlNWhEMs4G9desD1baGNZl5HDgCTDvJfSVJY6hjbj5HxIqI6I+I/gMHDrS7HUl602pFMOwDzq1b7662NayJiPHAFODgSe4LQGb2ZWYtM2szZsxoQduSpEZaEQyPA+dFxNyIeBuDN5M3DKnZACyvlm8AtmRmVttvrJ5amgucB/xXC3qSJI3Q+GYPkJnHI+JTwEZgHPD1zHwqIu4E+jNzA/A14MGI2A0cYjA8qOoeBnYCx4GbMvO1ZnuSJI1cDP7h3llqtVr29/e3uw1J6igRsT0za8PVdczNZ0nS2DAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVDAYJEkFg0GSVGgqGCJiakRsiohd1deuE9Qtr2p2RcTyatvkiPh2RDwTEU9FxN3N9CJJao1mzxhWAo9k5nnAI9V6ISKmArcD7wcuAW6vC5AvZua7gYuAP4yIJU32I0lqUrPB0AusrpZXA9c1qLkG2JSZhzLzMLAJWJyZP8/MrQCZ+SvgCaC7yX4kSU1qNhjOycwXq+WXgHMa1MwG9tatD1TbXhcRZwEfYvCsQ5LURuOHK4iIzcDMBkO31a9kZkZEnmoDETEe+Ffgvszc8wZ1K4AVAHPmzDnVt5EknaRhgyEzrzzRWETsj4hZmfliRMwCXm5Qtg+4vG69G3i0br0P2JWZXxqmj76qllqtdsoBJEk6Oc1eStoALK+WlwP/1qBmI3B1RHRVN52vrrYREauAKcCnm+xDktQizQbD3cBVEbELuLJaJyJqEfFVgMw8BNwFPF697szMQxHRzeDlqHnAExHxZET8ZZP9SJKaFJmdd1WmVqtlf39/u9uQpI4SEdszszZcnZ98liQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUsFgkCQVDAZJUqGpYIiIqRGxKSJ2VV+7TlC3vKrZFRHLG4xviIgfNtOLJKk1mj1jWAk8kpnnAY9U64WImArcDrwfuAS4vT5AIuJ64GiTfUiSWqTZYOgFVlfLq4HrGtRcA2zKzEOZeRjYBCwGiIgzgVuBVU32IUlqkWaD4ZzMfLFafgk4p0HNbGBv3fpAtQ3gLuAfgJ832YckqUXGD1cQEZuBmQ2GbqtfycyMiDzZN46IC4Hfz8xbIqLnJOpXACsA5syZc7JvI0k6RcMGQ2ZeeaKxiNgfEbMy88WImAW83KBsH3B53Xo38CjwB0AtIn5S9XF2RDyamZfTQGb2AX0AtVrtpANIknRqmr2UtAH49VNGy4F/a1CzEbg6Irqqm85XAxsz84HMfGdm9gB/BPzoRKEgSRo7zQbD3cBVEbELuLJaJyJqEfFVgMw8xOC9hMer153VNknSaSgyO++qTK1Wy/7+/na3IUkdJSK2Z2ZtuDo/+SxJKhgMkqSCwSBJKhgMkqSCwSBJKhgMkqSCwSBJKhgMkqSCwSBJKhgMkqSCwSBJKhgMkqSCwSBJKhgMkqSCwSBJKhgMkqSCwSBJKhgMkqSCwSBJKhgMkqSCwSBJKhgMkqSCwSBJKhgMkqSCwSBJKkRmtruHUxYRB4Dn293HKZoOvNLuJsaYc35rcM6d43czc8ZwRR0ZDJ0oIvozs9buPsaSc35rcM5vPl5KkiQVDAZJUsFgGDt97W6gDZzzW4NzfpPxHoMkqeAZgySpYDC0UERMjYhNEbGr+tp1grrlVc2uiFjeYHxDRPxw9DtuXjNzjojJEfHtiHgmIp6KiLvHtvtTExGLI+LZiNgdESsbjE+MiIeq8ccioqdu7K+r7c9GxDVj2XczRjrniLgqIrZHxI7q6xVj3ftINPMzrsbnRMTRiPjMWPU8KjLTV4tewBeAldXySuCeBjVTgT3V165quatu/HrgX4Aftns+oz1nYDLwJ1XN24D/AJa0e04nmOc44MfA71W9/g8wb0jNXwH/XC3fCDxULc+r6icCc6vjjGv3nEZ5zhcB76yW3wPsa/d8RnO+dePrgG8Cn2n3fJp5ecbQWr3A6mp5NXBdg5prgE2ZeSgzDwObgMUAEXEmcCuwagx6bZURzzkzf56ZWwEy81fAE0D3GPQ8EpcAuzNzT9XrWgbnXq/+e7EOWBQRUW1fm5m/zMzngN3V8U53I55zZv53Zr5QbX8K+J2ImDgmXY9cMz9jIuI64DkG59vRDIbWOiczX6yWXwLOaVAzG9hbtz5QbQO4C/gH4Oej1mHrNTtnACLiLOBDwCOj0WQLDDuH+prMPA4cAaad5L6no2bmXO/PgCcy85ej1GerjHi+1R91nwX+dgz6HHXj291Ap4mIzcDMBkO31a9kZkbEST/yFREXAr+fmbcMvW7ZbqM157rjjwf+FbgvM/eMrEudjiJiPnAPcHW7exlldwD3ZubR6gSioxkMpygzrzzRWETsj4hZmfliRMwCXm5Qtg+4vG69G3gU+AOgFhE/YfDncnZEPJqZl9NmozjnX+sDdmXml1rQ7mjZB5xbt95dbWtUM1CF3RTg4EnuezpqZs5ERDewHvjzzPzx6LfbtGbm+37ghoj4AnAW8H8RcSwzvzL6bY+Cdt/keDO9gL+nvBH7hQY1Uxm8DtlVvZ4Dpg6p6aFzbj43NWcG76d8Czij3XMZZp7jGbxpPpff3JicP6TmJsobkw9Xy/Mpbz7voTNuPjcz57Oq+uvbPY+xmO+Qmjvo8JvPbW/gzfRi8NrqI8AuYHPdL78a8NW6ur9g8AbkbuBjDY7TScEw4jkz+BdZAk8DT1avv2z3nN5grn8K/IjBJ1duq7bdCVxbLU9i8ImU3cB/Ab9Xt+9t1X7Pcpo+edXKOQOfB35W93N9Eji73fMZzZ9x3TE6Phj85LMkqeBTSZKkgsEgSSoYDJKkgsEgSSoYDJKkgsEgSSoYDJKkgsEgSSr8PzZrrTRwFbRfAAAAAElFTkSuQmCC\n"},"metadata":{}}]},{"metadata":{},"cell_type":"markdown","source":"### Test data"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_ann_file = '../input/inaturalist-2019-fgvc6/test2019.json'\nwith open(test_ann_file) as data_file:\n        test_anns = json.load(data_file)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_img_df = pd.DataFrame(test_anns['images'])[['id', 'file_name']].rename(columns={'id':'image_id'})\ntest_img_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n\ntest_generator = test_datagen.flow_from_dataframe(      \n    \n        dataframe=test_img_df,    \n    \n        directory = \"../input/inaturalist-2019-fgvc6/test2019\",    \n        x_col=\"file_name\",\n        target_size = (img_size,img_size),\n        batch_size = 1,\n        shuffle = False,\n        class_mode = None\n        )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Prediction"},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\ntest_generator.reset()\npredict=model_final.predict_generator(test_generator, steps = len(test_generator.filenames))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(predict)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predicted_class_indices=np.argmax(predict,axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = (train_generator.class_indices)\nlabels = dict((v,k) for k,v in labels.items())\npredictions = [labels[k] for k in predicted_class_indices]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sam_sub_df = pd.read_csv('../input/inaturalist-2019-fgvc6/kaggle_sample_submission.csv')\nsam_sub_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"filenames=test_generator.filenames\nresults=pd.DataFrame({\"file_name\":filenames,\n                      \"predicted\":predictions})\ndf_res = pd.merge(test_img_df, results, on='file_name')[['image_id','predicted']]\\\n    .rename(columns={'image_id':'id'})\n\ndf_res.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_res.to_csv(\"submission.csv\",index=False)","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}