{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport re\nfrom glob import glob\nfrom tqdm import tqdm\nimport numpy as np\nimport pandas as pd\nimport ast\nimport matplotlib.pyplot as plt\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fnames = glob('../input/quickdraw-doodle-recognition/train_simplified/*.csv')\ncnames = ['countrycode', 'drawing', 'key_id', 'recognized', 'timestamp', 'word']\ndrawlist = []\nfor f in fnames[0:6]:\n    first = pd.read_csv(f, nrows=10) # make sure we get a recognized drawing\n    first = first[first.recognized==True].head(2)\n    drawlist.append(first)\ndraw_df = pd.DataFrame(np.concatenate(drawlist), columns=cnames)\ndraw_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"evens = range(0,11,2)\nodds = range(1,12, 2)\ndf1 = draw_df[draw_df.index.isin(evens)]\ndf2 = draw_df[draw_df.index.isin(odds)]\n\nexample1s = [ast.literal_eval(pts) for pts in df1.drawing.values]\nexample2s = [ast.literal_eval(pts) for pts in df2.drawing.values]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = df2.word.tolist()\nfor i, example in enumerate(example1s):\n    plt.figure(figsize=(6,3))\n    \n    for x,y in example:\n        plt.subplot(1,2,1)\n        plt.plot(x, y, marker='.')\n        plt.axis('off')\n\n    for x,y, in example2s[i]:\n        plt.subplot(1,2,2)\n        plt.plot(x, y, marker='.')\n        plt.axis('off')\n        label = labels[i]\n        plt.title(label, fontsize=10)\n\n    plt.show()  ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # commented out to save memory\n# import urllib\n\n# LABELS = np.array(['baseball', 'bowtie', 'clock', 'hand', 'hat'])\n# for b in LABELS:\n#     url = \"https://storage.googleapis.com/quickdraw_dataset/full/numpy_bitmap/{}.npy\".format(b)\n#     urllib.request.urlretrieve(url, \"{}.npy\".format(b))\n#     nb = np.load(\"{}.npy\".format(b))\n#     print(\"\\n Class '{0}' has {1} examples of {2}x{2} images\".format(b, nb.shape[0], int(nb.shape[1]**0.5)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#%% import\nimport os\nfrom glob import glob\nimport re\nimport ast\nimport numpy as np \nimport pandas as pd\nfrom PIL import Image, ImageDraw \nfrom tqdm import tqdm\nfrom dask import bag\n\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout, Flatten\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D\nfrom tensorflow.keras.metrics import top_k_categorical_accuracy\nfrom tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#%% set label dictionary and params\nclassfiles = os.listdir('../input/quickdraw-doodle-recognition/train_simplified/')\nnumstonames = {i: v[:-4].replace(\" \", \"_\") for i, v in enumerate(classfiles)} #adds underscores\n\nnum_classes = 340    #340 max \nimheight, imwidth = 32, 32  \nims_per_class = 2000  #max?","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# faster conversion function\ndef draw_it(strokes):\n    image = Image.new(\"P\", (256,256), color=255)\n    image_draw = ImageDraw.Draw(image)\n    for stroke in ast.literal_eval(strokes):\n        for i in range(len(stroke[0])-1):\n            image_draw.line([stroke[0][i], \n                             stroke[1][i],\n                             stroke[0][i+1], \n                             stroke[1][i+1]],\n                            fill=0, width=5)\n    image = image.resize((imheight, imwidth))\n    return np.array(image)/255.\n\n#%% get train arrays\ntrain_grand = []\nclass_paths = glob('../input/quickdraw-doodle-recognition/train_simplified/*.csv')\nfor i,c in enumerate(tqdm(class_paths[0: num_classes])):\n    train = pd.read_csv(c, usecols=['drawing', 'recognized'], nrows=ims_per_class*5//4)\n    train = train[train.recognized == True].head(ims_per_class)\n    imagebag = bag.from_sequence(train.drawing.values).map(draw_it) \n    trainarray = np.array(imagebag.compute())  # PARALLELIZE\n    trainarray = np.reshape(trainarray, (ims_per_class, -1))    \n    labelarray = np.full((train.shape[0], 1), i)\n    trainarray = np.concatenate((labelarray, trainarray), axis=1)\n    train_grand.append(trainarray)\n    \ntrain_grand = np.array([train_grand.pop() for i in np.arange(num_classes)]) #less memory than np.concatenate\ntrain_grand = train_grand.reshape((-1, (imheight*imwidth+1)))\n\ndel trainarray\ndel train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# memory-friendly alternative to train_test_split?\nvalfrac = 0.1\ncutpt = int(valfrac * train_grand.shape[0])\n\nnp.random.shuffle(train_grand)\ny_train, X_train = train_grand[cutpt: , 0], train_grand[cutpt: , 1:]\ny_val, X_val = train_grand[0:cutpt, 0], train_grand[0:cutpt, 1:] #validation set is recognized==True\n\ndel train_grand\n\ny_train = keras.utils.to_categorical(y_train, num_classes)\nX_train = X_train.reshape(X_train.shape[0], imheight, imwidth, 1)\ny_val = keras.utils.to_categorical(y_val, num_classes)\nX_val = X_val.reshape(X_val.shape[0], imheight, imwidth, 1)\n\nprint(y_train.shape, \"\\n\",\n      X_train.shape, \"\\n\",\n      y_val.shape, \"\\n\",\n      X_val.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(Conv2D(32, kernel_size=(3, 3), padding='same', activation='relu', input_shape=(imheight, imwidth, 1)))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Conv2D(64, kernel_size=(3, 3), padding='same', activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.2))\nmodel.add(Flatten())\nmodel.add(Dense(680, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(num_classes, activation='softmax'))\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def top_3_accuracy(x,y): \n    t3 = top_k_categorical_accuracy(x,y, 3)\n    return t3\n\nreduceLROnPlat = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3, \n                                   verbose=1, mode='auto', min_delta=0.005, cooldown=5, min_lr=0.0001)\nearlystop = EarlyStopping(monitor='val_top_3_accuracy', mode='max', patience=5) \ncallbacks = [reduceLROnPlat, earlystop]\n\nmodel.compile(loss='categorical_crossentropy',\n              optimizer='adam',\n              metrics=['accuracy', top_3_accuracy])\n\nmodel.fit(x=X_train, y=y_train,\n          batch_size = 32,\n          epochs = 22,\n          validation_data = (X_val, y_val),\n          callbacks = callbacks,\n          verbose = 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#%% get test set\nttvlist = []\nreader = pd.read_csv('../input/quickdraw-doodle-recognition/test_simplified.csv', index_col=['key_id'],\n    chunksize=2048)\nfor chunk in tqdm(reader, total=55):\n    imagebag = bag.from_sequence(chunk.drawing.values).map(draw_it)\n    testarray = np.array(imagebag.compute())\n    testarray = np.reshape(testarray, (testarray.shape[0], imheight, imwidth, 1))\n    testpreds = model.predict(testarray, verbose=0)\n    ttvs = np.argsort(-testpreds)[:, 0:3]  # top 3\n    ttvlist.append(ttvs)\n    \nttvarray = np.concatenate(ttvlist)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds_df = pd.DataFrame({'first': ttvarray[:,0], 'second': ttvarray[:,1], 'third': ttvarray[:,2]})\npreds_df = preds_df.replace(numstonames)\npreds_df['words'] = preds_df['first'] + \" \" + preds_df['second'] + \" \" + preds_df['third']\n\nsub = pd.read_csv('../input/quickdraw-doodle-recognition/sample_submission.csv', index_col=['key_id'])\nsub['word'] = preds_df.words.values\nsub.to_csv('subcnn_small.csv')\nsub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import sys\n\n# These are the usual ipython objects, including this one you are creating\nipython_vars = ['In', 'Out', 'exit', 'quit', 'get_ipython', 'ipython_vars']\n\n# Get a sorted list of the objects and their sizes\nsorted([(x, sys.getsizeof(globals().get(x))) for x in dir() if not \n    x.startswith('_') and x not in sys.modules and x \n    not in ipython_vars], key=lambda x: x[1], reverse=True)","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":1}