{"cells":[{"metadata":{"_uuid":"c33c9d9187ac8b5c59b5c46bde879fabbd095e78"},"cell_type":"markdown","source":"# Convnet Baseline\nThis is a simple baseline which converts strokes to matplotlib figure and from there we convert it to numpy arrays. Finally the arrays are threated as images and feed into ConvNets."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport matplotlib.pyplot as plt\nimport os\n# import multiprocessing\nimport cv2\nimport math\n\nfrom keras.applications import MobileNet\nfrom keras.losses import sparse_categorical_crossentropy\nfrom tqdm import trange\nplt.rcParams[\"figure.max_open_warning\"] = 300","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2eb4f037832e5a498350a27de0270f51e631f110"},"cell_type":"code","source":"def strokes_to_img(in_strokes):\n    in_strokes = eval(in_strokes)\n    # make an agg figure\n    fig, ax = plt.subplots()\n    for x,y in in_strokes:\n        ax.plot(x, y, linewidth=12.) #  marker='.',\n    ax.axis('off')\n    fig.canvas.draw()\n    \n    # grab the pixel buffer and dump it into a numpy array\n    X = np.array(fig.canvas.renderer._renderer)\n    plt.close(fig)\n    return (cv2.resize(X, (96, 96)) / 255.)[::-1]\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e967b975913488c91b8685f61a0b96f7212c51b1"},"cell_type":"code","source":"class_files = os.listdir(\"../input/train_simplified/\")\nclasses = {x[:-4]:i for i, x in enumerate(class_files)}\nto_class = {i:x[:-4].replace(\" \", \"_\") for i, x in enumerate(class_files)}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c90069a4b0600bdd177a44df778665ed577cf71f"},"cell_type":"code","source":"dfs = [pd.read_csv(\"../input/train_simplified/\" + x, nrows=10000)[[\"word\", \"drawing\"]] for x in class_files]\ndf = pd.concat(dfs)\ndel dfs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7b8a180f7844e88d1509e28251e574d4cfb6d452"},"cell_type":"code","source":"# mppool = multiprocessing.Pool(6)\nn_samples = df.shape[0]\nbatch_size = 64\n\npick_order = np.arange(n_samples)\npick_per_epoch = n_samples // batch_size\n\ndef train_gen():\n    while True:  # Infinity loop\n        np.random.shuffle(pick_order)\n        for i in range(pick_per_epoch):\n            c_pick = pick_order[i*batch_size: (i+1)*batch_size]\n            dfs = df.iloc[c_pick]\n            out_imgs = list(map(strokes_to_img, dfs[\"drawing\"]))\n            X = np.array(out_imgs)[:, :, :, :3].astype(np.float32)\n            y = np.array([classes[x] for x in dfs[\"word\"]])\n            yield X, y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f5120e3eaa00e978bd2fbfd12f30807be384c734"},"cell_type":"code","source":"tran_datagen = train_gen()\nx,y = next(tran_datagen)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0db10929dca20a5418e1f476aeec012789fc61c8"},"cell_type":"code","source":"# Display some images\nfor i in range(12):\n    plt.subplot(2,6,i+1)\n    plt.imshow(x[i])\n    plt.axis('off')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d11956f02c12475c6687c49b10e5fc2f2ee191a1"},"cell_type":"code","source":"model = MobileNet(input_shape=(96, 96, 3), weights=None, classes=len(classes))\nmodel.compile(optimizer=\"adam\", loss=sparse_categorical_crossentropy)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"668a140ab7971c37a5a8cc823fbe538e2f4b7326"},"cell_type":"code","source":"model.fit_generator(tran_datagen, steps_per_epoch=20, epochs=5, verbose=1)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cde7f45a9d978dc525fb227c64d1bd2b1b038007"},"cell_type":"code","source":"del tran_datagen\ndel df\n\nimport gc\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6eb43d04afaa846efca3fbfe83eee4469ba8fb2d"},"cell_type":"markdown","source":"# Eval"},{"metadata":{"trusted":true,"_uuid":"1d4f255c93628441b7104c3cc1c002020aa7e82b"},"cell_type":"code","source":"test_df = pd.read_csv(\"../input/test_simplified.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1325888d2407dbaac7923864ca77302689f3879b"},"cell_type":"code","source":"n_samples = test_df.shape[0]\npick_per_epoch = math.ceil(n_samples / batch_size)\npick_order = np.arange(test_df.shape[0])\n\nall_preds = []\n\nfor i in trange(pick_per_epoch):\n        c_pick = pick_order[i*batch_size: (i+1)*batch_size]\n        dfs = test_df.iloc[c_pick]\n        out_imgs = list(map(strokes_to_img, dfs[\"drawing\"]))\n        X = np.array(out_imgs)[:, :, :, :3].astype(np.float32)\n        preds = model.predict(X)\n        for x in preds:\n            all_preds.append(to_class[np.argmax(x)])\n        if i == 50:  # TODO: let it run till completion\n            break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"371c257c0cbb803eb1a0bce50c781c6fa70d8161"},"cell_type":"code","source":"fdf = pd.DataFrame({\"key_id\": test_df[\"key_id\"], \"word\": all_preds + ([\"\"] * (test_df.shape[0] - len(all_preds)))})  # TODO: No need to kill it early\nfdf.to_csv(\"mobilenet_submit.csv\", index=False)","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}