{"cells":[{"cell_type":"markdown","metadata":{"_cell_guid":"d02af827-edda-3054-375f-c3fbfbbe53f6"},"source":"# Development notebook\n\n- data generator for Keras\n- random submission"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"ebc9ee4d-ccdb-f049-1ac8-8bc4488ced1a"},"outputs":[],"source":"import os \nfrom glob import glob\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport cv2\n\nimport matplotlib.pyplot as plt\n\nfrom keras.backend import set_image_dim_ordering, image_dim_ordering\n\nset_image_dim_ordering('th')\nprint(\"Image dim ordering : \", image_dim_ordering())"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"a1461181-304b-4fe8-112c-197dab930a6e"},"outputs":[],"source":"TRAIN_DATA = \"../input/train\"\nTEST_DATA = \"../input/test\"\nADDITIONAL_DATA = \"../input/additional\"\n\n\ntype_1_files = glob(os.path.join(TRAIN_DATA, \"Type_1\", \"*.jpg\"))\ntype_1_ids = np.array([s[len(os.path.join(TRAIN_DATA, \"Type_1\"))+1:-4] for s in type_1_files])\ntype_2_files = glob(os.path.join(TRAIN_DATA, \"Type_2\", \"*.jpg\"))\ntype_2_ids = np.array([s[len(os.path.join(TRAIN_DATA, \"Type_2\"))+1:-4] for s in type_2_files])\ntype_3_files = glob(os.path.join(TRAIN_DATA, \"Type_3\", \"*.jpg\"))\ntype_3_ids = np.array([s[len(os.path.join(TRAIN_DATA, \"Type_3\"))+1:-4] for s in type_3_files])\n\nadditional_type_1_files = glob(os.path.join(ADDITIONAL_DATA, \"Type_1\", \"*.jpg\"))\nadditional_type_1_ids = np.array([s[len(os.path.join(ADDITIONAL_DATA, \"Type_1\"))+1:-4] for s in additional_type_1_files])\nadditional_type_2_files = glob(os.path.join(ADDITIONAL_DATA, \"Type_2\", \"*.jpg\"))\nadditional_type_2_ids = np.array([s[len(os.path.join(ADDITIONAL_DATA, \"Type_2\"))+1:-4] for s in additional_type_2_files])\nadditional_type_3_files = glob(os.path.join(ADDITIONAL_DATA, \"Type_3\", \"*.jpg\"))\nadditional_type_3_ids = np.array([s[len(os.path.join(ADDITIONAL_DATA, \"Type_3\"))+1:-4] for s in additional_type_3_files])\n\ntest_files = glob(os.path.join(TEST_DATA, \"*.jpg\"))\ntest_ids = np.array([s[len(TEST_DATA)+1:-4] for s in test_files])"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"a0f5eddf-8cb8-6a0d-667a-efd618e030d3"},"outputs":[],"source":"def get_filename(image_id, image_type):\n    \"\"\"\n    Method to get image file path from its id and type   \n    \"\"\"\n    if image_type == \"Type_1\" or \\\n        image_type == \"Type_2\" or \\\n        image_type == \"Type_3\":\n        data_path = os.path.join(TRAIN_DATA, image_type)\n    elif image_type == \"Test\":\n        data_path = TEST_DATA\n    elif image_type == \"AType_1\" or \\\n          image_type == \"AType_2\" or \\\n          image_type == \"AType_3\":\n        data_path = os.path.join(ADDITIONAL_DATA, image_type)\n    else:\n        raise Exception(\"Image type '%s' is not recognized\" % image_type)\n\n    ext = 'jpg'\n    return os.path.join(data_path, \"{}.{}\".format(image_id, ext))\n\n\ndef get_image_data(image_id, image_type):\n    \"\"\"\n    Method to get image data as np.array specifying image id and type\n    \"\"\"\n    fname = get_filename(image_id, image_type)\n    img = cv2.imread(fname)\n    assert img is not None, \"Failed to read image : %s, %s\" % (image_id, image_type)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    return img"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"6cf918d9-10a4-0076-d52c-55f78660b202"},"outputs":[],"source":"type_to_index = {\n    \"Type_1\": 0,\n    \"Type_2\": 1,\n    \"Type_3\": 2,\n}\n\n\ndef data_iterator(image_id_type_list, batch_size, image_size, verbose=0, test_mode=False):\n    \n    while True:\n        X = np.zeros((batch_size, 3) + image_size, dtype=np.float32)\n        Y = np.zeros((batch_size, 3), dtype=np.uint8)\n        image_ids = np.empty((batch_size,), dtype=np.object)\n        counter = 0\n        for i, (image_id, image_type) in enumerate(image_id_type_list):\n            \n            img = get_image_data(image_id, image_type)\n            img = cv2.resize(img, dsize=image_size[::-1])\n            img = img.transpose([2,0,1])\n            img = img.astype(np.float32) / 255.0\n                        \n            X[counter, :, :, :] = img            \n            if test_mode:\n                image_ids[counter] = image_id\n            else:\n                Y[counter, type_to_index[image_type]] = 1    \n                \n            if verbose > 0:\n                print(\"Image id/type:\", image_id, image_type)\n            \n            counter += 1\n            if counter == batch_size:\n                yield (X, Y) if not test_mode else (X, Y, image_ids)\n                X = np.zeros((batch_size, 3) + image_size, dtype=np.float32)\n                Y = np.zeros((batch_size, 3), dtype=np.uint8)\n                image_ids = np.empty((batch_size,), dtype=np.object)\n                counter = 0\n        \n        if counter > 0:\n            X = X[:counter,:,:,:]\n            Y = Y[:counter,:]\n            image_ids = image_ids[:counter]\n            yield (X, Y) if not test_mode else (X, Y, image_ids)\n            \n        if test_mode:\n            break"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"3090c8b3-f1d9-30b4-85d2-a89ecb5a5c78"},"outputs":[],"source":"val_split=0.3\ntype_ids = [type_1_ids, type_2_ids, type_3_ids]\nimage_types = [\"Type_1\", \"Type_2\", \"Type_3\"]\ntrain_ll = [int(len(ids) * (1.0 - val_split)) for ids in type_ids]\nval_ll = [int(len(ids) * (val_split)) for ids in type_ids]\n\n\ncount = 0\ntrain_id_type_list = []\ntrain_ids = [ids[:l] for ids, l in zip(type_ids, train_ll)]\nmax_size = max(train_ll)\nwhile count < max_size:    \n    for l, ids, image_type in zip(train_ll, train_ids, image_types):    \n        image_id = ids[count % l]\n        train_id_type_list.append((image_id, image_type))\n    count += 1\n   \n\ncount = 0\nval_id_type_list = []\nval_ids = [ids[tl:tl+vl] for ids, tl, vl in zip(type_ids, train_ll, val_ll)]\nmax_size = max(val_ll)\nwhile count < max_size:    \n    for l, ids, image_type in zip(val_ll, val_ids, image_types):    \n        image_id = ids[count % l]\n        val_id_type_list.append((image_id, image_type))\n    count += 1\n\nassert len(set(train_id_type_list) & set(val_id_type_list)) == 0, \"WTF\" \n\n    \nprint(\"Train dataset contains : \")\nprint(\"-\", train_ll, \" images of corresponding types\")\nprint(\"Validation dataset contains : \")\nprint(\"-\", val_ll, \" images of corresponding types\")"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"696d4b4f-17bc-ce9d-4f46-cbb81fd12e60"},"outputs":[],"source":"image_size = (224, 224)\nbatch_size = 15\ntrain_iter = data_iterator(train_id_type_list, batch_size=batch_size, image_size=image_size, verbose=1)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"1202960d-1113-85a2-8211-142c8e020cc0"},"outputs":[],"source":"for X, Y in train_iter:\n    print(X.shape, X.dtype, Y.shape)\n    n = 5\n    for counter in range(batch_size):\n        if counter % n == 0:\n            plt.figure(figsize=(12, 4))\n        plt.subplot(1, n, counter % n + 1)\n        plt.imshow(X[counter, :, :, :].transpose([1, 2, 0]))\n        plt.title(\"Type : {}\".format(Y[counter,:]))\n        plt.axis('off')\n    \n    break"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"a24022e8-a665-e461-7fe3-e265ff75fdb7"},"outputs":[],"source":"image_size = (224, 224)\nbatch_size = 15\nval_iter = data_iterator(val_id_type_list, batch_size=batch_size, image_size=image_size, verbose=1)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"8a643e65-083f-1f60-f6ed-38881193a236"},"outputs":[],"source":"for X, Y in val_iter:\n    print(X.shape, X.dtype, Y.shape)\n    n = 5\n    for counter in range(batch_size):\n        if counter % n == 0:\n            plt.figure(figsize=(12, 4))\n        plt.subplot(1, n, counter % n + 1)\n        plt.imshow(X[counter, :, :, :].transpose([1, 2, 0]))\n        plt.title(\"Type : {}\".format(Y[counter,:]))\n        plt.axis('off')\n    \n    break"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"969725f8-a841-152f-6a3c-a5e8a6ed9e02"},"outputs":[],"source":""},{"cell_type":"markdown","metadata":{"_cell_guid":"248665e2-fb26-4052-7c78-eec07199d44c"},"source":"### Try ResNet from Keras applications"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"829aa560-ad9b-c46d-5c9f-16a399dea1c1"},"outputs":[],"source":"from keras.applications.resnet50 import ResNet50\nfrom keras.layers import Dense, Flatten\nfrom keras.models import Model\n\nimage_size = (224, 224)\n\nbase_model = ResNet50(include_top=False, weights=None, input_tensor=None, input_shape=(3,) + image_size)\nx = Flatten()(base_model.output)\noutput = Dense(3, activation='softmax')(x)\nmodel = Model(inputs=base_model.input, outputs=output)\nmodel.summary()"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"d1a0a8e3-5884-dec2-5850-d58a36d92e13"},"outputs":[],"source":"model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy',])"},{"cell_type":"markdown","metadata":{"_cell_guid":"91e407e4-79a5-8b65-76c3-e84625d228f9"},"source":"### Random predictions"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"fb5f6ad0-4f20-d665-1962-ec9df3e72de0"},"outputs":[],"source":"def logloss_mc(y_true, y_prob, epsilon=1e-15):\n    \"\"\" Multiclass logloss\n    This function is not officially provided by Kaggle, so there is no\n    guarantee for its correctness.\n    https://github.com/ottogroup/kaggle/blob/master/benchmark.py\n    \"\"\"\n    # normalize\n    y_prob = y_prob / y_prob.sum(axis=1).reshape(-1, 1)\n    y_prob = np.maximum(epsilon, y_prob)\n    y_prob = np.minimum(1 - epsilon, y_prob)\n    # get probabilities\n    y = [y_prob[i, j] for (i, j) in enumerate(y_true)]\n    ll = - np.mean(np.log(y))\n    return ll"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"ad86c7b9-085a-938c-07c0-3480eff2650a"},"outputs":[],"source":"batch_size = 16\nval_iter = data_iterator(val_id_type_list, batch_size=batch_size, image_size=image_size, test_mode=True)\n\ntotal_loss = 0.0\ntotal_counter = 0 \nfor X, Y_true, _ in val_iter:            \n    s = Y_true.shape[0]\n    total_counter += s\n    #Y_pred = model.predict(X)\n    Y_pred = 0.33333 * np.ones_like(Y_true)\n    loss = logloss_mc(Y_true, Y_pred)\n    print(\"--\", total_counter, \"batch loss : \", loss)\n    total_loss += s * loss\n\ntotal_loss *= 1.0 / total_counter   \nprint(\"Total loss : \", total_loss)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"9af7139d-0f3b-7c91-e55d-5f8733c4e91d"},"outputs":[],"source":"df = pd.DataFrame(columns=['image_name','Type_1','Type_2','Type_3'])\ndef get_test_id_type_list():\n    return [(image_id, 'Test') for image_id in test_ids]\n\nimage_size = (224, 224)\nbatch_size = 16\ntest_id_type_list = get_test_id_type_list()\ntest_iter = data_iterator(test_id_type_list, batch_size=batch_size, image_size=image_size, test_mode=True)\n\n\ndf = pd.DataFrame(columns=['image_name','Type_1','Type_2','Type_3'])\ntotal_counter = 0\nfor X, _, image_ids in test_iter:            \n    #Y_pred = model.predict(X)    \n    s = X.shape[0]\n    total_counter += s\n    Y_pred = 0.33333 * np.ones((s, 3))\n    print(\"--\", total_counter, image_ids)\n    for i in range(s):\n        df.loc[total_counter + i, :] = (image_ids[i] + '.jpg', ) + tuple(Y_pred[i, :])"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"fe93644a-8a18-7c80-08c7-6e399fdd49be"},"outputs":[],"source":"print(df.shape)\ndf.head()"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"eeefe47c-0567-7ee8-3995-751905183f74"},"outputs":[],"source":"import datetime\nnow = datetime.datetime.now()\ninfo = 'random_predictions'\nsub_file = 'submission_' + info + '_' + str(now.strftime(\"%Y-%m-%d-%H-%M\")) + '.csv'\ndf.to_csv(sub_file, index=False)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"a93b5287-f7f0-3aaa-6bbc-b65cb921299c"},"outputs":[],"source":"!ls "},{"cell_type":"markdown","metadata":{"_cell_guid":"5b5a3c1c-7712-3a9a-e4a9-600dd88b872c"},"source":"### Training phase\n\nStops by Kaggle server due to 1200 timeout "},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"46037148-008f-e031-9732-1755e1a121c1"},"outputs":[],"source":"batch_size=16\nsamples_per_epoch = 512\nnb_val_samples = 64\n\nprint(batch_size, samples_per_epoch, nb_val_samples)\n\ntrain_iter = data_iterator(train_id_type_list, batch_size=batch_size, image_size=image_size)\nval_iter = data_iterator(val_id_type_list, batch_size=batch_size, image_size=image_size)\n\n#history = model.fit_generator(\n#    train_iter,\n#    steps_per_epoch=samples_per_epoch, \n#    epochs=1,\n#    validation_data=val_iter,\n#    validation_steps=nb_val_samples,\n#    verbose=1\n#)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"6b4eb433-3a88-c08e-f717-eb1c3001b758"},"outputs":[],"source":""},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"24ac2241-1168-4b34-81e1-3e978404778b"},"outputs":[],"source":""}],"metadata":{"_change_revision":0,"_is_fork":false,"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.0"}},"nbformat":4,"nbformat_minor":0}