{"cells":[{"metadata":{"_uuid":"69d2efeec40b970538a50997a6ae667fb52145b8"},"cell_type":"markdown","source":"# Image classification with Keras"},{"metadata":{"_uuid":"1edb476cc9fdc8079734156e8c8a3a1f6d18cfbb"},"cell_type":"markdown","source":"![](http://)## Install dependencies"},{"metadata":{"_uuid":"d9a854a3cd7e221db870f61d95b8372b5e642f69","trusted":false},"cell_type":"code","source":"%matplotlib inline\nimport os\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\n\nfrom keras import optimizers\nfrom keras.models import Sequential\nfrom keras.layers import (\n    Dense,\n    Dropout,\n    Flatten,\n    ZeroPadding2D,\n    Conv2D,\n    MaxPool2D,\n    Activation,\n)\nfrom keras.preprocessing.image import ImageDataGenerator\n\nprint(\"import is ready\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"78bf344f5f3dcd1ff3962520998d7aacf21e98ef","trusted":false},"cell_type":"code","source":"# set consistent random seed\nrandom_seed = 2018\nnp.random.seed(random_seed)  \ntf.set_random_seed(random_seed)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2d1d46e6569522b8ecd1b07a7b94a6b1ab9c4d9e"},"cell_type":"markdown","source":""},{"metadata":{"_uuid":"dae00b73201663ee1d221e084857d364f9070948"},"cell_type":"markdown","source":"## Dataset\nWhales dataset"},{"metadata":{"_uuid":"153d1c97dabbba900aca6b5ba2610023e6c9ba54"},"cell_type":"markdown","source":"### Show the content of the current and parent folder"},{"metadata":{"_uuid":"b5a53e5267fe99d98ce6227f54c9952280f67a6e","trusted":false},"cell_type":"code","source":"print(os.listdir(\"..\"))\nprint(os.listdir(\".\"))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fe89170d5cfe11ff0e517ac2be24c8a93679b3ee"},"cell_type":"markdown","source":"### Show the content of the input folder"},{"metadata":{"_uuid":"f5d2eadabe3dcff48419b129b0731cd6ac5238ba","trusted":false},"cell_type":"code","source":"print(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2c3c0355171cc1c56578f56b884fb98607691550"},"cell_type":"markdown","source":"### Importing, normalizing, visualizing"},{"metadata":{"_uuid":"1dfb8fd00f700d01d58c2daefbbe66999079cec3"},"cell_type":"markdown","source":"Let's upload whales dataset."},{"metadata":{"_uuid":"a3511c220c54d001ade23212c8500c1da4587651","trusted":false},"cell_type":"code","source":"# flow_from_dataframe\n# https://medium.com/@vijayabhaskar96/tutorial-on-keras-flow-from-dataframe-1fd4493d237c\ntraindf=pd.read_csv(\"../input/train.csv\",dtype=str)\n# remove new whales from input\ntraindf = traindf[traindf.Id != \"new_whale\"]\n# remove single whales values\ntraindf = traindf.groupby('Id').filter(lambda x: len(x) > 1)\n# plot Id frequencies\ntraindf['Id'].value_counts()[1:16].plot(kind='bar')\n\ntestdf=pd.read_csv(\"../input/sample_submission.csv\",dtype=str)\n\n# datagen=ImageDataGenerator(rescale=1./255.,validation_split=0.25)\ndatagen = ImageDataGenerator(\n        rotation_range=20,\n        width_shift_range=0.1,\n        height_shift_range=0.1,\n        shear_range=0.5,\n        zoom_range=(0.9, 1.1),\n        horizontal_flip=False,\n        vertical_flip=False,\n        fill_mode='constant',\n        cval=0,\n        rescale=1./255.,\n        validation_split=0.25    \n)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"719fb63b764a0a9922c03f4113944d9654ea6776"},"cell_type":"markdown","source":"Print obtained dataframes for checking"},{"metadata":{"_uuid":"12537f7667d69638cb0ff5bac022b4c810abb59c","trusted":false},"cell_type":"code","source":"traindf.shape\n# Calculate number of unique classes (whales)\nnumber_of_classes = traindf['Id'].nunique()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c51bbc67a4d2b97b4cca0f1ad1d0516f22c51b3a","trusted":false},"cell_type":"code","source":"testdf.head(1)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"17b1aabe891e79ea851b4953857d2e213d189523","trusted":false},"cell_type":"code","source":"# Pass the dataframes to 2 different flow_from_dataframe functions\n# https://medium.com/@vijayabhaskar96/tutorial-on-keras-flow-from-dataframe-1fd4493d237c\ntrain_generator=datagen.flow_from_dataframe(\ndataframe=traindf,\ndirectory=\"../input/train/\",\nx_col=\"Image\",\ny_col=\"Id\",\nsubset=\"training\",\nbatch_size=32,\nseed=42,\nshuffle=True,\nclass_mode=\"categorical\",\ntarget_size=(80,80))\n\nvalid_generator=datagen.flow_from_dataframe(\ndataframe=traindf,\ndirectory=\"../input/train/\",\nx_col=\"Image\",\ny_col=\"Id\",\nsubset=\"validation\",\nbatch_size=32,\nseed=42,\nshuffle=True,\nclass_mode=\"categorical\",\ntarget_size=(80,80))\n\ntest_datagen=ImageDataGenerator(rescale=1./255.)\n\ntest_generator=test_datagen.flow_from_dataframe(\ndataframe=testdf,\ndirectory=\"../input/test/\",\nx_col=\"Image\",\ny_col=None,\nbatch_size=32,\nseed=42,\nshuffle=False,\nclass_mode=None,\ntarget_size=(80,80))\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8c5edbb0be6a2744be4b83100117fc529c811966","trusted":false},"cell_type":"code","source":"# Model @frommedium\n# https://medium.com/@vijayabhaskar96/tutorial-on-keras-flow-from-dataframe-1fd4493d237c\nmodel = Sequential()\nmodel.add(Conv2D(64, (3, 3), padding='same',\n                 input_shape=(80,80,3)))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(64, (3, 3)))\nmodel.add(Activation('relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(128, (3, 3), padding='same'))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(128, (3, 3)))\nmodel.add(Activation('relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\n# VGG 19 start\n# https://gist.github.com/baraldilorenzo/8d096f48a1be4a2d660d\n# part 2\nmodel.add(ZeroPadding2D((1,1)))\nmodel.add(Conv2D(128, (3, 3)))\nmodel.add(ZeroPadding2D((1,1)))\nmodel.add(Conv2D(128, (3, 3)))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\n\n# part1\nmodel.add(ZeroPadding2D((1,1)))\nmodel.add(Conv2D(256, (3, 3)))\nmodel.add(ZeroPadding2D((1,1)))\nmodel.add(Conv2D(256, (3, 3)))\nmodel.add(ZeroPadding2D((1,1)))\nmodel.add(Conv2D(256, (3, 3)))\nmodel.add(ZeroPadding2D((1,1)))\nmodel.add(Conv2D(256, (3, 3)))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\n# VGG 19 end\n\nmodel.add(Flatten())\n# model.add(Dense(512))\nmodel.add(Dense(8192))\nmodel.add(Activation(\"relu\"))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(number_of_classes, activation=\"softmax\"))\nmodel.compile(\n    optimizers.rmsprop(lr=0.0001, decay=1e-6),\n    loss=\"categorical_crossentropy\",\n    metrics=[\"accuracy\"],\n)\n\nprint(\"The model is ready\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a327641474e8e4f16db9425e2480df704c1b1670","trusted":false},"cell_type":"code","source":"# Fit the model @frommedium\n# https://medium.com/@vijayabhaskar96/tutorial-on-keras-flow-from-dataframe-1fd4493d237c\nSTEP_SIZE_TRAIN=train_generator.n//train_generator.batch_size\nSTEP_SIZE_VALID=valid_generator.n//valid_generator.batch_size\nSTEP_SIZE_TEST=test_generator.n//test_generator.batch_size\n# Class weights balancing\nhistory = model.fit_generator(\n    generator=train_generator,\n    steps_per_epoch=STEP_SIZE_TRAIN,\n    validation_data=valid_generator,\n    validation_steps=STEP_SIZE_VALID,\n    class_weight=\"auto\",\n    epochs=30,\n)\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"76c432630680af5db7238f8fdbfc6bc79aa53ab9","trusted":false},"cell_type":"code","source":"# history plots\nplt.plot(history.history['acc'])\nplt.title('Model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('Epoch')\nplt.show()\n\n# Plot the loss curve for training\nplt.plot(history.history['loss'], color='r', label=\"Train Loss\")\nplt.title(\"Train Loss\")\nplt.xlabel(\"Number of Epochs\")\nplt.ylabel(\"Loss\")\nplt.legend()\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c9293c3f6eeed1df370336320229ff3aa5a0e6c2","trusted":false},"cell_type":"code","source":"# Evaluate model\n# https://medium.com/@vijayabhaskar96/tutorial-on-keras-flow-from-dataframe-1fd4493d237c\nmodel.evaluate_generator(generator=valid_generator, steps=1)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"37449802e63496676480bc645c6dbb3f17c8e3c9","trusted":false},"cell_type":"code","source":"print(os.listdir(\".\"))","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"_uuid":"f1b92e7a9e0bc0f6130a092023943447137db546","trusted":false},"cell_type":"code","source":"# Predict the output\n# https://medium.com/@vijayabhaskar96/tutorial-on-keras-flow-from-dataframe-1fd4493d237c\n\ntest_generator.reset()\npred = model.predict_generator(test_generator, steps=STEP_SIZE_TEST + 1, verbose=1)\n\npredicted_class_indices = np.argmax(pred, axis=1)\n\nlabels = train_generator.class_indices\nlabels = dict((v, k) for k, v in labels.items())\npredictions = [labels[k] for k in predicted_class_indices]\n\nfilenames = test_generator.filenames\n\nprint(\"filenames were prepared\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8769dc3c129d44a3e1afe5f2c6d51714cf7f4bde","trusted":false},"cell_type":"code","source":"# multiple classes output\n# https://www.kaggle.com/hexadd5/simple-resnet50-with-keras\nkth = 5\nclasses = np.array([c for c, v in train_generator.class_indices.items()])\n\nif True:\n    classify_index = np.argpartition(-pred, kth)[:, :kth]\n    classify_value = pred[np.arange(pred.shape[0])[:, None], classify_index]\n    best_5_pred = np.zeros((len(classify_index), 5))\n    best_5_class = np.zeros((len(classify_index), 5), dtype='int32')\n    for i, p in enumerate(classify_value):\n        sort_index = np.argsort(p)[::-1]\n        best_5_pred[i] = (p[sort_index])\n        best_5_class[i] = (classify_index[i][sort_index])\n        \n    # create output\n    submit = pd.DataFrame(columns=['Image', 'Id'])\n    for i, p in enumerate(best_5_pred):\n        submit_classes = []\n        if p[0] < 0.55:\n            submit_classes.append('new_whale')\n            submit_classes.extend(classes[best_5_class[i]][0:4])\n        elif p[1] < 0.4 :\n            submit_classes.extend(classes[best_5_class[i]][0:1])\n            submit_classes.append('new_whale')\n            submit_classes.extend(classes[best_5_class[i]][1:4])\n        elif p[2] < 0.1 :\n            submit_classes.extend(classes[best_5_class[i]][0:2])\n            submit_classes.append('new_whale')\n            submit_classes.extend(classes[best_5_class[i]][2:4])\n        elif p[3] < 0.05 :\n            submit_classes.extend(classes[best_5_class[i]][0:3])\n            submit_classes.append('new_whale')\n            submit_classes.extend(classes[best_5_class[i]][3:4])\n        else:\n            submit_classes.extend(classes[best_5_class[i]])\n        classes_text = ' '.join(submit_classes)\n        submit = submit.append(pd.Series(np.array([test_generator.filenames[i], classes_text]), index=submit.columns), ignore_index=True)\n        # print(submit)\n    submit.to_csv('submit.csv', index=False)\n    print(\"submit results were written to the output\")","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}