{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Training part","metadata":{"papermill":{"duration":0.005433,"end_time":"2023-06-16T21:11:16.918829","exception":false,"start_time":"2023-06-16T21:11:16.913396","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport time\nfrom glob import glob\nfrom IPython.display import clear_output ","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:13.934026Z","iopub.execute_input":"2023-07-20T08:55:13.934898Z","iopub.status.idle":"2023-07-20T08:55:22.348083Z","shell.execute_reply.started":"2023-07-20T08:55:13.934865Z","shell.execute_reply":"2023-07-20T08:55:22.347115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint_dir = os.path.join('kaggle','working', 'models',\"model_checkpoint\")\ncheckpoint_prefix = os.path.join(checkpoint_dir, \"ckpt\")\n\nconfig = {\n    'train_data_path': \"/kaggle/input/contrails-images-ash-color-tfrecord/contrails-images-ash-color-tfrecord\",\n    'weight_path': \"/kaggle/input/tf-keras-pretrained-model-weights/No Top/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_192_no_top.h5\",\n    'checkpoint_prefix': checkpoint_prefix,\n    'checkpoint_dir': checkpoint_dir,\n    'output_dir': \"models\",\n    'batch_size': 32,\n    'image_size': 256,\n    'input_shape': [256,256,3],\n    'output_channel': 1,  #0,1 분류이므로\n    'learning_rate': 0.0001,\n    'epochs': 10,\n    'loss_smooth': 1.0,\n    \n}\n\n","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:22.350132Z","iopub.execute_input":"2023-07-20T08:55:22.350753Z","iopub.status.idle":"2023-07-20T08:55:22.357382Z","shell.execute_reply.started":"2023-07-20T08:55:22.350725Z","shell.execute_reply":"2023-07-20T08:55:22.356478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def _parse_function(tfrecord_serialized):\n    features = {\n    'inputs': tf.io.FixedLenFeature([], tf.string),\n    'labels': tf.io.FixedLenFeature([], tf.string),\n}\n\n    parsed_features = tf.io.parse_single_example(tfrecord_serialized, features)\n    \n    inputs = tf.io.decode_raw(parsed_features['inputs'], tf.float32)\n    labels = tf.io.decode_raw(parsed_features['labels'], tf.int32)\n\n    inputs = tf.reshape(inputs, [config['image_size'], config['image_size'], 3])\n    labels = tf.reshape(labels, [config['image_size'], config['image_size'], 1])\n\n    return inputs, labels\n\n# del train_dataset, valid_dataset\n\ntrain_dataset = tf.data.TFRecordDataset(glob(os.path.join(config['train_data_path'],\"train_set_*.tfr\")))\n# train_dataset = tf.data.TFRecordDataset(os.path.join(BASE_DIR,\"tfrecord\",\"train_set.tfr\"))\ntrain_dataset = train_dataset.map(_parse_function)\ntrain_dataset = train_dataset.batch(config['batch_size'])\n# train_dataset = train_dataset.prefetch(tf.data.experimental.AUTOTUNE).batch(config['batch_size'])\n\nvalid_dataset = tf.data.TFRecordDataset(os.path.join(config['train_data_path'],\"valid_set.tfr\"))\nvalid_dataset = valid_dataset.map(_parse_function)\nvalid_dataset = valid_dataset.batch(config['batch_size'])\n# valid_dataset = valid_dataset.prefetch(tf.data.experimental.AUTOTUNE).batch(config['batch_size'])","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:22.358845Z","iopub.execute_input":"2023-07-20T08:55:22.359474Z","iopub.status.idle":"2023-07-20T08:55:25.26579Z","shell.execute_reply.started":"2023-07-20T08:55:22.359441Z","shell.execute_reply":"2023-07-20T08:55:25.264827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for img, labels in train_dataset.take(1):\n    print(img.shape)  \n    print(labels.shape)  \n\nplt.subplot(1, 2, 1)\nplt.imshow(tf.keras.utils.array_to_img(img.numpy()[3,:,:,:]))\n\nplt.subplot(1, 2, 2)\nplt.imshow(tf.keras.utils.array_to_img(labels.numpy()[3,:,:,:]))","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:25.268394Z","iopub.execute_input":"2023-07-20T08:55:25.268854Z","iopub.status.idle":"2023-07-20T08:55:26.398437Z","shell.execute_reply.started":"2023-07-20T08:55:25.268821Z","shell.execute_reply":"2023-07-20T08:55:26.39749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def soft_dice_score(output, target, smooth=0.0, eps=1e-7, dims=None):\n    assert output.shape == target.shape\n    if dims is not None:\n        intersection = tf.reduce_sum(output * target, axis=dims)\n        cardinality = tf.reduce_sum(output + target, axis=dims)\n    else:\n        intersection = tf.reduce_sum(output * target)\n        cardinality = tf.reduce_sum(output + target)\n    dice_score = (2.0 * intersection + smooth) / tf.clip_by_value(cardinality + smooth, eps, float(\"inf\"))\n    return dice_score\n\nclass DiceLoss(tf.keras.losses.Loss):\n    def __init__(self,log_loss=False, from_logits=True, smooth=0.0, eps=1e-7):\n\n        self.from_logits = from_logits\n        self.smooth = smooth\n        self.eps = eps\n        self.log_loss = log_loss\n\n    def call(self, y_pred, y_true):\n        assert y_true.shape[0] == y_pred.shape[0]\n\n        if self.from_logits:\n            y_pred = tf.math.exp(tf.math.log_sigmoid(y_pred))\n\n        bs = y_true.shape[0]\n        dims = (0, 2)\n\n       \n        y_true = tf.reshape(y_true, (bs, 1, -1))\n        y_pred = tf.reshape(y_pred, (bs, 1, -1))\n\n        # if self.ignore_index is not None:\n        #     mask = y_true != self.ignore_index\n        #     y_pred = y_pred * tf.cast(mask, y_pred.dtype)\n        #     y_true = y_true * tf.cast(mask, y_true.dtype)\n\n        scores = self.compute_score(y_pred, y_true, smooth=self.smooth, eps=self.eps, dims=dims)\n\n        if self.log_loss:\n            loss = -tf.math.log(tf.clip_by_value(scores, self.eps, float(\"inf\")))\n        else:\n            loss = 1.0 - scores\n\n        mask = tf.reduce_sum(y_true, axis=dims) > 0\n        loss *= tf.cast(mask, loss.dtype)\n\n        return self.aggregate_loss(loss)\n\n    def aggregate_loss(self, loss):\n        return tf.reduce_mean(loss)\n\n    def compute_score(self, output, target, smooth=0.0, eps=1e-7, dims=None):\n        return soft_dice_score(output, target, smooth, eps, dims)","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:26.399782Z","iopub.execute_input":"2023-07-20T08:55:26.400073Z","iopub.status.idle":"2023-07-20T08:55:26.416037Z","shell.execute_reply.started":"2023-07-20T08:55:26.400048Z","shell.execute_reply":"2023-07-20T08:55:26.414515Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class SCSEModule(tf.keras.layers.Layer):\n    def __init__(self, in_channels, reduction=16):\n        super(SCSEModule, self).__init__()\n        self.cSE = tf.keras.Sequential([\n            tf.keras.layers.GlobalAveragePooling2D(keepdims=True),\n            tf.keras.layers.Conv2D(in_channels // reduction, 1),\n            tf.keras.layers.ReLU(),\n            tf.keras.layers.Conv2D(in_channels, 1),\n            tf.keras.layers.Activation('sigmoid')\n        ])\n        self.sSE = tf.keras.Sequential([\n            tf.keras.layers.Conv2D(1, 1),\n            tf.keras.layers.Activation('sigmoid')\n        ])\n\n    def call(self, x):\n        result = x * self.cSE(x) + x * self.sSE(x)\n        return result\n\ndef upsample(filters, size, apply_dropout=False):\n  initializer = tf.random_normal_initializer(0., 0.02)\n\n  result = tf.keras.Sequential()\n  result.add(\n    tf.keras.layers.Conv2DTranspose(filters, size, strides=2,\n                                    padding='same',\n                                    kernel_initializer=initializer,#'he_uniform'\n                                    use_bias=False))\n\n  result.add(tf.keras.layers.BatchNormalization())\n\n  if apply_dropout:\n      result.add(tf.keras.layers.Dropout(0.5))\n\n  result.add(tf.keras.layers.ReLU())\n\n  return result\n\nclass Unet_v1(tf.keras.Model):\n    def __init__(self): \n        super(Unet_v1, self).__init__()\n#         base_model = tf.keras.applications.MobileNetV2(input_shape=config['input_shape'], include_top=False)\n\n        backbone=tf.keras.applications.MobileNetV2\n        backbone(include_top=False, weights=None, input_shape=config['input_shape'])\n\n        inputs = tf.keras.layers.Input(shape=config['input_shape'])\n        base_model = backbone(weights=config['weight_path'], include_top=False, input_tensor=inputs)\n\n\n\n        # Use the activations of these layers\n        layer_names = [\n            'block_1_expand_relu',   # 128\n            'block_3_expand_relu',   # 64\n            'block_6_expand_relu',   # 32\n            'block_13_expand_relu',  # 16\n        ]\n        base_model_outputs = [base_model.get_layer(name).output for name in layer_names]\n\n        self.down_stack = []\n        for output in base_model_outputs:\n            down = tf.keras.Model(inputs=base_model.input, outputs=output)\n            down.trainable = False\n            self.down_stack.append(down)\n        \n        self.up_stack = [\n            # upsample(512, 3),  # 8 -> 16\n            upsample(256, 3),  # 16 -> 32\n            upsample(128, 3),  # 32 -> 64\n            upsample(64, 3),   # 64 -> 128\n            # upsample(32, 3),   # 128 -> 256\n        ]\n\n        self.scse_stack = [\n            # SCSEModule(1088, 3),  # 8 -> 16\n            SCSEModule(448, 3),  # 16 -> 32\n            SCSEModule(272, 3),  # 32 -> 64\n            SCSEModule(160, 3),   # 64 -> 128\n            # SCSEModule(64, 3),   # 128 -> 256\n        ]\n\n\n\n        self.input_resize_layer = tf.keras.layers.Resizing(\n          config['input_shape'][0],\n          config['input_shape'][1],\n          interpolation='bilinear',\n          crop_to_aspect_ratio=False,\n          )\n        \n        self.output_resize_layer = tf.keras.layers.Resizing(\n          256,\n          256,\n          interpolation='bilinear',\n          crop_to_aspect_ratio=False,\n          )\n        \n        self.last = tf.keras.layers.Conv2DTranspose(\n          filters= config['output_channel'], kernel_size=2, strides=2,\n          padding='same') \n        self.last_2 = tf.keras.layers.Conv2D(1, 3, padding='same')\n        self.concat = tf.keras.layers.Concatenate()\n\n    def call(self, input): \n\n        resized_inputs = self.input_resize_layer(input)\n\n        skips = [down(resized_inputs) for down in self.down_stack] #down_stack(resized_inputs)\n        x = skips[-1]\n        skips = reversed(skips[:-1])\n\n        # Upsampling and establishing the skip connections\n        for up, scse, skip in zip(self.up_stack, self.scse_stack, skips):\n          x = up(x)\n       \n          x = self.concat([x, skip])\n          x = self.concat([x, scse(x)])\n\n        x = self.last(x)\n        x = self.concat([x, resized_inputs])\n        x = self.last_2(x)\n        x = self.output_resize_layer(x)\n        return x\n\nmodel = Unet_v1()\noptimizer = tf.keras.optimizers.Adam(config['learning_rate'])\nloss_dice = DiceLoss(smooth=config['loss_smooth'])\nmodel.compile()\n\ncheckpoint = tf.train.Checkpoint(optimizer=optimizer,\n                                 model=model,\n                                 )\n\ncheck_pred = model(img)","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:26.417832Z","iopub.execute_input":"2023-07-20T08:55:26.418599Z","iopub.status.idle":"2023-07-20T08:55:35.776882Z","shell.execute_reply.started":"2023-07-20T08:55:26.41856Z","shell.execute_reply":"2023-07-20T08:55:35.775916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resized_img = tf.keras.layers.Resizing(config['input_shape'][0],config['input_shape'][1])(img)\nresults_down_stack = [down(resized_img) for down in model.down_stack]\nfor i in range(len(results_down_stack)):\n    print(results_down_stack[i].shape)\nplt.figure(figsize=[20,20])\nfor j in range(4):\n    for i in range(len(results_down_stack)):\n        plt.subplot(4,len(results_down_stack),4*j+i+1)\n        plt.imshow(results_down_stack[i][0,:,:,j])","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:35.779098Z","iopub.execute_input":"2023-07-20T08:55:35.779377Z","iopub.status.idle":"2023-07-20T08:55:39.28423Z","shell.execute_reply.started":"2023-07-20T08:55:35.779353Z","shell.execute_reply":"2023-07-20T08:55:39.2834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output = model(img)\noutput = tf.math.exp(tf.math.log_sigmoid(output))\n\nbs = labels.shape[0]\ndims = (0, 2)\n\ntarget = tf.reshape(tf.cast(labels, tf.float32), (bs, 1, -1))\noutput = tf.reshape(output, (bs, 1, -1))\n\nintersection = tf.reduce_sum(output * target, axis=dims)\ncardinality = tf.reduce_sum(output + target, axis=dims)\n    \ndice_score = (2.0 * intersection + 1) / tf.clip_by_value(cardinality + 1, 0.001, float(\"inf\"))\ndice_score","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:39.285483Z","iopub.execute_input":"2023-07-20T08:55:39.286553Z","iopub.status.idle":"2023-07-20T08:55:39.514377Z","shell.execute_reply.started":"2023-07-20T08:55:39.28652Z","shell.execute_reply":"2023-07-20T08:55:39.513447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# loss_fun = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)\n# loss_fun = tf.keras.losses.BinaryCrossentropy(from_logits=True)\n\ndef train(lr_rate, n_epoch):\n    optimizer = tf.keras.optimizers.Adam(lr_rate)\n    \n    @tf.function\n    def train_step(inputs, targets):\n        with tf.GradientTape() as tape:\n            preds = model(inputs, training=True)\n#             loss = loss_dice.call(preds, targets)\n            loss = loss_dice.call(preds, targets)\n        # loss = loss_fun(targets, preds)\n\n        gradients = tape.gradient(loss, model.trainable_variables)\n        optimizer.apply_gradients(zip(gradients, model.trainable_variables))\n\n        return loss\n\n    train_loss_list = []\n    valid_loss_list = []\n\n\n    epochs = n_epoch\n    train_batch_len = tf.data.experimental.cardinality(train_dataset).numpy()\n    # train_batch_len = 1\n\n    for img, labels in train_dataset.take(1):\n        labels = tf.cast(labels, tf.float32)\n        train_preds = model.predict(img)\n        train_coefficient = loss_dice.compute_score(train_preds,labels)\n        \n    for img, labels in valid_dataset.take(1):\n        labels = tf.cast(labels, tf.float32)\n        valid_preds = model.predict(img)\n        valid_coefficient = loss_dice.compute_score(valid_preds,labels)\n\n    for epoch in range(epochs):\n        start = time.time()\n\n        loss_list = []\n        for step, (inputs, labels) in enumerate(train_dataset.take(train_batch_len)):\n            labels = tf.cast(labels, tf.float32)\n            loss = train_step(inputs, labels)\n            loss_list.append(loss)\n\n            if epoch != 0:\n                print(f'\\repoch: {epoch}/{epochs}  step: {step}/{train_batch_len}  train-loss: {loss} train-loss2: {train_loss_last} valid_loss: {valid_loss_last}', end=\"\")\n            else:\n                print(f'\\repoch: {epoch}/{epochs}  step: {step}/{train_batch_len}  train-loss: {loss}', end=\"\")\n        \n        valid_results = []\n        for img, labels in valid_dataset.take(30):\n            labels = tf.cast(labels, tf.float32)\n            valid_preds = model.predict(img)\n            valid_coefficient = loss_dice.call(valid_preds, labels)\n            valid_results.append(valid_coefficient.numpy())\n            \n        \n        valid_loss_last = np.mean(valid_results)\n        valid_loss_list.append(valid_loss_last)\n\n        train_loss_last = np.mean(loss_list)\n        train_loss_list.append(train_loss_last)\n\n        clear_output()\n#     checkpoint.save(file_prefix=config[\"checkpoint_prefix\"])\n    return train_loss_list, valid_loss_list","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:39.516001Z","iopub.execute_input":"2023-07-20T08:55:39.51643Z","iopub.status.idle":"2023-07-20T08:55:39.531203Z","shell.execute_reply.started":"2023-07-20T08:55:39.516378Z","shell.execute_reply":"2023-07-20T08:55:39.530195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"results = []","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:39.535509Z","iopub.execute_input":"2023-07-20T08:55:39.53579Z","iopub.status.idle":"2023-07-20T08:55:39.546053Z","shell.execute_reply.started":"2023-07-20T08:55:39.535767Z","shell.execute_reply":"2023-07-20T08:55:39.545134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 베이스학습\nfor i in range(len(model.down_stack)):\n    model.down_stack[i].trainable = False\n\nfor i in range(len(model.up_stack)):\n    model.up_stack[i].trainable = True\n\nfor i in range(len(model.scse_stack)):\n    model.scse_stack[i].trainable = True\n\nresult = train(0.0001,2)\nresults.extend(result)","metadata":{"execution":{"iopub.status.busy":"2023-07-20T08:55:39.547368Z","iopub.execute_input":"2023-07-20T08:55:39.547834Z","iopub.status.idle":"2023-07-20T09:02:22.704328Z","shell.execute_reply.started":"2023-07-20T08:55:39.547801Z","shell.execute_reply":"2023-07-20T09:02:22.703339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(len(model.down_stack)):\n    model.down_stack[i].trainable = True\n\nfor i in range(len(model.up_stack)):\n    model.up_stack[i].trainable = True\n\nfor i in range(len(model.scse_stack)):\n    model.scse_stack[i].trainable = True\n\nresult = train(0.00005,10)\nresults.extend(result)","metadata":{"execution":{"iopub.status.busy":"2023-07-20T09:02:22.708978Z","iopub.execute_input":"2023-07-20T09:02:22.709288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint.save(file_prefix=config[\"checkpoint_prefix\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del (\n        train_dataset,\n        valid_dataset,\n        model,\n        checkpoint,\n    )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Submission part","metadata":{"papermill":{"duration":0.013882,"end_time":"2023-06-16T23:35:32.376031","exception":false,"start_time":"2023-06-16T23:35:32.362149","status":"completed"},"tags":[]}},{"cell_type":"code","source":"model = Unet_v1()\noptimizer = tf.keras.optimizers.Adam(config['learning_rate'])\nmodel.compile()\n\ncheckpoint = tf.train.Checkpoint(optimizer=optimizer,\n                                 model=model,\n                                 )\n\n####### 저장된 모델 있을 경우 ##########\nmanager = tf.train.CheckpointManager(checkpoint, config[\"checkpoint_dir\"], max_to_keep=1)\ncheckpoint.restore(manager.latest_checkpoint)\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import csv\nimport math\nfrom tqdm import tqdm\nfrom scipy import ndimage\nimport gc\nimport csv\n\nBASE_DIR = '/kaggle/input/google-research-identify-contrails-reduce-global-warming'\nSUBMISSION_DIR = \"/kaggle/working\"\n\ndef normalize_range(data, bounds):\n    \"\"\"Maps data to the range [0, 1].\"\"\"\n\n    return (data - bounds[0]) / (bounds[1] - bounds[0])\n\ndef process_test_record(subset,record_id):\n    with open(os.path.join(BASE_DIR,subset, record_id, 'band_11.npy'), 'rb') as f:\n        band11 = np.load(f)\n    with open(os.path.join(BASE_DIR,subset, record_id, 'band_14.npy'), 'rb') as f:\n        band14 = np.load(f)\n    with open(os.path.join(BASE_DIR,subset, record_id, 'band_15.npy'), 'rb') as f:\n        band15 = np.load(f)\n \n    _T11_BOUNDS = (243, 303)\n    _CLOUD_TOP_TDIFF_BOUNDS = (-4, 5)\n    _TDIFF_BOUNDS = (-4, 2)\n\n    N_TIMES_BEFORE = 4\n\n    r = normalize_range(band15 - band14, _TDIFF_BOUNDS)\n    g = normalize_range(band14 - band11, _CLOUD_TOP_TDIFF_BOUNDS)\n    b = normalize_range(band14, _T11_BOUNDS)\n    false_color = np.clip(np.stack([r, g, b], axis=2), 0, 1)\n    img = false_color[..., N_TIMES_BEFORE]\n\n    return img\n    \ndef process_test_batch(subset,cur_batch,batch_size,records):\n    \n    n_records = min(len(records),batch_size)\n    data = np.zeros(shape=(n_records,256,256,3),dtype=\"float32\")\n    for i,record_id in tqdm(enumerate(records[:n_records]),total = n_records,desc=f\"Processing {subset} data\"):\n        data[i] = process_test_record(subset,record_id)\n\n    \n    return n_records,data\n\ndef rle_encode(x):\n    mask = np.where(x.T.flatten() == 1)[0]\n    rle = []\n    prev = -2\n    for i in mask:\n        if i==prev+1:\n            rle[-1]+=1\n        else:\n            rle.extend((i+1,1))\n        prev = i\n    if not rle:\n        text = '-'\n    else:\n        text = str(rle).replace(\"[\", \"\").replace(\"]\", \"\").replace(\",\", \"\")\n    return text\n\n\ndef clean(binary_prediction): \n    #removes single dots in prediction(improvement is not significant)\n    k = np.ones((10,10,1))\n    conv = ndimage.convolve(binary_prediction,k,mode='constant',cval=0.25 ) > 2\n    return np.logical_and(binary_prediction,conv)\n\ncsvfile = open(os.path.join(SUBMISSION_DIR,'submission.csv'), 'w')\n\nfield_names= ['record_id', 'encoded_pixels']\nwriter = csv.DictWriter(csvfile, fieldnames=field_names)\nwriter.writeheader()\n\nrecords = os.listdir(os.path.join(BASE_DIR,'test'))\nbatch_size = 32\nbatches = math.ceil(len(records)/batch_size)\n\nfor batch in range(batches):\n    processed,test_X = process_test_batch('test', 1, batch_size,records)\n    predictions = model.predict(test_X)\n    predictions = tf.math.exp(tf.math.log_sigmoid(predictions)).numpy() # logit으로 출력하는 모델이므로\n    \n    submission = []                 \n    for i,record in enumerate(records[:processed]):\n        ############이부분 logit인지 sigmoid인지 잘 체크하고 코드쓰기~\n        binary_prediction = np.vectorize(lambda x: 1 if x>=0.05 else 0)(predictions[i])\n        binary_prediction = clean(binary_prediction)\n        submission.append({})\n        submission[-1]['record_id']=record\n        submission[-1]['encoded_pixels']=rle_encode(binary_prediction)\n\n    writer.writerows(submission)\n    records = records[processed:]\n    gc.collect()\ncsvfile.close()","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}