{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"!pip install -q efficientnet >> /dev/null\n!pip install tensorflow~=2.2.0 tensorflow_gcs_config~=2.2.0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd, numpy as np\nfrom kaggle_datasets import KaggleDatasets\nimport tensorflow as tf, re, math\nimport tensorflow.keras.backend as K\nimport efficientnet.tfkeras as efn\nfrom sklearn.model_selection import KFold\nfrom sklearn.metrics import roc_auc_score\nimport matplotlib.pyplot as plt\nfrom keras.utils.vis_utils import plot_model\nimport time,random","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DEVICE = \"TPU\"\n# SEED=random.randint(1,100)\nSEED = 42\nFOLDS = 5 \nCROP_SIZE=512\nNET_SIZE=384\nIMG_SIZES = [768,768,768,768,768]\nINC2019 = [0,0,0,0,0]\nINC2018 = [1,1,1,1,1]\nBATCH_SIZES = [32]*FOLDS\nEPOCHS = [13]*FOLDS\nEFF_NETS = [6,6,6,6,6]\nWGTS = [1/FOLDS]*FOLDS\nTTA = 14\nMODEL=[5]\nVERBOSE = 2\n# partition=0\nENSEMBLE=False\n# UPSAMPLE MALIGNANT COUNT TIMES\nM1 = [0]*FOLDS #2020 malig\nM2 = [0]*FOLDS #ISIC malig\nM3 = [0]*FOLDS #2019 good malig\nM4 = [0]*FOLDS #2018 2017 malig\n\n\nif DEVICE == \"TPU\":\n    print(\"connecting to TPU...\")\n    try:\n        tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n        print('Running on TPU ', tpu.master())\n    except ValueError:\n        print(\"Could not connect to TPU\")\n        tpu = None\n\n    if tpu:\n        try:\n            print(\"initializing  TPU ...\")\n            tf.config.experimental_connect_to_cluster(tpu)\n            tf.tpu.experimental.initialize_tpu_system(tpu)\n            strategy = tf.distribute.experimental.TPUStrategy(tpu)\n            print(\"TPU initialized\")\n        except _:\n            print(\"failed to initialize TPU\")\n    else:\n        DEVICE = \"GPU\"\n\nif DEVICE != \"TPU\":\n    print(\"Using default strategy for CPU and single GPU\")\n    strategy = tf.distribute.get_strategy()\n\nif DEVICE == \"GPU\":\n    print(\"Num GPUs Available: \", len(tf.config.experimental.list_physical_devices('GPU')))\n    \n\nAUTO     = tf.data.experimental.AUTOTUNE\nREPLICAS = strategy.num_replicas_in_sync\nprint(f'REPLICAS: {REPLICAS}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"GCS_PATH = [None]*FOLDS; GCS_PATH2 = [None]*FOLDS; GCS_PATH3 = [None]*FOLDS\nfor i,k in enumerate(IMG_SIZES):\n    GCS_PATH[i] = KaggleDatasets().get_gcs_path('melanoma-%ix%i'%(k,k))\n    GCS_PATH2[i] = KaggleDatasets().get_gcs_path('isic2019-%ix%i'%(k,k))\n    GCS_PATH3[i] = KaggleDatasets().get_gcs_path('malignant-v2-%ix%i'%(k,k))\nfiles_train = np.sort(np.array(tf.io.gfile.glob(GCS_PATH[0] + '/train*.tfrec')))\nfiles_test  = np.sort(np.array(tf.io.gfile.glob(GCS_PATH[0] + '/test*.tfrec')))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ROT_ = 180.0\nSHR_ = 2.0\nHZOOM_ = 8.0\nWZOOM_ = 8.0\nHSHIFT_ = 8.0\nWSHIFT_ = 8.0\ndef get_mat(rotation, shear, height_zoom, width_zoom, height_shift, width_shift):\n    rotation = math.pi * rotation / 180.\n    shear    = math.pi * shear    / 180.\n    def get_3x3_mat(lst):\n        return tf.reshape(tf.concat([lst],axis=0), [3,3])\n    c1   = tf.math.cos(rotation)\n    s1   = tf.math.sin(rotation)\n    one  = tf.constant([1],dtype='float32')\n    zero = tf.constant([0],dtype='float32')\n    rotation_matrix = get_3x3_mat([c1,   s1,   zero, \n                                   -s1,  c1,   zero, \n                                   zero, zero, one])    \n    c2 = tf.math.cos(shear)\n    s2 = tf.math.sin(shear)    \n    shear_matrix = get_3x3_mat([one,  s2,   zero, \n                                zero, c2,   zero, \n                                zero, zero, one])        \n    zoom_matrix = get_3x3_mat([one/height_zoom, zero,           zero, \n                               zero,            one/width_zoom, zero, \n                               zero,            zero,           one])    \n    shift_matrix = get_3x3_mat([one,  zero, height_shift, \n                                zero, one,  width_shift, \n                                zero, zero, one])\n    \n    return K.dot(K.dot(rotation_matrix, shear_matrix), \n                 K.dot(zoom_matrix,     shift_matrix))\ndef transform(image, DIM=256):    \n    XDIM = DIM%2 #fix for size 331\n    rot = ROT_ * tf.random.normal([1], dtype='float32')\n    shr = SHR_ * tf.random.normal([1], dtype='float32') \n    h_zoom = 1.0 + tf.random.normal([1], dtype='float32') / HZOOM_\n    w_zoom = 1.0 + tf.random.normal([1], dtype='float32') / WZOOM_\n    h_shift = HSHIFT_ * tf.random.normal([1], dtype='float32') \n    w_shift = WSHIFT_ * tf.random.normal([1], dtype='float32') \n    m = get_mat(rot,shr,h_zoom,w_zoom,h_shift,w_shift) \n    x   = tf.repeat(tf.range(DIM//2, -DIM//2,-1), DIM)\n    y   = tf.tile(tf.range(-DIM//2, DIM//2), [DIM])\n    z   = tf.ones([DIM*DIM], dtype='int32')\n    idx = tf.stack( [x,y,z] )\n    idx2 = K.dot(m, tf.cast(idx, dtype='float32'))\n    idx2 = K.cast(idx2, dtype='int32')\n    idx2 = K.clip(idx2, -DIM//2+XDIM+1, DIM//2)      \n    idx3 = tf.stack([DIM//2-idx2[0,], DIM//2-1+idx2[1,]])\n    d    = tf.gather_nd(image, tf.transpose(idx3))\n    return tf.reshape(d,[DIM, DIM,3])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def read_labeled_tfrecord(example):\n    tfrec_format = {\n        'image'                        : tf.io.FixedLenFeature([], tf.string),\n        'image_name'                   : tf.io.FixedLenFeature([], tf.string),\n        'patient_id'                   : tf.io.FixedLenFeature([], tf.int64),\n        'sex'                          : tf.io.FixedLenFeature([], tf.int64),\n        'age_approx'                   : tf.io.FixedLenFeature([], tf.int64),\n        'anatom_site_general_challenge': tf.io.FixedLenFeature([], tf.int64),\n        'diagnosis'                    : tf.io.FixedLenFeature([], tf.int64),\n        'target'                       : tf.io.FixedLenFeature([], tf.int64)\n    }           \n    example = tf.io.parse_single_example(example, tfrec_format)\n    \n    return {'input_1':[example['sex'],example['age_approx'],example['anatom_site_general_challenge']],\n            'input_2':example['image']\n            }, example['target']\n\ndef read_unlabeled_tfrecord(example, return_image_name):\n    tfrec_format = {\n        'image'                        : tf.io.FixedLenFeature([], tf.string),\n        'image_name'                   : tf.io.FixedLenFeature([], tf.string),\n        'patient_id'                   : tf.io.FixedLenFeature([], tf.int64),\n        'sex'                          : tf.io.FixedLenFeature([], tf.int64),\n        'age_approx'                   : tf.io.FixedLenFeature([], tf.int64),\n        'anatom_site_general_challenge': tf.io.FixedLenFeature([], tf.int64),\n    } \n    example = tf.io.parse_single_example(example, tfrec_format)\n    return {'input_1':[example['sex'],example['age_approx'],example['anatom_site_general_challenge']],\n            'input_2':example['image']\n            }, example['image_name'] if return_image_name else 0\n\ndef prepare_image(img, augment=True, dim=256):    \n    img = tf.image.decode_jpeg(img, channels=3)\n    img = tf.cast(img, tf.float32) / 255.0\n    \n    if augment:\n        img = transform(img,DIM=dim)\n        img = tf.image.random_crop(img, [CROP_SIZE,CROP_SIZE,3])\n        img = tf.image.random_flip_left_right(img)\n        #img = tf.image.random_hue(img, 0.01)\n        img = tf.image.random_saturation(img, 0.7, 1.3)\n        img = tf.image.random_contrast(img, 0.8, 1.2)\n        img = tf.image.random_brightness(img, 0.1)\n    else:\n        img = tf.image.random_crop(img, [CROP_SIZE,CROP_SIZE,3])\n    \n    img = tf.image.resize(img, [NET_SIZE, NET_SIZE])        \n    img = tf.reshape(img, [NET_SIZE,NET_SIZE, 3])\n            \n    return img\n\ndef count_data_items(filenames):\n    n = [int(re.compile(r\"-([0-9]*)\\.\").search(filename).group(1)) \n         for filename in filenames]\n    return np.sum(n)\n\ndef get_dataset(files, augment = False, shuffle = False, repeat = False, \n                labeled=True, return_image_names=True, batch_size=16, dim=256):\n    \n    ds = tf.data.TFRecordDataset(files, num_parallel_reads=AUTO)\n    ds = ds.cache()\n    \n    if repeat:\n        ds = ds.repeat()\n    \n    if shuffle: \n        ds = ds.shuffle(1024*8,seed=SEED)\n        opt = tf.data.Options()\n        opt.experimental_deterministic = False\n        ds = ds.with_options(opt)\n        \n    if labeled: \n        ds = ds.map(read_labeled_tfrecord, num_parallel_calls=AUTO)\n    else:\n        ds = ds.map(lambda example: read_unlabeled_tfrecord(example, return_image_names), \n                    num_parallel_calls=AUTO)      \n    \n    ds = ds.map(lambda x,y:({'input_1':x['input_1'],'input_2':prepare_image(x['input_2'], augment=augment, dim=dim)},y),\n                num_parallel_calls=AUTO)\n    \n    ds = ds.batch(batch_size * REPLICAS)\n    ds = ds.prefetch(AUTO)\n    return ds","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"EFNS = [efn.EfficientNetB0, efn.EfficientNetB1, efn.EfficientNetB2, efn.EfficientNetB3, \n        efn.EfficientNetB4, efn.EfficientNetB5, efn.EfficientNetB6,efn.EfficientNetB7]\n\ndef binary_focal_loss(gamma=2., alpha=.25):\n    def binary_focal_loss_fixed(y_true, y_pred):\n        pt_1 = tf.where(tf.equal(y_true, 1), y_pred, tf.ones_like(y_pred))\n        pt_0 = tf.where(tf.equal(y_true, 0), y_pred, tf.zeros_like(y_pred))\n\n        epsilon = K.epsilon()\n        # clip to prevent NaN's and Inf's\n        pt_1 = K.clip(pt_1, epsilon, 1. - epsilon)\n        pt_0 = K.clip(pt_0, epsilon, 1. - epsilon)\n\n        return -K.sum(alpha * K.pow(1. - pt_1, gamma) * K.log(pt_1)) \\\n               -K.sum((1 - alpha) * K.pow(pt_0, gamma) * K.log(1. - pt_0))\n\n    return binary_focal_loss_fixed\n\ndef build_model(dim=384, model=MODEL):\n    inpA = tf.keras.layers.Input(shape=(3,),name='input_1')\n    y = tf.keras.layers.BatchNormalization()(inpA)\n    y = tf.keras.layers.Dense(3,activation='relu',kernel_initializer='he_normal')(y)\n    y = tf.keras.layers.BatchNormalization()(y)\n    y = tf.keras.layers.Dense(3,activation='relu',kernel_initializer='he_normal')(y)\n    y = tf.keras.layers.BatchNormalization()(y)    \n    y = tf.keras.layers.Dense(1,activation='relu',kernel_initializer='he_normal')(y)\n    \n    inpB = tf.keras.layers.Input(shape=(dim,dim,3),name='input_2')\n    for i in model:\n        base = EFNS[i](input_shape=(dim,dim,3),weights='imagenet',include_top=False)\n        x = base(inpB)\n        x = tf.keras.layers.GlobalAveragePooling2D()(x)\n        x = tf.keras.layers.BatchNormalization()(x)    \n        x = tf.keras.layers.Dense(9,activation='relu',kernel_initializer='he_normal')(x)\n\n        combined=tf.keras.layers.Concatenate()([x, y])\n        combined = tf.keras.layers.BatchNormalization()(combined)            \n        \n    output=tf.keras.layers.Dense(1,activation='sigmoid',kernel_initializer='he_normal')(combined)        \n    model = tf.keras.Model(inputs=[inpA,inpB],outputs=output)\n\n    \n    opt = tf.keras.optimizers.Adam(learning_rate=0.001)\n#     loss = tf.keras.losses.BinaryCrossentropy(label_smoothing=0.05) \n    loss=binary_focal_loss(gamma = 2.0, alpha = 0.80)\n    model.compile(optimizer=opt,loss=loss,metrics=['AUC'])\n    return model\n\n    \n\ndef build_ensemble_model(dim=384, model=MODEL):    \n    inpA = tf.keras.layers.Input(shape=(3,),name='input_1')\n    y = tf.keras.layers.BatchNormalization()(inpA)\n    y = tf.keras.layers.Dense(3,activation='relu',kernel_initializer='he_normal')(y)\n    y = tf.keras.layers.BatchNormalization()(y)\n    y = tf.keras.layers.Dense(1,activation='relu',kernel_initializer='he_normal')(y)    \n    \n    inpB = tf.keras.layers.Input(shape=(dim,dim,3),name='input_2')\n    for i in model:\n        base = EFNS[i](input_shape=(dim,dim,3),weights='imagenet',include_top=False)\n        x = base(inpB)\n        x = tf.keras.layers.GlobalAveragePooling2D()(x)\n        x = tf.keras.layers.BatchNormalization()(x)    \n        x = tf.keras.layers.Dense(1,activation='relu',kernel_initializer='he_normal')(x)\n        if i==MODEL[0]:\n            combined=x\n        else:\n            combined=tf.keras.layers.Concatenate()([combined, x])\n            \n    ensemble=tf.keras.layers.Concatenate()([combined, y])        \n    ensemble = tf.keras.layers.BatchNormalization()(ensemble)                    \n    output=tf.keras.layers.Dense(1,activation='sigmoid',kernel_initializer='he_normal')(ensemble)        \n    model = tf.keras.Model(inputs=[inpA,inpB],outputs=output)\n\n    \n    opt = tf.keras.optimizers.Adam(learning_rate=0.001) \n    loss=binary_focal_loss(gamma = 2.0, alpha = 0.80)\n    model.compile(optimizer=opt,loss=loss,metrics=['AUC'])\n    return model\n\ndef get_lr_callback(batch_size=8):\n    lr_start   = 0.001\n    lr_max     = 0.001\n    lr_min     = 0.000001\n    lr_ramp_ep = 2\n    lr_sus_ep  = 0\n    lr_decay   = 0.72\n   \n    def lrfn(epoch):\n        if epoch < lr_ramp_ep:\n            lr = (lr_max - lr_start) / lr_ramp_ep * epoch + lr_start\n            \n        elif epoch < lr_ramp_ep + lr_sus_ep:\n            lr = lr_max\n            \n        else:\n            lr = (lr_max - lr_min) * lr_decay**(epoch - lr_ramp_ep - lr_sus_ep) + lr_min\n            \n        return lr\n\n    lr_callback = tf.keras.callbacks.LearningRateScheduler(lrfn, verbose=False)\n    return lr_callback","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('SEED:{}'.format(SEED))\nskf = KFold(n_splits=FOLDS,shuffle=True,random_state=SEED)\noof_pred = []; oof_tar = []; oof_val = []; oof_names = []; oof_folds = [] \npreds = np.zeros((count_data_items(files_test),1))\n\nclass TimeHistory(tf.keras.callbacks.Callback):\n    def on_train_begin(self, logs={}):\n        self.times = []\n\n    def on_epoch_begin(self, batch, logs={}):\n        self.epoch_time_start = time.time()\n\n    def on_epoch_end(self, batch, logs={}):\n        self.times.append(time.time() - self.epoch_time_start)\n        \ntime_callback = TimeHistory()\n      \n# print('Trainning Partition:{}'.format(partition))\nfor fold,(idxT,idxV) in enumerate(skf.split(np.arange(15))):\n#     if fold==partition:        \n    # DISPLAY FOLD INFO\n    if DEVICE=='TPU':\n        if tpu: tf.tpu.experimental.initialize_tpu_system(tpu)\n    print('#'*25); print('#### FOLD',fold+1)\n    print('#### Image Size %i with EfficientNet B%i-B%i and batch_size %i'%\n          (IMG_SIZES[fold],MODEL[0],MODEL[-1],BATCH_SIZES[fold]*REPLICAS))\n\n    # CREATE TRAIN AND VALIDATION SUBSETS\n    files_train = tf.io.gfile.glob([GCS_PATH[fold] + '/train%.2i*.tfrec'%x for x in idxT])\n    if INC2019[fold]:\n        files_train += tf.io.gfile.glob([GCS_PATH2[fold] + '/train%.2i*.tfrec'%x for x in idxT*2+1])\n        print('#### Using 2019 external data')\n    if INC2018[fold]:\n        files_train += tf.io.gfile.glob([GCS_PATH2[fold] + '/train%.2i*.tfrec'%x for x in idxT*2])\n        print('#### Using 2018+2017 external data')\n\n    for k in range(M1[fold]):\n        files_train += tf.io.gfile.glob([GCS_PATH3[fold] + '/train%.2i*.tfrec'%x for x in idxT])\n        print('#### Upsample MALIG-1 data (2020 comp)')\n    for k in range(M2[fold]):\n        files_train += tf.io.gfile.glob([GCS_PATH3[fold] + '/train%.2i*.tfrec'%x for x in idxT+15])\n        print('#### Upsample MALIG-2 data (ISIC website)')\n    for k in range(M3[fold]):\n        files_train += tf.io.gfile.glob([GCS_PATH3[fold] + '/train%.2i*.tfrec'%x for x in idxT*2+1+30])\n        print('#### Upsample MALIG-3 data (2019 comp)')\n    for k in range(M4[fold]):\n        files_train += tf.io.gfile.glob([GCS_PATH3[fold] + '/train%.2i*.tfrec'%x for x in idxT*2+30])\n        print('#### Upsample MALIG-4 data (2018 2017 comp)')\n                                \n    np.random.shuffle(files_train); print('#'*25)\n    files_valid = tf.io.gfile.glob([GCS_PATH[fold] + '/train%.2i*.tfrec'%x for x in idxV])\n    files_test = np.sort(np.array(tf.io.gfile.glob(GCS_PATH[fold] + '/test*.tfrec')))\n\n    # BUILD MODEL\n    K.clear_session()\n    with strategy.scope():\n        if ENSEMBLE:\n            print('Building Ensemble Model...')\n            model = build_ensemble_model(dim=NET_SIZE,model=MODEL)\n        else:\n            print('Building Single Model...')\n            model = build_model(dim=NET_SIZE,model=MODEL)\n\n\n    # SAVE BEST MODEL EACH FOLD\n    sv = tf.keras.callbacks.ModelCheckpoint(\n        'fold-%i.h5'%fold, monitor='loss', verbose=0, save_best_only=True,\n        save_weights_only=True, mode='min', save_freq='epoch')\n\n    early_stopping = tf.keras.callbacks.EarlyStopping(monitor = 'val_auc', mode = 'max', patience = 5, verbose = 1,\n                                                       min_delta = 0.0001)\n    cb_lr_schedule = tf.keras.callbacks.ReduceLROnPlateau(monitor = 'val_auc', \n                                                          factor = 0.5, \n                                                          patience = 2, \n                                                          verbose = 1,\n                                                          min_delta = 0.0001, \n                                                          mode = 'max')        \n    # TRAIN\n    print('Training...')\n    history = model.fit(\n        get_dataset(files_train, augment=True, shuffle=True, repeat=True,dim=IMG_SIZES[fold], batch_size = BATCH_SIZES[fold]), \n        epochs=EPOCHS[fold], \n        #get_lr_callback(BATCH_SIZES[fold]),cb_lr_schedule\n        callbacks = [time_callback,sv,early_stopping,get_lr_callback(BATCH_SIZES[fold])], \n        steps_per_epoch=count_data_items(files_train)/BATCH_SIZES[fold]//REPLICAS,\n        validation_data=get_dataset(files_valid,augment=False,shuffle=False,repeat=False,dim=IMG_SIZES[fold]), #class_weight = {0:1,1:2},\n        verbose=VERBOSE)\n\n    times = time_callback.times  \n\n    print('Loading best model...')\n    model.load_weights('fold-%i.h5'%fold)    \n\n    print('Predicting OOF with TTA...')\n    ds_valid = get_dataset(files_valid,labeled=False,return_image_names=False,augment=True,\n            repeat=True,shuffle=False,dim=IMG_SIZES[fold],batch_size=BATCH_SIZES[fold]*4)\n    ct_valid = count_data_items(files_valid);STEPS = TTA * ct_valid/BATCH_SIZES[fold]/4/REPLICAS\n    pred = model.predict(ds_valid,steps=STEPS,verbose=VERBOSE)[:TTA*ct_valid,]\n    oof_pred.append( np.mean(pred.reshape((ct_valid,TTA),order='F'),axis=1) )\n\n    # GET OOF TARGETS AND NAMES\n    ds_valid = get_dataset(files_valid, augment=False, repeat=False, dim=IMG_SIZES[fold],\n            labeled=True, return_image_names=True)    \n    oof_tar.append( np.array([target.numpy() for X, target in iter(ds_valid.unbatch())]) )\n    oof_folds.append( np.ones_like(oof_tar[-1],dtype='int8')*fold )\n    ds = get_dataset(files_valid, augment=False, repeat=False, dim=IMG_SIZES[fold],\n                labeled=False, return_image_names=True)\n    oof_names.append( np.array([img_name.numpy().decode(\"utf-8\") for X, img_name in iter(ds.unbatch())])) \n\n    # REPORT RESULTS\n    auc = roc_auc_score(oof_tar[-1],oof_pred[-1])\n    oof_val.append(np.max( history.history['val_auc'] ))\n    print('#### FOLD %i OOF AUC without TTA = %.3f, with TTA = %.3f'%(fold+1,oof_val[-1],auc))    \n\n    # PREDICT TEST USING TTA\n    print('Predicting Test with TTA...')\n    ds_test = get_dataset(files_test,labeled=False,return_image_names=False,augment=True,\n            repeat=True,shuffle=False,dim=IMG_SIZES[fold],batch_size=BATCH_SIZES[fold]*4)\n    ct_test = count_data_items(files_test); STEPS = TTA * ct_test/BATCH_SIZES[fold]/4/REPLICAS\n    pred = model.predict(ds_test,steps=STEPS,verbose=VERBOSE)[:TTA*ct_test,] \n    preds[:,0] += np.mean(pred.reshape((ct_test,TTA),order='F'),axis=1) * WGTS[fold]   ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# COMPUTE OVERALL OOF AUC\noof = np.concatenate(oof_pred); true = np.concatenate(oof_tar);\nnames = np.concatenate(oof_names); folds = np.concatenate(oof_folds)\nauc = roc_auc_score(true,oof)\nprint('Overall OOF AUC with TTA = %.3f'%auc)\n\n# SAVE OOF TO DISK\ndf_oof = pd.DataFrame(dict(\n    image_name = names, target=true, pred = oof, fold=folds))\ndf_oof.to_csv('oof.csv',index=False)\ndf_oof.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ds = get_dataset(files_test, augment=False, repeat=False, dim=IMG_SIZES[fold],\n                 labeled=False, return_image_names=True)\n\nimage_names = np.array([img_name.numpy().decode(\"utf-8\") \n                        for img, img_name in iter(ds.unbatch())])\n\nsubmission = pd.DataFrame(dict(image_name=image_names, target=preds[:,0]))\nsubmission = submission.sort_values('image_name') \nsubmission.to_csv('submission.csv', index=False)\nsubmission.head()","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}