{"cells":[{"metadata":{"_uuid":"2ac4ab8c6f7f1d1f47e031f85841bf7b98b6456b"},"cell_type":"markdown","source":"I used this [code](https://www.kaggle.com/keegil/keras-u-net-starter-lb-0-277) for U_net"},{"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 in \n\nimport os\nimport sys\nimport random\nimport warnings\n\nimport numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\n\nfrom tqdm import tqdm\nfrom itertools import chain\nfrom skimage.io import imshow, imread_collection, concatenate_images, imread\nfrom matplotlib.pyplot import imread\nfrom skimage.transform import resize\nfrom skimage.morphology import label\n\nfrom tensorflow.python.keras.models import load_model\nfrom tensorflow.python.keras.callbacks import EarlyStopping, ModelCheckpoint\n\nfrom tensorflow.python.keras.layers import Input, Conv2D,Dropout,MaxPooling2D,Lambda,Conv2DTranspose\nfrom tensorflow.python.keras import backend as K\nfrom tensorflow.python.keras.layers.merge import concatenate as Concatenate\nfrom tensorflow.python.keras import Model\nimport numpy as np\nimport tensorflow as tf\nimport cv2\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c47cf2ab8fcfaf492259b675e2391c056859f9fb"},"cell_type":"code","source":"# Set some parameters\nIMG_WIDTH = 128\nIMG_HEIGHT = 128\nIMG_CHANNELS = 3\nTRAIN_PATH = '../input/stage1_train/'\nTEST_PATH = '../input/stage2_test_final/'\n# TEST_PATH = '../input/stage1_test/'\n\nwarnings.filterwarnings('ignore', category=UserWarning, module='skimage')\nseed = 42\nrandom.seed = seed\nnp.random.seed = seed","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"722c35aa7d2aea6010e9ecc19366c47105962479"},"cell_type":"markdown","source":"## load image data\n\nII used this code\nfrom https://www.kaggle.com/keegil/keras-u-net-starter-lb-0-277"},{"metadata":{"trusted":true,"_uuid":"b5403ff4a7022adf518264b90e24142992f0338b"},"cell_type":"code","source":"\n# Get train and test IDs\ntrain_ids = next(os.walk(TRAIN_PATH))[1] # os.walk 하위 디렉토리 검색\ntest_ids = next(os.walk(TEST_PATH))[1]\nprint(\"train length : \", len(train_ids))\nprint(\"test length : \", len(test_ids))\nX_train=np.zeros((len(train_ids), IMG_HEIGHT,IMG_WIDTH,IMG_CHANNELS),dtype=np.uint8)\nY_train=np.zeros((len(train_ids),IMG_HEIGHT,IMG_WIDTH,1), dtype=np.bool)\n\nprint('Getting and resizing train images and masks ... ')\nsys.stdout.flush() \nfor n,id_ in tqdm(enumerate(train_ids), total=len(train_ids)):\n    path=TRAIN_PATH+id_\n\n    img=imread(path+\"/images/\"+id_+'.png')[:,:,:IMG_CHANNELS]\n    img=resize(img, (IMG_HEIGHT,IMG_WIDTH), mode=\"constant\",preserve_range=True)\n    X_train[n]=img\n    mask=np.zeros((IMG_HEIGHT,IMG_WIDTH,1),dtype=np.bool)\n    for mask_file in next(os.walk(path+\"/masks/\"))[2]:\n        mask_=imread(path+\"/masks/\"+mask_file)\n        mask_=np.expand_dims(resize(mask_,(IMG_HEIGHT,IMG_WIDTH),mode=\"constant\",preserve_range=True),axis=-1)\n        mask=np.maximum(mask,mask_) # ?\n    Y_train[n]=mask\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"bef1e36de14a2485fc8cbb8bf93aaf44850d7084"},"cell_type":"code","source":"# Get and resize test images\nX_test = np.zeros((len(test_ids), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)\nsizes_test = []\nprint('Getting and resizing test images ... ')\nsys.stdout.flush()\nfor n, id_ in tqdm(enumerate(test_ids), total=len(test_ids)):\n    path = TEST_PATH + id_\n    print(\"n {}, id {}\".format(n,id_))\n    print(os.path.exists(path + '/images/' + id_ + '.png'))\n    try :\n        img = imread(path + '/images/' + id_ + '.png')\n        if len(img.shape)!=3: continue\n    except:\n        continue\n    img=img[:,:,:IMG_CHANNELS] # wrong png file\n    \n    print(\"n {}, id {} shape {}\".format(n,id_,img.shape))\n\n    #img = imread(path + '/images/' + id_ + '.png')[:,:,:IMG_CHANNELS]\n    sizes_test.append([img.shape[0], img.shape[1]])\n    img = resize(img, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)\n    X_test[n] = img\n    \nprint(\"X_test num : \",len(X_test))\nprint('Done!')","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"# Check if training data looks all right\nix = random.randint(0, len(train_ids))\nimshow(X_train[ix])\nplt.show()\nimshow(np.squeeze(Y_train[ix]))\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"60a913f158cbf79ceb5cfb2ff775b2f3abb3e8af"},"cell_type":"code","source":"# Define IoU metric\ndef mean_iou(y_true, y_pred):\n    prec = []\n    for t in np.arange(0.5, 1.0, 0.05):\n        y_pred_ = tf.to_int32(y_pred > t)\n        score, up_opt = tf.metrics.mean_iou(y_true, y_pred_, 2)\n        K.get_session().run(tf.local_variables_initializer())\n        with tf.control_dependencies([up_opt]):\n            score = tf.identity(score)\n        prec.append(score)\n    return K.mean(K.stack(prec), axis=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"66cf77af2c2a77b878feb8b6a5d1e830b3e04504"},"cell_type":"code","source":"def U_net(inputs):\n    \"\"\"\n    \n    :param inputs: train data\n    :return:\n    \"\"\"\n    input_shape=inputs[0].shape\n    inputs=Input(input_shape)\n    s=Lambda(lambda  x : x/255)(inputs)\n\n    c1=Conv2D(16,(3,3), activation=\"elu\", kernel_initializer=\"he_normal\",padding=\"same\")(s)\n    c1=Dropout(0.1)(c1)\n    c1=Conv2D(24,(3,3),activation='elu', kernel_initializer=\"he_normal\",padding=\"same\")(c1)\n    p1=MaxPooling2D((2,2))(c1)\n\n    c2=Conv2D(32,(3,3), activation=\"elu\", kernel_initializer=\"he_normal\",padding=\"same\")(p1)\n    c2=Dropout(0.1)(c2)\n    c2=Conv2D(48,(3,3),activation='elu', kernel_initializer=\"he_normal\",padding=\"same\")(c2)\n    p2=MaxPooling2D((2,2))(c2)\n\n    c3=Conv2D(64,(3,3), activation=\"elu\", kernel_initializer=\"he_normal\",padding=\"same\")(p2)\n    c3=Dropout(0.1)(c3)\n    c3=Conv2D(96,(3,3),activation='elu', kernel_initializer=\"he_normal\",padding=\"same\")(c3)\n    p3=MaxPooling2D((2,2))(c3)\n\n    c4=Conv2D(128,(3,3), activation=\"elu\", kernel_initializer=\"he_normal\",padding=\"same\")(p3)\n    c4=Dropout(0.1)(c4)\n    c4=Conv2D(192,(3,3),activation='elu', kernel_initializer=\"he_normal\",padding=\"same\")(c4)\n    p4=MaxPooling2D((2,2))(c4)\n\n    c5 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(p4)\n    c5 = Dropout(0.3)(c5)\n    c5 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c5)\n\n    u6=Conv2DTranspose(128,(2,2),strides=(2,2),activation=\"elu\", kernel_initializer=\"he_normal\", padding=\"same\")(c5)\n    u6=Concatenate([u6,c4])\n    c6=Conv2D(128,(3,3),activation=\"elu\",kernel_initializer=\"he_normal\",padding=\"same\")(u6)\n    c6=Dropout(0.2)(c6)\n    c6=Conv2D(128, (3,3),activation=\"elu\", kernel_initializer=\"he_normal\",padding=\"same\")(c6)\n\n    u7 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(c6)\n    u7 = Concatenate([u7, c3])\n    c7 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(u7)\n    c7 = Dropout(0.2)(c7)\n    c7 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c7)\n\n    u8 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same')(c7)\n    u8 = Concatenate([u8, c2])\n    c8 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(u8)\n    c8 = Dropout(0.1)(c8)\n    c8 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c8)\n\n    u9 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same')(c8)\n    u9 = Concatenate([u9, c1], axis=3)\n    c9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(u9)\n    c9 = Dropout(0.1)(c9)\n    c9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c9)\n\n    outputs=Conv2D(1,(1,1), activation='sigmoid')(c9)\n\n    model=Model(inputs, outputs)\n    model.compile(optimizer='adam', loss=\"binary_crossentropy\", metrics=[mean_iou])\n    model.summary()\n\n    return model","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3149b3cb7f90708c5b1ad3fb7e73964608f92212"},"cell_type":"markdown","source":"## U_net and Pyramid network\n\n![pyramid](https://camo.githubusercontent.com/e292aae383716144da11180a462d26a932be4712/68747470733a2f2f68737a68616f2e6769746875622e696f2f70726f6a656374732f7073706e65742f666967757265732f7073706e65742e706e67)\n\npyramid network has variable size of filters. And it helps model capture global context.\n\nreference : https://arxiv.org/pdf/1612.01105.pdf\n\n"},{"metadata":{"trusted":true,"_uuid":"e4a8d3dee40e3d9b9550551d350da4ffecb8ee3d"},"cell_type":"code","source":"def U_net_pyramid(inputs):\n\n    \"\"\"\n    piramid network 추가\n    :param inputs: train data\n    :return:\n    \"\"\"\n    input_shape=inputs[0].shape\n    inputs=Input(input_shape)\n    s=Lambda(lambda  x : x/255)(inputs)\n\n    c1=Conv2D(16,(3,3), activation=\"elu\", kernel_initializer=\"he_normal\",padding=\"same\")(s)\n    c1=Dropout(0.1)(c1)\n    c1_s=Conv2D(8,(1,1),activation='elu', kernel_initializer=\"he_normal\",padding=\"same\")(c1) # pyramid\n    c1_m=Conv2D(8,(3,3),activation='elu', kernel_initializer=\"he_normal\",padding=\"same\")(c1)  # pyramid\n    c1_l = Conv2D(8, (5, 5), activation='elu', kernel_initializer=\"he_normal\", padding=\"same\")(c1)  # pyramid\n    c1=Concatenate([c1_s,c1_m,c1_l])\n    p1=MaxPooling2D((2,2))(c1)\n\n    c2=Conv2D(32,(3,3), activation=\"elu\", kernel_initializer=\"he_normal\",padding=\"same\")(p1)\n    c2=Dropout(0.1)(c2)\n    c2_s = Conv2D(16, (1,1), activation='elu', kernel_initializer=\"he_normal\", padding=\"same\")(c2)  # pyramid\n    c2_m = Conv2D(16, (3,3), activation='elu', kernel_initializer=\"he_normal\", padding=\"same\")(c2)  # pyramid\n    c2_l = Conv2D(16, (5, 5), activation='elu', kernel_initializer=\"he_normal\", padding=\"same\")(c2)   # pyramid\n    c2 = Concatenate([c2_s, c2_m, c2_l])\n    p2=MaxPooling2D((2,2))(c2)\n\n    c3=Conv2D(64,(3,3), activation=\"elu\", kernel_initializer=\"he_normal\",padding=\"same\")(p2)\n    c3=Dropout(0.1)(c3)\n    c3_s = Conv2D(32, (1,1), activation='elu', kernel_initializer=\"he_normal\", padding=\"same\")(c3)  # pyramid\n    c3_m = Conv2D(32, (3,3), activation='elu', kernel_initializer=\"he_normal\", padding=\"same\")(c3)  # pyramid\n    c3_l = Conv2D(32, (5, 5), activation='elu', kernel_initializer=\"he_normal\", padding=\"same\")(c3)  # pyramid\n    c3 = Concatenate([c3_s, c3_m, c3_l])\n    p3=MaxPooling2D((2,2))(c3)\n\n    c4=Conv2D(128,(3,3), activation=\"elu\", kernel_initializer=\"he_normal\",padding=\"same\")(p3)\n    c4=Dropout(0.1)(c4)\n    c4_s = Conv2D(64, (1,1), activation='elu', kernel_initializer=\"he_normal\", padding=\"same\")(c4)  # pyramid\n    c4_m = Conv2D(64, (3,3), activation='elu', kernel_initializer=\"he_normal\", padding=\"same\")(c4)  # pyramid\n    c4_l = Conv2D(64, (5, 5),activation='elu', kernel_initializer=\"he_normal\", padding=\"same\")(c4)  # pyramid\n    c4 = Concatenate([c4_s, c4_m, c4_l])\n    p4=MaxPooling2D((2,2))(c4)\n\n    c5 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(p4)\n    c5 = Dropout(0.3)(c5)\n    c5 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c5)\n\n    u6=Conv2DTranspose(128,(2,2),strides=(2,2),activation=\"elu\", kernel_initializer=\"he_normal\", padding=\"same\")(c5)\n    u6=Concatenate([u6,c4])\n    c6=Conv2D(128,(3,3),activation=\"elu\",kernel_initializer=\"he_normal\",padding=\"same\")(u6)\n    c6=Dropout(0.2)(c6)\n    c6=Conv2D(128, (3,3),activation=\"elu\", kernel_initializer=\"he_normal\",padding=\"same\")(c6)\n\n    u7 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(c6)\n    u7 = Concatenate([u7, c3])\n    c7 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(u7)\n    c7 = Dropout(0.2)(c7)\n    c7 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c7)\n\n    u8 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same')(c7)\n    u8 = Concatenate([u8, c2])\n    c8 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(u8)\n    c8 = Dropout(0.1)(c8)\n    c8 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c8)\n\n    u9 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same')(c8)\n    u9 = Concatenate([u9, c1], axis=3)\n    c9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(u9)\n    c9 = Dropout(0.1)(c9)\n    c9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same')(c9)\n\n    outputs=Conv2D(1,(1,1), activation='sigmoid')(c9)\n\n    model=Model(inputs, outputs)\n    model.compile(optimizer='adam', loss=\"binary_crossentropy\", metrics=[mean_iou])\n    model.summary()\n\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9caac04b72be89525a8d50fd05b281df637ff515"},"cell_type":"code","source":"# for train\ndef train(model):\n    if model=='base':\n        print(\"base model training ...\")\n        model=U_net(np.array(X_train))\n        checkpointer = ModelCheckpoint('model-dsbowl2018-1.h5', verbose=1, save_best_only=True)\n    else :\n        print(\"pyramid model training ...\")\n        model=U_net_pyramid(np.array(X_train))\n        checkpointer = ModelCheckpoint('model-dsbowl2018-1_pyramid.h5', verbose=1, save_best_only=True)\n\n    earlystopper = EarlyStopping(patience=5, verbose=1)\n    model.fit(X_train, Y_train, validation_split=0.1, batch_size=16, epochs=50,\n                        callbacks=[earlystopper, checkpointer])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"edaaac79570878bc2a664f5edaa0e4d2777fa8c8"},"cell_type":"code","source":"def predict(X_train,X_test,model):\n    if model=='base':\n        print(\"base model load ...\")\n        model=load_model('model-dsbowl2018-1.h5', custom_objects={'mean_iou': mean_iou})\n    else :\n        print(\"pyramid model load ...\")\n        model = load_model('model-dsbowl2018-1_pyramid.h5', custom_objects={'mean_iou': mean_iou})\n    preds_train=model.predict(X_train[:int(X_train.shape[0]*0.9)], verbose=1)\n    preds_val=model.predict(X_train[int(X_train.shape[0]*0.9):], verbose=1)\n    preds_test=model.predict(X_test, verbose=1)\n\n    # Threshold predictions\n    preds_train_t = (preds_train > 0.5).astype(np.uint8)\n    preds_val_t = (preds_val > 0.5).astype(np.uint8)\n    preds_test_t = (preds_test > 0.5).astype(np.uint8)\n    preds_test_upsampled=[]\n    for i in range(len(preds_test)):\n        preds_test_upsampled.append(resize(np.squeeze([preds_test[i]]),(sizes_test[i][0], sizes_test[i][1]),\n                                           mode=\"constant\",preserve_range=True))\n\n    \n    print(\"visualization ...\")\n    # Perform a sanity check on some random training samples\n    X_train=np.array(X_train)\n    preds_val_t=np.array(preds_val_t)\n    preds_train_t=np.array(preds_train_t)\n\n    ix = random.randint(0, len(preds_train_t))\n    # save image\n    fig=plt.figure()\n    ax=[]\n    for i in range(3):\n        ax.append(fig.add_subplot(1,3,i+1))\n\n    ax[0].imshow(X_train[ix])\n    ax[0].set_title(\"X_train\")\n    ax[1].imshow(np.squeeze(Y_train[ix]))\n    ax[1].set_title(\"Y_train\")\n    ax[2].imshow(np.squeeze(preds_train_t[ix]))\n    ax[2].set_title(\"X_pred\")\n    plt.show()\n    #plt.savefig(\"./result/training_sample_{}.png\".format(ix))\n\n\n    # Perform a sanity check on some random validation samples\n    ix = random.randint(0, len(preds_val_t))\n    ix=36\n    fig=plt.figure()\n    ax=[]\n    for i in range(3):\n        ax.append(fig.add_subplot(1,3,i+1))\n\n    ax[0].imshow(X_train[int(X_train.shape[0] * 0.9):][ix])\n    ax[0].set_title(\"X_val\")\n    ax[1].imshow(np.squeeze(Y_train[int(Y_train.shape[0] * 0.9):][ix]))\n    ax[1].set_title(\"Y_val\")\n    ax[2].imshow(np.squeeze(preds_val_t[ix]))\n    ax[2].set_title(\"X_val_pred\")\n    plt.show()\n    #plt.savefig(\"./result/validation_sample_{}.png\".format(ix))\n    return preds_test_upsampled","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ed9edad17670ac4b6bd849330212d91b29fbfe26"},"cell_type":"markdown","source":"## train U_net"},{"metadata":{"trusted":true,"_uuid":"03fe18a2818486b500e8ff668dcdbd6921bf849e"},"cell_type":"code","source":"train(\"base\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"00dfcdf6d78259179e57b6ade0a9744692ed8857"},"cell_type":"markdown","source":"## train U_net + pyramid model ..."},{"metadata":{"trusted":true,"_uuid":"36450bdd274790351bc0496a7a7fc40c9d644c8a"},"cell_type":"code","source":"train(\"pyramid\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1aeab4caabcc9676726d4e35360454560d919fc3"},"cell_type":"markdown","source":"## predict simple U_net ...\n"},{"metadata":{"trusted":true,"_uuid":"fa7996ac5d0128df6b4ea40bb89bc42d276b7a13","scrolled":true},"cell_type":"code","source":"predict(X_train,X_test, \"base\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"792968e417f67ba44456b6a1befe77cf42decdd0"},"cell_type":"markdown","source":"## predict U_net + pyramid network ...\n\n- this model can capture tiny mask\n- https://github.com/RRoundTable/U_net"},{"metadata":{"trusted":true,"_uuid":"711503e8504972770c96329181539770d0d2d3c5","scrolled":true},"cell_type":"code","source":"preds_test_upsampled=predict(X_train, X_test, \"pyramid\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3b3a02e5ad3612c1beee62ed103f4efe6b3afa3a"},"cell_type":"code","source":"# Run-length encoding stolen from https://www.kaggle.com/rakhlin/fast-run-length-encoding-python\ndef rle_encoding(x):\n    dots = np.where(x.T.flatten() == 1)[0]\n    run_lengths = []\n    prev = -2\n    for b in dots:\n        if (b>prev+1): run_lengths.extend((b + 1, 0))\n        run_lengths[-1] += 1\n        prev = b\n    return run_lengths\n\ndef prob_to_rles(x, cutoff=0.5):\n    lab_img = label(x > cutoff)\n    for i in range(1, lab_img.max() + 1):\n        yield rle_encoding(lab_img == i)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5f67b83a7b9259138c715c37f5f0b25c176e4539"},"cell_type":"code","source":"new_test_ids = []\nrles = []\nfor n, id_ in enumerate(test_ids):\n    rle = list(prob_to_rles(preds_test_upsampled[n]))\n    rles.extend(rle)\n    new_test_ids.extend([id_] * len(rle))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0330f24476386f8cd59e4abc808fdac7885b639a"},"cell_type":"code","source":"# Create submission DataFrame\nsub = pd.DataFrame()\nsub['ImageId'] = new_test_ids\nsub['EncodedPixels'] = pd.Series(rles).apply(lambda x: ' '.join(str(y) for y in x))\nsub.to_csv('sub-dsbowl2018-1.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}