{"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":"code","source":"import os\nimport re\nfrom sklearn.cluster import KMeans\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nbatch_size = 1\nlambda_scale = 1.\ntrainset_path = '../input/tensorflow-great-barrier-reef/train_images'\n###############################################################\n# Please change testset to the testset path\ntestset_path = '../input/tensorflow-great-barrier-reef/train_images'\n###############################################################\nEPOCHS = 1\nSTEPS = 2800\nnum_shape = 10\n#model saved at \"RPN.npy\", result save at 'submission.csv'","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-02-14T20:26:06.399113Z","iopub.execute_input":"2022-02-14T20:26:06.399847Z","iopub.status.idle":"2022-02-14T20:26:11.447588Z","shell.execute_reply.started":"2022-02-14T20:26:06.399710Z","shell.execute_reply":"2022-02-14T20:26:11.446903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import greatbarrierreef\nenv = greatbarrierreef.make_env()   # initialize the environment\niter_test = env.iter_test()   ","metadata":{"execution":{"iopub.status.busy":"2022-02-14T20:26:11.451062Z","iopub.execute_input":"2022-02-14T20:26:11.451266Z","iopub.status.idle":"2022-02-14T20:26:11.477810Z","shell.execute_reply.started":"2022-02-14T20:26:11.451241Z","shell.execute_reply":"2022-02-14T20:26:11.477164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def annotations():\n    file = pd.read_csv('../input/tensorflow-great-barrier-reef/train.csv')\n    df = pd.DataFrame(file)\n    print(len(df))\n    data = df['annotations']\n    annotations = []\n    for i in range(0, len(df)):\n        annotations.append(list(map(int, re.findall(r\"\\d+\\.?\\d*\", data[i]))))\n    annotations = np.array(annotations,dtype=object)\n    video_id = np.array(df['video_id'])\n    video_frame = np.array(df['video_frame'])\n    print(\"Fishstar_Fish_Starfish\")\n\n    return annotations,video_id,video_frame\n\n\n[real_frame, video_id,video_frame] = annotations()\n\n\ndef K_mean(real_frame, num_shape):\n    weight_height = []\n    for i in range(0, len(real_frame)):\n            for j in range(0, int(len(real_frame[i]) / 4)):\n                weight_height.append([int(real_frame[i][4 * j + 2]), int(real_frame[i][4 * j + 3])])\n    km = KMeans(n_clusters=num_shape, init='k-means++', max_iter=60)\n\n    km.fit(weight_height)\n    centroids = km.cluster_centers_\n    centroids_int = []\n    for lines in centroids:\n        centroids_int.append(list(map(round, lines)))\n    # y_kmean = km.predict(weight_height)\n    # plt.scatter(x = weight,y = height,c = y_kmean)\n    # plt.scatter(centroids[:, 0], centroids[:, 1], c='red', s=10, alpha=0.7)\n    # plt.xlabel('weight')\n    # plt.ylabel('height')\n    # plt.show()\n    # print(centroids)\n    return centroids_int\n\n\n\nlikely_size_frame = K_mean(real_frame, num_shape)\n\n\ndef plot_boxes_on_image(show_image_with_boxes, real_frame, color=[0, 0, 255], thickness=2):\n    for i in range(0, len(real_frame)):\n        cv2.rectangle(show_image_with_boxes,\n                      pt1=(int(real_frame[i][1]), int(real_frame[i][0])),\n                      pt2=(int(real_frame[i][1]) + int(real_frame[i][2]),\n                           int(real_frame[i][0]) + int(real_frame[i][3])), color=color, thickness=thickness)\n    show_image_with_boxes = cv2.cvtColor(show_image_with_boxes, cv2.COLOR_BGR2RGB)\n    return show_image_with_boxes\n\n\ndef sorce(frame_0, frame_1):\n    inter_width = np.minimum(frame_0[0] + frame_0[2], frame_1[0] + frame_1[2]) - np.maximum(frame_0[0], frame_1[0])\n    inter_height = np.minimum(frame_0[1] + frame_0[3], frame_1[1] + frame_1[3]) - np.maximum(frame_0[1], frame_1[1])\n    if inter_width <= 0 or inter_height <= 0:\n        return -1\n    else:\n        intersection = inter_width * inter_height\n\n        frame_0_area = frame_0[2] * frame_0[3]\n        frame_1_area = frame_1[2] * frame_1[3]\n\n        union = frame_0_area + frame_1_area - intersection  # 并集的面积\n        return intersection / union\n\n\ndef bounding_box_regression(frame, truth):\n    target_reg = np.zeros(shape=4)\n    target_reg[0] = (truth[0] - frame[0]) / frame[2]\n    target_reg[1] = (truth[1] - frame[1]) / frame[3]\n    target_reg[2] = np.log(truth[2] / frame[2])\n    target_reg[3] = np.log(truth[3] / frame[3])\n\n    return target_reg\n\n\ndef decode_output(pred_bboxes, pred_scores, score_thresh=0.5):\n    grid_width = grid_height = 16\n    positive_boxes = []\n    positive_scores = []\n    target_masks = np.zeros(shape=[45, 80, num_shape])  # negative_samples: -1, positive_samples: 1\n    for i in range(45):\n        for j in range(80):\n            for k in range(num_shape):\n                if pred_scores[i,j,k] > score_thresh:\n\n                    center_x = j * grid_width + grid_width * 0.5\n                    center_y = i * grid_height + grid_height * 0.5\n                    xmin = center_x - likely_size_frame[k][0] * 0.5+pred_bboxes[0,i,j,k,0]\n                    ymin = center_y - likely_size_frame[k][1] * 0.5+pred_bboxes[0,i,j,k,1]\n                    positive_boxes.append([xmin, ymin, likely_size_frame[k][0]*np.exp(pred_bboxes[0,i,j,k,2]), likely_size_frame[k][1]*np.exp(pred_bboxes[0,i,j,k,3])])\n\n                    positive_scores.append(pred_scores[i,j,k])\n    return positive_scores, positive_boxes\n    # grid_x, grid_y = tf.range(80, dtype=tf.int32), tf.range(45, dtype=tf.int32)\n    # grid_x, grid_y = tf.meshgrid(grid_x, grid_y)\n    # grid_x, grid_y = tf.expand_dims(grid_x, -1), tf.expand_dims(grid_y, -1)\n    # grid_xy = tf.stack([grid_x, grid_y], axis=-1)\n    # center_xy = grid_xy * 16\n    # center_xy = tf.cast(center_xy, tf.float32)\n    # quarter_likely_size_frame = []\n    # # for i in range(len(likely_size_frame)):\n    # #     quarter_likely_size_frame.append([int(likely_size_frame[i][0]*0.5),int(likely_size_frame[i][1]*0.5)])\n    #\n    # # anchor_xymin = center_xy - quarter_likely_size_frame\n    # size = likely_size_frame * tf.exp(pred_bboxes[..., 2:4])\n    # xy_min = tf.exp(pred_bboxes[..., 0:1]) + center_xy\n    #\n    # pred_bboxes = tf.concat([xy_min, size], axis=-1)\n    # pred_scores = pred_scores[..., 1]\n    # score_mask = pred_scores > score_thresh\n    # ovo_bboxes = pred_bboxes[score_mask]\n    # ovo_scores = pred_scores[score_mask]\n    # pred_bboxes_0 = tf.reshape(pred_bboxes[score_mask], shape=[-1, 4]).numpy()\n    # pred_scores_0 = tf.reshape(pred_scores[score_mask], shape=[-1, ]).numpy()\n    # return pred_scores_0, pred_bboxes_0\n\n\ndef nms(pred_boxes, pred_score, iou_thresh):\n    selected_boxes = []\n    selected_scores = []\n    n = 0\n    while len(pred_boxes) > 0 and n < 10:\n        n += 1\n        max_idx = pred_score.index(max(pred_score))\n        selected_box = pred_boxes[max_idx]\n        selected_score = pred_score[max_idx]\n        selected_boxes.append(selected_box)\n        selected_scores.append(selected_score)\n        best_id = [True]*len(pred_boxes)\n        best_id[max_idx] = False\n        # pred_boxes = np.concatenate([pred_boxes[:max_idx], pred_boxes[max_idx + 1:]])\n        # pred_score = np.concatenate([pred_score[:max_idx], pred_score[max_idx + 1:]])\n        pred_boxes = np.array(pred_boxes)[best_id]\n        pred_score = np.array(pred_score)[best_id]\n        next_pred_boxes = []\n        next_pred_score = []\n        for i in range(len(pred_boxes)):\n            ious = sorce(selected_box, pred_boxes[i])\n\n            if ious >= iou_thresh:\n                next_pred_boxes.append(pred_boxes[i])\n                next_pred_score.append(pred_score[i])\n\n        pred_boxes = next_pred_boxes\n        pred_score = next_pred_score\n\n    # selected_boxes = np.array(selected_boxes)\n    # selected_scores = np.array(selected_scores)\n    return selected_boxes, selected_scores\n\n\nclass RPNplus(tf.keras.Model):\n    # VGG_MEAN = [103.939, 116.779, 123.68]\n    def __init__(self):\n        super(RPNplus, self).__init__()\n        # conv1\n        self.conv1_1 = tf.keras.layers.Conv2D(64, 3, activation='relu', padding='same')\n        #self.conv1_2 = tf.keras.layers.Conv2D(64, 3, activation='relu', padding='same')\n        self.pool1 = tf.keras.layers.MaxPooling2D(2, strides=2, padding='same')\n\n        # conv2\n        self.conv2_1 = tf.keras.layers.Conv2D(128, 3, activation='relu', padding='same')\n        #self.conv2_2 = tf.keras.layers.Conv2D(128, 3, activation='relu', padding='same')\n        self.pool2 = tf.keras.layers.MaxPooling2D(2, strides=2, padding='same')\n\n        # conv3\n        self.conv3_1 = tf.keras.layers.Conv2D(256, 3, activation='relu', padding='same')\n        #self.conv3_2 = tf.keras.layers.Conv2D(256, 3, activation='relu', padding='same')\n        #self.conv3_3 = tf.keras.layers.Conv2D(256, 3, activation='relu', padding='same')\n        self.pool3 = tf.keras.layers.MaxPooling2D(2, strides=2, padding='same')\n\n        # conv4\n        self.conv4_1 = tf.keras.layers.Conv2D(512, 3, activation='relu', padding='same')\n        #self.conv4_2 = tf.keras.layers.Conv2D(512, 3, activation='relu', padding='same')\n        #self.conv4_3 = tf.keras.layers.Conv2D(512, 3, activation='relu', padding='same')\n        self.pool4 = tf.keras.layers.MaxPooling2D(2, strides=2, padding='same')\n\n        # conv5\n        self.conv5_1 = tf.keras.layers.Conv2D(512, 3, activation='relu', padding='same')\n        #self.conv5_2 = tf.keras.layers.Conv2D(512, 3, activation='relu', padding='same')\n        #self.conv5_3 = tf.keras.layers.Conv2D(512, 3, activation='relu', padding='same')\n        self.pool5 = tf.keras.layers.MaxPooling2D(2, strides=2, padding='same')\n\n        ## region_proposal_conv\n        self.region_proposal_conv1 = tf.keras.layers.Conv2D(256, kernel_size=[5, 2],\n                                                            activation=tf.nn.relu,\n                                                            padding='same', use_bias=False)\n        self.region_proposal_conv2 = tf.keras.layers.Conv2D(512, kernel_size=[5, 2],\n                                                            activation=tf.nn.relu,\n                                                            padding='same', use_bias=False)\n        self.region_proposal_conv3 = tf.keras.layers.Conv2D(512, kernel_size=[5, 2],\n                                                            activation=tf.nn.relu,\n                                                            padding='same', use_bias=False)\n        ## Bounding Boxes Regression layer\n        self.bboxes_conv = tf.keras.layers.Conv2D(num_shape*4, kernel_size=[1, 1],\n                                                  padding='same', use_bias=False)\n        ## Output Scores layer\n        self.scores_conv = tf.keras.layers.Conv2D(num_shape*2, kernel_size=[1, 1],\n                                                  padding='same', use_bias=False)\n\n    def call(self, x, training=False):\n        h = self.conv1_1(x)\n        #h = self.conv1_2(h)\n        h = self.pool1(h)\n\n        h = self.conv2_1(h)\n        #h = self.conv2_2(h)\n        h = self.pool2(h)\n\n        h = self.conv3_1(h)\n        #h = self.conv3_2(h)\n        #h = self.conv3_3(h)\n        h = self.pool3(h)\n        # Pooling to same size\n        pool3_p = tf.nn.max_pool2d(h, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],\n                                   padding='SAME', name='pool3_proposal')\n        pool3_p = self.region_proposal_conv1(pool3_p)  # [1, 45, 60, 256]\n\n        h = self.conv4_1(h)\n       # h = self.conv4_2(h)\n        #h = self.conv4_3(h)\n        h = self.pool4(h)\n        pool4_p = self.region_proposal_conv2(h)  # [1, 45, 60, 512]\n\n        h = self.conv5_1(h)\n        #h = self.conv5_2(h)\n        #h = self.conv5_3(h)\n        pool5_p = self.region_proposal_conv2(h)  # [1, 45, 60, 512]\n\n        region_proposal = tf.concat([pool3_p, pool4_p, pool5_p], axis=-1)  # [1, 45, 60, 1280]\n\n        conv_cls_scores = self.scores_conv(region_proposal)  # [1, 45, 60, 18]\n        conv_cls_bboxes = self.bboxes_conv(region_proposal)  # [1, 45, 60, 36]\n\n        cls_scores = tf.reshape(conv_cls_scores, [batch_size, 45, 80, num_shape, 2])\n        cls_bboxes = tf.reshape(conv_cls_bboxes, [batch_size, 45, 80, num_shape, 4])\n\n        return cls_scores, cls_bboxes\n\n\ndef step_1(test_frame_0):\n    pos_thresh = 0.5\n    neg_thresh = 0.1\n    grid_width = 16\n    grid_height = 16\n    num_shape = len(likely_size_frame)\n    target_scores = np.zeros(shape=[45, 80, num_shape, 2])  # 0: background, 1: starfish,\n    target_regression = np.zeros(shape=[45, 80, num_shape, 4])  # t_x, t_y, t_w, t_h Return to the direction\n    target_masks = np.zeros(shape=[45, 80, num_shape])  # negative_samples: -1, positive_samples: 1\n    for i in range(45):\n        for j in range(80):\n            for k in range(num_shape):\n                center_x = j * grid_width + grid_width * 0.5\n                center_y = i * grid_height + grid_height * 0.5\n                xmin = center_x - likely_size_frame[k][0] * 0.5\n                ymin = center_y - likely_size_frame[k][1] * 0.5\n                anchor_boxes = np.array([xmin, ymin, likely_size_frame[k][0], likely_size_frame[k][1]])\n                num_test_frame = int(len(test_frame_0) / 4)\n                ious = np.zeros(num_test_frame)\n                # if j == 34 and i == 13:\n                #     print(\"here\")\n\n                for l in range(num_test_frame):\n                    test_frame = test_frame_0[0 + 4 * l:4 + 4 * l]\n                    ious[l] = (sorce(anchor_boxes, test_frame))\n\n                positive_masks = ious > pos_thresh\n                negative_masks = ious < neg_thresh\n                if np.any(positive_masks):\n                    target_scores[i, j, k, 1] = 1.\n                    target_masks[i, j, k] = 1  # labeled as a positive sample\n                    # find out which ground-truth box matches this anchor\n                    max_iou_idx = np.argmax(ious)\n                    selected_gt_boxes = test_frame_0[4*max_iou_idx:4*max_iou_idx+4]\n                    target_regression[i, j, k] = bounding_box_regression(anchor_boxes, selected_gt_boxes)\n\n\n                if np.all(negative_masks):\n                    target_scores[i, j, k, 0] = 1.\n                    target_masks[i, j, k] = -1  # labeled as a negative sample\n\n    return target_scores, target_regression, target_masks\n\ndef process_image_label(image_path):\n    raw_image = cv2.imread(image_path)\n    split = re.split('\\W', image_path)\n    id = int(split[-3][-1])\n    frame = int(split[-2])\n\n    test_frame_0 = real_frame[(video_id==id)*(video_frame == frame)]\n\n    return raw_image, test_frame_0[0]\n\ndef create_image_path_generator(dataset_path):\n    # while True:\n        print(\"new round\")\n        for dirname, _, filenames in os.walk(dataset_path):\n            for filename in filenames:\n                path = os.path.join(dirname, filename)\n                yield path\n                # try:\n                #     path = os.path.join(dirname, filename)\n                #     yield path\n                # except StopIteration:\n                #     continue\n\n\n        # for i in [0, 1, 2]:\n        #     print(\"new round\")\n        #     j = 0\n        #     for line in video_frame_3[i]:\n        #         try:\n        #             image_paths = dataset_path + str(i) + \"/\" + str(line) + \".jpg\"\n        #             test_frame_0 = real_frame_3[i][j]\n        #             j+=1\n        #             if test_frame_0 == []:\n        #                 continue\n        #             yield image_paths, test_frame_0\n        #         except StopIteration:\n        #             continue\n\n\ndef Generator():\n    image_label_path_generator = create_image_path_generator(trainset_path)\n    while True:\n        # try:\n\n        images = np.zeros(shape=[batch_size, 720, 1280, 3], dtype=float)\n        target_scores = np.zeros(shape=[batch_size, 45, 80, num_shape, 2], dtype=float)\n        target_bboxes = np.zeros(shape=[batch_size, 45, 80, num_shape, 4], dtype=float)\n        target_masks = np.zeros(shape=[batch_size, 45, 80, num_shape], dtype=int)\n        for i in range(batch_size):\n            while True:\n                try:\n                    image_path = next(image_label_path_generator)\n                except StopIteration:\n                    image_label_path_generator = create_image_path_generator(trainset_path)\n                    image_path = next(image_label_path_generator)\n                image, test_frame_0 = process_image_label(image_path)\n                if test_frame_0 != []:\n                    break\n            target = step_1(test_frame_0)\n            images[i] = image\n            target_scores[i] = target[0]\n            target_bboxes[i] = target[1]\n            target_masks[i] = target[2]\n        yield images, target_scores, target_bboxes, target_masks\n        #     yield images, target_scores, target_bboxes, target_masks\n        # except StopIteration:\n        #     print('omo')\n        #     return\n\n\ndef compute_loss(target_scores, target_bboxes, target_masks, pred_scores, pred_bboxes):\n    score_loss = tf.nn.softmax_cross_entropy_with_logits(labels=target_scores, logits=pred_scores)\n    foreground_background_mask = (np.abs(target_masks) == 1).astype(int)\n    score_loss = tf.reduce_sum(score_loss * foreground_background_mask, axis=[1, 2, 3]) / (\n                np.sum(foreground_background_mask) + 0.00001)\n    score_loss = tf.reduce_mean(score_loss)\n\n    boxes_loss = tf.abs(target_bboxes - pred_bboxes)\n    boxes_loss = 0.5 * tf.pow(boxes_loss, 2) * tf.cast(boxes_loss < 1, tf.float32) + (boxes_loss - 0.5) * tf.cast(\n        boxes_loss >= 1, tf.float32)\n    boxes_loss = tf.reduce_sum(boxes_loss, axis=-1)\n    foreground_mask = (target_masks > 0).astype(np.float32)\n\n    boxes_loss = tf.reduce_sum(boxes_loss * foreground_mask, axis=[1, 2, 3]) / (np.sum(foreground_mask) + 1)\n    boxes_loss = tf.reduce_mean(boxes_loss)\n\n    return score_loss, boxes_loss","metadata":{"execution":{"iopub.status.busy":"2022-02-14T20:26:11.479417Z","iopub.execute_input":"2022-02-14T20:26:11.479677Z","iopub.status.idle":"2022-02-14T20:26:13.409651Z","shell.execute_reply.started":"2022-02-14T20:26:11.479643Z","shell.execute_reply":"2022-02-14T20:26:13.408934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train():\n    # real_frame = annotations()\n    # num_shape = 30\n    # likely_size_frame = np.array(K_mean(real_frame, num_shape))\n    print(\"hello world\")\n    iterator  = Generator()\n\n\n    model = RPNplus()\n    optimizer = tf.keras.optimizers.Adam(learning_rate=0.01)\n    writer = tf.summary.create_file_writer(\"./log\")\n    global_steps = tf.Variable(0, trainable=False, dtype=tf.int64)\n    epoch_i = 0\n    while epoch_i < EPOCHS:\n        for step in range(STEPS):\n            global_steps.assign_add(1)\n            image_data, target_scores, target_bboxes, target_masks = next(iterator)\n            with tf.GradientTape() as tape:\n                pred_scores, pred_bboxes = model(image_data)\n                # print(\"ovo\")\n                score_loss, boxes_loss = compute_loss(target_scores, target_bboxes, target_masks, pred_scores,\n                                                      pred_bboxes)\n                total_loss = score_loss + lambda_scale * boxes_loss\n                gradients = tape.gradient(total_loss, model.trainable_variables)\n                optimizer.apply_gradients(zip(gradients, model.trainable_variables))\n                print(\n                    \"=> epoch %d  step %d  total_loss: %.6f  score_loss: %.6f  boxes_loss: %.6f\" % (epoch_i + 1, step + 1,\n                                                                                                    total_loss.numpy(),\n                                                                                                    score_loss.numpy(),\n                                                                                                    boxes_loss.numpy()))\n            # writing summary data\n            with writer.as_default():\n                tf.summary.scalar(\"total_loss\", total_loss, step=global_steps)\n                tf.summary.scalar(\"score_loss\", score_loss, step=global_steps)\n                tf.summary.scalar(\"boxes_loss\", boxes_loss, step=global_steps)\n            writer.flush()\n        model.save_weights(\"RPN.npy\")\n        epoch_i+=1","metadata":{"execution":{"iopub.status.busy":"2022-02-14T20:26:13.411125Z","iopub.execute_input":"2022-02-14T20:26:13.411360Z","iopub.status.idle":"2022-02-14T20:26:13.422410Z","shell.execute_reply.started":"2022-02-14T20:26:13.411329Z","shell.execute_reply":"2022-02-14T20:26:13.421789Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test():\n    iterator  = create_image_path_generator(testset_path)\n\n    model = RPNplus()\n    model.load_weights(\"RPN.npy\")\n    result = []\n    for (pixel_array, sample_prediction_df) in iter_test:\n#     sample_prediction_df['annotations'] = '0.5 0 0 100 100'  # make your predictions here\n#     env.predict(sample_prediction_df)\n#     while True:\n#         try:\n#             image_path = next(iterator)\n#             split = re.split('\\W', image_path)\n#             frame = int(split[-2])\n#             raw_image = cv2.imread(image_path)\n        images = np.zeros(shape=[1, 720, 1280, 3])\n        images[0] = pixel_array\n        pred_scores, pred_bboxes = model(images)\n        pred_scores = np.array(pred_scores[0,:,:,:,1])\n        pred_bboxes = np.array(pred_bboxes)\n        pred_scores, pred_bboxes = decode_output(pred_bboxes, pred_scores, 0)\n        pred_bboxes,pred_scores = nms(pred_bboxes, pred_scores, 0.5)\n        text = \"\"\n        for i in range(len(pred_scores)):\n            text = text+str(pred_scores[i])+\" \"\n            for j in range(4):\n                text = text + str(pred_bboxes[i][j]) + \" \"\n        text = text[0:-1] # resuce the last space\n        print(text)\n        sample_prediction_df['annotations'] = test\n        result.append(text)\n        env.predict(sample_prediction_df)\n\n    df = pd.DataFrame(result)\n    df.to_csv('submission.csv')","metadata":{"execution":{"iopub.status.busy":"2022-02-14T20:26:13.424469Z","iopub.execute_input":"2022-02-14T20:26:13.424944Z","iopub.status.idle":"2022-02-14T20:26:13.438194Z","shell.execute_reply.started":"2022-02-14T20:26:13.424908Z","shell.execute_reply":"2022-02-14T20:26:13.437509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train()\ntest()","metadata":{"execution":{"iopub.status.busy":"2022-02-14T20:26:13.439651Z","iopub.execute_input":"2022-02-14T20:26:13.439921Z","iopub.status.idle":"2022-02-14T20:26:42.957489Z","shell.execute_reply.started":"2022-02-14T20:26:13.439887Z","shell.execute_reply":"2022-02-14T20:26:42.955030Z"},"trusted":true},"execution_count":null,"outputs":[]}]}