{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"seed = 61299\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport os","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Added by Chirag\nfrom IPython.display import Image, display\n\nBASE_PATH = '../input/landmark-recognition-2020'\nTRAIN_DIR = f'{BASE_PATH}/train'\nTEST_DIR = f'{BASE_PATH}/test'\n\nprint('Reading data...')\ntrain = pd.read_csv(f'{BASE_PATH}/train.csv')\nsubmission = pd.read_csv(f'{BASE_PATH}/sample_submission.csv')\nprint('Reading data completed')\n\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Get all three IDs (113209,177870,194914)\nlandmark = train[train[\"landmark_id\"].isin([113209,177870,194914])]\n#Add a human-readable label to each\n\n#This should be so simple, but is UGLY and inelegant in Python\nlabels = pd.DataFrame({\"landmark_id\": [113209,177870,194914],\n         \"label\":[\"mountain\", \"city\", \"boat\"]})\n\n#Tack on a shuffle after merging\nlandmark = pd.merge(landmark, labels, on=\"landmark_id\", how=\"left\").sample(frac=1)\nlandmark.head()\n\n#Set full path to the image\ndef get_image_path(image_id):\n    return os.path.join(TRAIN_DIR, f'{image_id[0]}/{image_id[1]}/{image_id[2]}/{image_id}.jpg')\nlandmark[\"file_path\"] = landmark[\"id\"].apply(get_image_path)\n\nprint(landmark[\"label\"].value_counts())\nlandmark.head()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Visualize images\nimport PIL\nfrom PIL import Image, ImageDraw\n\ndef display_images(images,title=None): \n    f, ax = plt.subplots(5,5, figsize=(18,22))\n    if title:\n        f.suptitle(title, fontsize = 30)\n\n    for i, image_id in enumerate(images):\n        image_path = get_image_path(image_id)\n        image = Image.open(image_path)\n        \n        #This is clever floor division\n        ax[i//5, i%5].imshow(image) \n        ax[i//5, i%5].axis('off')\n        \n        #Add titles\n        landmark_id = landmark[landmark.id==image_id.split('.')[0]].landmark_id.values[0]\n        this_label = labels[labels[\"landmark_id\"] == landmark_id][\"label\"].values[0]\n        ax[i//5, i%5].set_title(f\"ID: {image_id.split('.')[0]}\\nLandmark_id: {landmark_id}\\nLabel: {this_label}\", fontsize=\"12\")\n\n    plt.show() ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# pick random 25 images from the dataset and print\nsamples = landmark.sample(25).id.values\ndisplay_images(samples)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"landmark.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Now ready for keras flow from directory\n\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nimagegen = ImageDataGenerator(rescale=1/255.,\n                             validation_split = 0.25) \n\n#Set up a generator\ntrain_generator = imagegen.flow_from_dataframe(dataframe = landmark,\n                                               directory = None,\n                                               x_col = \"file_path\",\n                                               y_col = \"label\",\n                                               target_size = (256,256),\n                                               class_mode = \"sparse\",\n                                               batch_size = 128,\n                                               shuffle = True,\n                                               seed = 42,\n                                               subset = \"training\")\n#Validation data\nval_generator = imagegen.flow_from_dataframe(dataframe = landmark,\n                                               directory = None,\n                                               x_col = \"file_path\",\n                                               y_col = \"label\",\n                                               target_size = (256,256),\n                                               class_mode = \"sparse\",\n                                               batch_size = 128,\n                                               shuffle = True,\n                                               seed = 42,\n                                               subset = \"validation\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Check the output from one batch\nfor batch_data, batch_labels in train_generator:\n    print(\"data batch shape: \" + str(batch_data.shape))\n    print(\"labels batch shape: \" +str(batch_labels.shape))\n    print(\"max value: \" + str(np.max(batch_data[1,:,:,0])))\n    print(\"min value: \" + str(np.min(batch_data[1,:,:,0])))\n    break\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Develop a simple linear classifier (this is a multinomial logistic model)\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\n\n#Functional API model\ninputs = keras.Input(shape = (256,256,3))\nx = layers.Flatten()(inputs)\noutputs = layers.Dense(3, activation = \"softmax\")(x)\n\nlinear_model = keras.Model(inputs = inputs, outputs = outputs, name = \"linear_model\")\nlinear_model.summary()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"keras.utils.plot_model(linear_model,show_shapes=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\n\ndef plot_history(history, log = False):\n    \n    epc = np.arange(len(history.history[\"loss\"]))+1\n    \n    fig, ax = plt.subplots(1,2, figsize = (16,8))\n    \n    #Loss\n    ax[0].plot(epc, history.history[\"loss\"], color = \"blue\")\n    ax[0].plot(epc, history.history[\"val_loss\"], color = \"red\")\n    ax[0].set_title(\"Loss\")\n    \n    if log:\n        ax[0].set_yscale('log')\n    \n    ax[1].plot(epc, history.history[\"accuracy\"], color = \"black\")\n    ax[1].plot(epc, history.history[\"val_accuracy\"], color = \"green\")\n    ax[1].set_title(\"Accuracy\")\n    \n    if log:\n        ax[1].set_yscale('log')\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Compile and train\nlinear_model.compile(loss = \"sparse_categorical_crossentropy\",\n                    optimizer = keras.optimizers.Adam(learning_rate = 1e-4),\n                    metrics = [\"accuracy\"])\n\n\nhistory = linear_model.fit(x = train_generator,\n                           validation_data = val_generator,\n                           epochs = 30,\n                           verbose = 1,\n                           use_multiprocessing = True)\n\n\nplot_history(history)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Fit a neural network with two hidden layers (a multilayer perceptron or MLP)\n#Functional API model\ndrop_prob = 0.3 #dropout probability\n\ninputs = keras.Input(shape = (256,256,3))\nx = layers.Flatten()(inputs)\nx = layers.Dense(512)(x)\nx = layers.Dropout(drop_prob)(x)\nx = layers.Dense(512)(x)\nx = layers.Dropout(drop_prob)(x)\noutputs = layers.Dense(3, activation = \"softmax\")(x)\n\nmlp_model = keras.Model(inputs = inputs, outputs = outputs, name = \"mlp_model\")\nmlp_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"keras.utils.plot_model(mlp_model,show_shapes=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mlp_model.compile(loss = \"sparse_categorical_crossentropy\",\n                    optimizer = keras.optimizers.Adam(learning_rate = 3e-4),\n                    metrics = [\"accuracy\"])\n\n\"\"\"\nhistory = mlp_model.fit(x = train_generator,\n                           validation_data = val_generator,\n                           epochs = 50,\n                           verbose = 1,\n                           use_multiprocessing = True)\n\nplot_history(history)\n\"\"\"","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":4}