{"cells":[{"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\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 read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nsns.set(style='white', context='notebook')\n\nnp.random.seed(36)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Deep Learning Packages","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import ast\nimport cv2\nimport dask.bag as db\n\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D, MaxPool2D, Flatten, Dense, Dropout\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau \n\nfrom keras.applications.resnet50 import ResNet50\nfrom tensorflow.keras.applications.vgg19 import VGG19","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Loading Data","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Since the file is very huge we are taking only 50 animals as sample","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# list of animals \nanimals = ['ant', 'bat', 'bear', 'bee', 'bird', 'butterfly', 'camel', 'cat', 'cow',\n           'crab', 'crocodile', 'dog', 'dolphin', 'dragon', 'duck', 'elephant', 'fish',\n           'flamingo', 'frog', 'giraffe', 'hedgehog', 'horse', 'kangaroo', 'lion',\n           'lobster', 'monkey', 'mosquito', 'mouse', 'octopus', 'owl', 'panda',\n           'parrot', 'penguin', 'pig', 'rabbit', 'raccoon', 'rhinoceros', 'scorpion',\n           'sea turtle', 'shark', 'sheep', 'snail', 'snake', 'spider', 'squirrel',\n           'swan', 'teddy-bear', 'tiger', 'whale', 'zebra']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Taking only one animal from the list to analyze the columns.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"dir_path='/kaggle/input/quickdraw-doodle-recognition/train_simplified/'\ndf = pd.read_csv(dir_path + animals[0] + '.csv')\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Important Features\n* Drawing is the stroke values, which is telling the drawing of animals.We need to exchage this data into image data\n* Recognized is whether it recognized a drawing.\n* word indicates the result of drawings or animals","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"We are taking 100 rows per animal and only taking recognized images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"am = pd.DataFrame(columns = df.columns)\n\nfor i in range(len(animals)):\n    filename = dir_path + animals[i] + '.csv'\n    df = pd.read_csv(filename, nrows = 100)\n    df = df[df.recognized == True]\n    am = am.append(df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"am.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"am.word.nunique()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"As we can see there are 50 unique animals","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Visulizing the Drawings","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"* Let's See how people drew animals.\n*  The image information can be found at drawing but in order to make it visual, we need some steps of processing. \n* Let's take only 100 data for an example.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Sampling only 100 examples\nex = am.sample(100)\n# Convert to list as drawing columns is in strings\nex['drawing'] = ex.drawing.map(ast.literal_eval)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Plotting Sample 100 Strokes ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, axs = plt.subplots(nrows = 10, ncols = 10, figsize = (10, 8))\n\nfor index, col in enumerate(ex.drawing):\n    ax = axs[index//10, index%10]\n    for x, y in col:\n        ax.plot(x,-np.array(y), lw = 3)\n    ax.axis('off')\n    \nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Strokes to Images\n*  The data isn't in the form of image data.\n* We have to covert it into numpy array format","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"im_size = 64\nn_class = len(animals)\n\n# redefine\ndef draw_to_img(strokes, im_size = im_size):\n    fig, ax = plt.subplots()                        # plot the drawing as we did above\n    for x, y in strokes:\n        ax.plot(x, -np.array(y), lw = 10)\n    ax.axis('off')\n    \n    fig.canvas.draw()                               # update a figure that has been altered\n    A = np.array(fig.canvas.renderer._renderer)     # converting them into array\n    \n    plt.close('all')\n    plt.clf()\n    \n    A = (cv2.resize(A, (im_size, im_size)) / 255.)  # image resizing to uniform format\n\n    return A[:, :, :3]        ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Check the function with one image","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"X = ex.drawing.values\nimage = draw_to_img(X[1])\nplt.imshow(image)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Checking shape","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"image.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We can apply for these methods for our entire dataset.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"im_size = 64\nn_class = len(animals)\nn_samples = 500\nX_train = np.zeros((1, im_size, im_size, 3))\ny = []\n\nfor a in animals:\n    #print(a)\n    filename = dir_path + a + '.csv'\n    df = pd.read_csv(filename, usecols=['drawing', 'word'], nrows=n_samples)  # import the data in chunks\n    df['drawing'] = df.drawing.map(ast.literal_eval)                          # convert strings into list\n    X = df.drawing.values\n    \n    img_bag = db.from_sequence(X).map(draw_to_img)                            # covert strokes into array\n    X = np.array(img_bag.compute())  \n    X_train = np.vstack((X_train, X))                                         # concatenate to get X_train  \n    \n    y.append(df.word)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Drop the first layer\nX_train = X_train[1:, :, :, :]\nX_train.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Encoding \ny = pd.DataFrame(y)\ny = pd.get_dummies(y)\ny_train = np.array(y).transpose()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Training data\nprint(\"The input shape is {}\".format(X_train.shape))\nprint(\"The output shape is {}\".format(y_train.shape))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train[0][1][2]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Now let's combine the X_train and y_train again. This is for splitting the data into the trainning set and validation set.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Reshape X_train\nX_train_2 = X_train.reshape((X_train.shape[0], im_size*im_size*3))\n\n# Concatenate X_train and y_train\nX_y_train = np.hstack((X_train_2, y_train))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Sepearting train and validation set","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Random shuffle\nnp.random.shuffle(X_y_train)\na = im_size*im_size*3\ncut = int(len(X_y_train) * .1)\nX_val = X_y_train[:cut, :a]\ny_val = X_y_train[:cut, a:]\nX_train = X_y_train[cut:, :a]\ny_train = X_y_train[cut:, a:]\n\n# Reshape X_train back to (64, 64)\nX_train = X_train.reshape((X_train.shape[0], im_size, im_size, 3))\nX_val = X_val.reshape((X_val.shape[0], im_size, im_size, 3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#final Shape\nprint(\"The input shape of train set is {}\".format(X_train.shape))\nprint(\"The input shape of validation set is {}\".format(X_val.shape))\nprint(\"The output shape of train set is {}\".format(y_train.shape))\nprint(\"The output shape of validation set is {}\".format(y_val.shape))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# CNN Base Model.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"n_epochs = 10\nbatch_size = 500\n\n# Initialize\nmodel = Sequential()\n\n# ConvNet_1\nmodel.add(Conv2D(32, kernel_size = 3, input_shape = (im_size, im_size, 3), padding = 'same', activation = 'relu'))\nmodel.add(MaxPool2D(2, strides = 2))\n# Dropout\nmodel.add(Dropout(.2))\n\n# ConvNet_2\nmodel.add(Conv2D(64, kernel_size = 3, activation = 'relu'))\nmodel.add(MaxPool2D(2, strides = 2))\n# Dropout\nmodel.add(Dropout(.2))\n\n# ConvNet_3\nmodel.add(Conv2D(64, kernel_size = 3, activation = 'relu'))\nmodel.add(MaxPool2D(2, strides = 2))\n# Dropout\nmodel.add(Dropout(.2))\n\n# Flattening\nmodel.add(Flatten())\n\n# Fully connected\nmodel.add(Dense(680, activation = 'relu'))\n\n# Dropout\nmodel.add(Dropout(.5))\n\n# Final layer\nmodel.add(Dense(n_class, activation = 'softmax'))\n\n# Compile\nmodel.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Fitting baseline\nhistory = model.fit(X_train, y_train, epochs = n_epochs, batch_size = batch_size, \n                    validation_split = .2, verbose = True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Modeling with ResNet50","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"It's seem not good. Let's try other pre-trained model.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# ResNet50 Application \nmodel_r = ResNet50(include_top = True, weights= None, input_shape=(im_size, im_size, 3), classes = n_class)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_r.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])\nmodel_r.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"n_epochs = 5\nbatch_size = 50","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Fitting ResNet50\nhistory_r = model_r.fit(X_train, y_train, epochs = n_epochs, batch_size = batch_size, \n                      validation_split = .2, verbose = True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Train and validation curves with ResNet50\nfig, (ax1, ax2) = plt.subplots(2, 1)\nax1.plot(history_r.history['loss'], color = 'b', label = 'Train Loss')\nax1.plot(history_r.history['val_loss'], color = 'm', label = 'Valid Loss')\nax1.legend(loc = 'best')\n\nax2.plot(history_r.history['acc'], color = 'b', label = 'Train Accuracy')\nax2.plot(history_r.history['val_acc'], color = 'm', label = 'Valid Accuracy')\nax2.legend(loc = 'best')","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}