{"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":"%matplotlib inline\n#這是juoyter notebook的magic word˙\n\nimport matplotlib\nimport matplotlib.pyplot as plt\nfrom IPython import display","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-05T09:04:49.579030Z","iopub.execute_input":"2022-07-05T09:04:49.579539Z","iopub.status.idle":"2022-07-05T09:04:49.590705Z","shell.execute_reply.started":"2022-07-05T09:04:49.579445Z","shell.execute_reply":"2022-07-05T09:04:49.589754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Steel Defect 瑕疵分割\n","metadata":{}},{"cell_type":"code","source":"import os\n#判斷是否在jupyter notebook上\ndef is_in_ipython():\n    \"Is the code running in the ipython environment (jupyter including)\"\n    program_name = os.path.basename(os.getenv('_', ''))\n\n    if ('jupyter-notebook' in program_name or # jupyter-notebook\n        'ipython'          in program_name or # ipython\n        'jupyter' in program_name or  # jupyter\n        'JPY_PARENT_PID'   in os.environ):    # ipython-notebook\n        return True\n    else:\n        return False\n\n\n#判斷是否在colab上\ndef is_in_colab():\n    if not is_in_ipython(): return False\n    try:\n        from google import colab\n        return True\n    except: return False\n\n#判斷是否在kaggke_kernal上\ndef is_in_kaggle_kernal():\n    if 'kaggle' in os.environ['PYTHONPATH']:\n        return True\n    else:\n        return False\n\nif is_in_colab():\n    from google.colab import drive\n    drive.mount('/content/gdrive')","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:04:49.592490Z","iopub.execute_input":"2022-07-05T09:04:49.593193Z","iopub.status.idle":"2022-07-05T09:04:49.603432Z","shell.execute_reply.started":"2022-07-05T09:04:49.593135Z","shell.execute_reply":"2022-07-05T09:04:49.602427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.environ['TRIDENT_BACKEND'] = 'pytorch'\n\nif is_in_kaggle_kernal():\n    os.environ['TRIDENT_HOME'] = './trident'\n    \nelif is_in_colab():\n    os.environ['TRIDENT_HOME'] = '/content/gdrive/My Drive/trident'\n\n#為確保安裝最新版 \n!pip uninstall tridentx -y\n!pip install ../input/trident/tridentx-0.7.5-py3-none-any.whl --upgrade\nimport json\nimport copy\nimport numpy as np\n#調用trident api\nimport trident as T\nfrom trident import *\nfrom trident.models import resnet,efficientnet,bisenet,densenet\nimport random","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:04:49.605754Z","iopub.execute_input":"2022-07-05T09:04:49.606401Z","iopub.status.idle":"2022-07-05T09:04:59.718193Z","shell.execute_reply.started":"2022-07-05T09:04:49.606365Z","shell.execute_reply":"2022-07-05T09:04:59.717208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import glob\nimport pandas as pd\nimgs=glob.glob('../input/severstal-steel-defect-detection/train_images/*jpg')\nprint(len(imgs))\n\ndf_train=pd.read_csv('../input/severstal-steel-defect-detection/train.csv')\nprint(df_train)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:04:59.720022Z","iopub.execute_input":"2022-07-05T09:04:59.720564Z","iopub.status.idle":"2022-07-05T09:04:59.935157Z","shell.execute_reply.started":"2022-07-05T09:04:59.720521Z","shell.execute_reply":"2022-07-05T09:04:59.934253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_images_frequency=df_train['ImageId'].value_counts()\nprint(df_images_frequency)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:04:59.936422Z","iopub.execute_input":"2022-07-05T09:04:59.936769Z","iopub.status.idle":"2022-07-05T09:04:59.949976Z","shell.execute_reply.started":"2022-07-05T09:04:59.936731Z","shell.execute_reply":"2022-07-05T09:04:59.949033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"palette = [(0, 0, 0),(256, 192, 0), (0, 192, 256), (128, 0, 256), (256,64,0)]\n\ndef enc2mask(enc, shape=(1600,256),fill_value=0):\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    s = enc.split()\n    for i in range(len(s)//2):\n        start = int(s[2*i]) - 1\n        length = int(s[2*i+1])\n        img[start:start+length] = int(fill_value)\n    return img.reshape(shape).T\n\n\ndef mask2enc(mask, n=4):\n    pixels = mask.T.flatten()\n    encs = []\n    for i in range(1,n+1):\n        p = (pixels == i).astype(np.int8)\n        if p.sum() == 0: encs.append('')\n        else:\n            p = np.concatenate([[0], p, [0]])\n            runs = np.where(p[1:] != p[:-1])[0] + 1\n            runs[1::2] -= runs[::2]\n            encs.append(' '.join(str(x) for x in runs))\n    return encs\n\n\ndef label2color(label_mask,palette):\n    num_classes = len(palette)\n\n    color_label= np.zeros((*label_mask.shape,3)).astype(np.int64)\n    for i in range(num_classes):\n        color_label[label_mask==i]=palette[i]\n    return color_label","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:04:59.951427Z","iopub.execute_input":"2022-07-05T09:04:59.951773Z","iopub.status.idle":"2022-07-05T09:04:59.966932Z","shell.execute_reply.started":"2022-07-05T09:04:59.951739Z","shell.execute_reply":"2022-07-05T09:04:59.966035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train['mask'] = df_train.apply(lambda row: enc2mask(enc=row.EncodedPixels,fill_value=row.ClassId),axis=1)\nprint(df_train)","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:04:59.968195Z","iopub.execute_input":"2022-07-05T09:04:59.968667Z","iopub.status.idle":"2022-07-05T09:05:04.882256Z","shell.execute_reply.started":"2022-07-05T09:04:59.968502Z","shell.execute_reply":"2022-07-05T09:05:04.881369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(10):\n    exsample_mask=df_train['mask'].iloc[i]\n    print(exsample_mask.shape)\n    print(exsample_mask.max())\n","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:05:04.884876Z","iopub.execute_input":"2022-07-05T09:05:04.885231Z","iopub.status.idle":"2022-07-05T09:05:04.897726Z","shell.execute_reply.started":"2022-07-05T09:05:04.885201Z","shell.execute_reply":"2022-07-05T09:05:04.896734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"exsample_mask=df_train['mask'].iloc[3]\nexsample_image=image2array('../input/severstal-steel-defect-detection/train_images/'+df_train['ImageId'].iloc[3])\nprint(exsample_mask.max())\ndisplay.display(array2image(exsample_mask))\n\nis_mask=np.expand_dims(np.greater(exsample_mask,0).astype(np.float32),-1)\ncolor_mask=label2color(exsample_mask,palette)\n\n\ndisplay.display(array2image(label2color(exsample_mask,palette)))\ndisplay.display(array2image(exsample_image))\n\ndisplay.display(array2image(0.5*exsample_image+0.5*(1-is_mask)*exsample_image+0.5*is_mask*color_mask))\n","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:05:04.899343Z","iopub.execute_input":"2022-07-05T09:05:04.899692Z","iopub.status.idle":"2022-07-05T09:05:05.349416Z","shell.execute_reply.started":"2022-07-05T09:05:04.899656Z","shell.execute_reply":"2022-07-05T09:05:05.347999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"masked_dict=OrderedDict()\n\nfor index, row in df_train.iterrows():\n    img_key='../input/severstal-steel-defect-detection/train_images/'+row['ImageId']\n    if img_key not in masked_dict:\n        masked_dict[img_key]=row['mask']\n    else:\n        masked_dict[img_key]=masked_dict[img_key]+row['mask']\n\nprint(len(masked_dict))","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:05:05.350731Z","iopub.execute_input":"2022-07-05T09:05:05.351343Z","iopub.status.idle":"2022-07-05T09:05:06.046001Z","shell.execute_reply.started":"2022-07-05T09:05:05.351305Z","shell.execute_reply":"2022-07-05T09:05:06.045091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"你如果試圖要把所有mask生成出來，很快你會超過kaggle記憶體上限造成notebook重啟，而若是一張一張存檔來調用看起來可行，可是會佔用不少","metadata":{}},{"cell_type":"code","source":"class MyMaskDataset(MaskDataset):\n    def __init__(self, masks, class_names=None, symbol=\"mask\", **kwargs):\n        super().__init__(masks,class_names=class_names, symbol=symbol, object_type=ObjectType.label_mask, **kwargs)\n     \n    def __getitem__(self, index: int):\n        img_id = self.items[index]  # self.pop(index)\n        if img_id in masked_dict:\n            return masked_dict[img_id].astype(np.int64)\n        else:\n            return np.zeros((256,1600,3),dtype=np.int64)\n        \n#如果是mask非零則ok，否則只有20%機率取用\nsample_filter=lambda x:x[-1].max()>0 #or random.random()>0.9\n\nds1=ImageDataset(list(masked_dict.keys()),symbol='image')\nds2=MyMaskDataset(list(masked_dict.keys()),symbol='mask')\n\n#設定調色盤\nfor i in range(5):\n    ds2.palette[i] =palette[i]\n\ndata_provider=DataProvider(traindata=Iterator(data=ds1,label=ds2,sample_filter=sample_filter))\ndata_provider.paired_transform_funcs=[\n    RandomTransformAffine(rotation_range=5, zoom_range=0.00, shift_range=0.00, shear_range=0.1, random_flip=0.15 ,border_mode='zero'),\n    RandomRescaleCrop((224,224),scale=(0.8,1.2))]\n\ndata_provider.image_transform_funcs=[\n                     AddNoise(0.01),\n                     RandomAdjustGamma(gamma_range=(0.6,1.5)),\n                     RandomAdjustContrast(value_range=(0.6, 1.5)),\n                     RandomAdjustHue(value_range=(-0.5, 0.5)),\n                     Normalize(127.5,127.5)]\n        \n\nimg_data,mask_data=data_provider.next()\nprint(mask_data.shape)\nprint(mask_data.max())\n\n","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:05:06.047305Z","iopub.execute_input":"2022-07-05T09:05:06.047644Z","iopub.status.idle":"2022-07-05T09:05:09.491994Z","shell.execute_reply.started":"2022-07-05T09:05:06.047606Z","shell.execute_reply":"2022-07-05T09:05:09.490388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ndata_provider.preview_images()","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:05:09.493327Z","iopub.execute_input":"2022-07-05T09:05:09.493663Z","iopub.status.idle":"2022-07-05T09:05:09.977780Z","shell.execute_reply.started":"2022-07-05T09:05:09.493625Z","shell.execute_reply":"2022-07-05T09:05:09.976985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from trident.models import efficientnet,deeplab,bisenet,densenet\nbackbond_net=efficientnet.EfficientNetB0(pretrained=True,input_shape=(3,224,224))\nbackbond=backbond_net.model\nbackbond.trainable=False\ndeeplabv3=deeplab.DeeplabV3_plus(backbond,atrous_rates=(6,12,18,24),num_filters=256,classes=5)\ndeeplabv3.load_model('../input/steeldefect-sgment/Models/deeplabv3.pth.tar')\n#deeplabv3.load_model('./Models/deeplabv3.pth.tar')\ndeeplabv3.summary()\n","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:05:09.979326Z","iopub.execute_input":"2022-07-05T09:05:09.979890Z","iopub.status.idle":"2022-07-05T09:05:15.103780Z","shell.execute_reply.started":"2022-07-05T09:05:09.979851Z","shell.execute_reply":"2022-07-05T09:05:15.102971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tiramisu = densenet.DenseNetFcn(blocks=(4,4,5,5,6), growth_rate=16, initial_filters=32, num_classes=5)\ntiramisu.load_model('../input/steeldefect-sgment/Models/tiramisu.pth')\n#tiramisu.load_model('./Models/tiramisu.pth.tar')\ntiramisu.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:05:15.104973Z","iopub.execute_input":"2022-07-05T09:05:15.105329Z","iopub.status.idle":"2022-07-05T09:05:16.543610Z","shell.execute_reply.started":"2022-07-05T09:05:15.105290Z","shell.execute_reply":"2022-07-05T09:05:16.542795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bisenetmodel=ImageSegmentationModel(input_shape=(3,224,224), output=bisenet.BiSeNetV2(n_classes=5))\nbisenetmodel.load_model('../input/steeldefect-sgment/Models/bisenetmodel.pth.tar')\n#bisenetmodel.load_model('./Models/bisenetv2.pth.tar')\nbisenetmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:08:30.219762Z","iopub.execute_input":"2022-07-05T09:08:30.220144Z","iopub.status.idle":"2022-07-05T09:08:30.985611Z","shell.execute_reply.started":"2022-07-05T09:08:30.220111Z","shell.execute_reply":"2022-07-05T09:08:30.984803Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn.functional as F\n\ndef one_hot(label, n_classes):\n    \"\"\"Return One Hot Label\"\"\"\n    one_hot_label = torch.eye(n_classes, device=get_device())[label]\n    one_hot_label = one_hot_label.transpose(1, 3).transpose(2, 3)\n\n    return one_hot_label\n\ndef BoundaryLoss(output, target):\n    \"\"\"Boundary Loss proposed in:\n    Alexey Bokhovkin et al., Boundary Loss for Remote Sensing Imagery Semantic Segmentation\n    https://arxiv.org/abs/1905.07852\n    \"\"\"\n\n    theta0=3\n    theta=5\n    pred=exp(output)\n    gt=target\n    n, c, _, _ = pred.shape\n\n    # softmax so that predicted map can be distributed in [0, 1]\n\n\n    # one-hot vector of ground truth\n    one_hot_gt = one_hot(gt, c)\n\n    # boundary map\n    gt_b = F.max_pool2d(\n        1 - one_hot_gt, kernel_size=theta0, stride=1, padding=(theta0 - 1) // 2)\n    gt_b -= 1 - one_hot_gt\n\n    pred_b = F.max_pool2d(\n        1 - pred, kernel_size=theta0, stride=1, padding=(theta0 - 1) // 2)\n    pred_b -= 1 - pred\n\n    # extended boundary map\n    gt_b_ext = F.max_pool2d(\n        gt_b, kernel_size=theta, stride=1, padding=(theta - 1) // 2)\n\n    pred_b_ext = F.max_pool2d(\n        pred_b, kernel_size=theta, stride=1, padding=(theta - 1) // 2)\n\n    # reshape\n    gt_b = gt_b.view(n, c, -1)\n    pred_b = pred_b.view(n, c, -1)\n    gt_b_ext = gt_b_ext.view(n, c, -1)\n    pred_b_ext = pred_b_ext.view(n, c, -1)\n\n    # Precision, Recall\n    P = torch.sum(pred_b * gt_b_ext, dim=2) / (torch.sum(pred_b, dim=2) + 1e-7)\n    R = torch.sum(pred_b_ext * gt_b, dim=2) / (torch.sum(gt_b, dim=2) + 1e-7)\n\n    # Boundary F1 Score\n    BF1 = 2 * P * R / (P + R + 1e-7)\n\n    # summing BF1 Score for each class and average over mini-batch\n    loss = torch.mean(1 - BF1)\n\n    return loss\n\n","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:08:30.987392Z","iopub.execute_input":"2022-07-05T09:08:30.987740Z","iopub.status.idle":"2022-07-05T09:08:30.998740Z","shell.execute_reply.started":"2022-07-05T09:08:30.987702Z","shell.execute_reply":"2022-07-05T09:08:30.997898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def draw_seg_image(training_context):\n    data_feed = training_context['data_feed']\n    data = training_context['train_data']\n    model = training_context['current_model']\n    output_data=data[data_feed['output']]\n    target_data=to_numpy(data['mask'])\n    input_data=to_numpy(data['image'])\n    output_data=np.argmax(to_numpy(output_data),1)\n    tile_images_list=[]\n    input_arr = []\n    target_arr=[]\n    output_arr=[]\n    for i in range(len(output_data)):\n        input_arr.append(image_backend_adaption(data_provider.reverse_image_transform(input_data[i])))\n        target_arr.append(label2color(target_data[i],palette))\n        output_arr.append(label2color(output_data[i],palette))\n    tile_images_list.append(input_arr)\n    tile_images_list.append(target_arr)\n    tile_images_list.append(output_arr)\n    fig = tile_rgb_images(*tile_images_list, save_path='Results/segtile_image_{0}.png', imshow=True)\n    plt.close()\n        \n        \n    ","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:08:31.000574Z","iopub.execute_input":"2022-07-05T09:08:31.000934Z","iopub.status.idle":"2022-07-05T09:08:31.013851Z","shell.execute_reply.started":"2022-07-05T09:08:31.000898Z","shell.execute_reply":"2022-07-05T09:08:31.012648Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"deeplabv3.with_optimizer(optimizer=DiffGrad,lr=5e-4,betas=(0.9, 0.999),gradient_centralization='all')\\\n    .with_loss(DiceLoss(axis=1),loss_weight=2)\\\n    .with_loss(CrossEntropyLoss(ignore_index=0,axis=1))\\\n    .with_loss(BoundaryLoss)\\\n    .with_loss(CrossEntropyLoss(auto_balance=True,ignore_index=0,enable_ohem=True,ohem_thresh=0.1),loss_weight=0.2,start_epoch=10)\\\n    .with_loss(IoULoss,start_epoch=15)\\\n    .with_metric(pixel_accuracy,name='pixel_accuracy',print_only=True)\\\n    .with_metric(iou,name='iou')\\\n    .with_regularizer('l2',reg_weight=1e-5)\\\n    .with_learning_rate_scheduler(CosineLR(period=5000,unit='batch',max_lr=1e-3, min_lr=1e-6))\\\n    .with_model_save_path('Models/deeplabv3.pth') \\\n    .trigger_when(when='on_batch_end',frequency=50,action=draw_seg_image)\\\n    .with_automatic_mixed_precision_training()\n\n\ntiramisu.with_optimizer(optimizer=DiffGrad,lr=5e-4,betas=(0.9, 0.999),gradient_centralization='all')\\\n    .with_loss(DiceLoss(axis=1),loss_weight=2)\\\n    .with_loss(CrossEntropyLoss(ignore_index=0,axis=1))\\\n    .with_loss(BoundaryLoss)\\\n    .with_loss(CrossEntropyLoss(auto_balance=True,ignore_index=0,enable_ohem=True,ohem_thresh=0.1),loss_weight=0.2,start_epoch=10)\\\n    .with_loss(IoULoss,start_epoch=15)\\\n    .with_metric(pixel_accuracy,name='pixel_accuracy',print_only=True)\\\n    .with_metric(iou,name='iou')\\\n    .with_regularizer('l2',reg_weight=1e-5)\\\n    .with_learning_rate_scheduler(CosineLR(period=5000,unit='batch',max_lr=1e-3, min_lr=1e-6))\\\n    .with_model_save_path('Models/tiramisu.pth') \\\n    .trigger_when(when='on_batch_end',frequency=50,action=draw_seg_image)\\\n    .with_automatic_mixed_precision_training()\n\n\n\nbisenetmodel.with_optimizer(optimizer=DiffGrad,lr=5e-4,betas=(0.9, 0.999),gradient_centralization='all')\\\n    .with_loss(DiceLoss(axis=1),loss_weight=2)\\\n    .with_loss(CrossEntropyLoss(ignore_index=0,axis=1))\\\n    .with_loss(BoundaryLoss)\\\n    .with_loss(CrossEntropyLoss(auto_balance=True,ignore_index=0,enable_ohem=True,ohem_thresh=0.1),loss_weight=0.2,start_epoch=10)\\\n    .with_loss(IoULoss,start_epoch=15)\\\n    .with_metric(pixel_accuracy,name='pixel_accuracy',print_only=True)\\\n    .with_metric(iou,name='iou')\\\n    .with_regularizer('l2',reg_weight=1e-5)\\\n    .with_learning_rate_scheduler(CosineLR(period=5000,unit='batch',max_lr=1e-3, min_lr=1e-6))\\\n    .with_model_save_path('Models/bisenetmodel.pth') \\\n    .trigger_when(when='on_batch_end',frequency=50,action=draw_seg_image)\\\n    .with_automatic_mixed_precision_training()\n\n","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:08:31.016815Z","iopub.execute_input":"2022-07-05T09:08:31.017083Z","iopub.status.idle":"2022-07-05T09:08:31.102108Z","shell.execute_reply.started":"2022-07-05T09:08:31.017038Z","shell.execute_reply":"2022-07-05T09:08:31.101345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plan=TrainingPlan()\\\n    .add_training_item(deeplabv3,name='deeplabv3')\\\n    .add_training_item(tiramisu,name='tiramisu')\\\n    .add_training_item(bisenetmodel,name='bisenetmodel')\\\n    .with_data_loader(data_provider)\\\n    .repeat_epochs(30)\\\n    .with_batch_size(16)\\\n    .print_progress_scheduling(10,unit='batch')\\\n    .display_loss_metric_curve_scheduling(frequency=100,unit='batch',imshow=True)\\\n    .save_model_scheduling(20,unit='batch')\\","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:08:31.103324Z","iopub.execute_input":"2022-07-05T09:08:31.103670Z","iopub.status.idle":"2022-07-05T09:08:31.109745Z","shell.execute_reply.started":"2022-07-05T09:08:31.103634Z","shell.execute_reply":"2022-07-05T09:08:31.108817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plan.start_now()","metadata":{"execution":{"iopub.status.busy":"2022-07-05T09:08:31.111296Z","iopub.execute_input":"2022-07-05T09:08:31.111930Z"},"trusted":true},"execution_count":null,"outputs":[]}]}