{"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":"## MNIST - Hand-written digit classification\n### Libraries import","metadata":{"pycharm":{"name":"#%% md\n"},"id":"0xEfiGKgYnSu"}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport torch\nfrom torchvision import transforms\nfrom torch import nn, optim\nfrom torch.utils.data.sampler import SubsetRandomSampler, SequentialSampler\nimport csv\nfrom sklearn.metrics import confusion_matrix\nimport seaborn as sns\nimport time","metadata":{"pycharm":{"name":"#%%\n"},"id":"jlBeUj1wYnSx","executionInfo":{"status":"ok","timestamp":1632680801428,"user_tz":-180,"elapsed":514,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"execution":{"iopub.status.busy":"2021-09-26T22:23:16.988919Z","iopub.execute_input":"2021-09-26T22:23:16.989252Z","iopub.status.idle":"2021-09-26T22:23:22.504181Z","shell.execute_reply.started":"2021-09-26T22:23:16.989151Z","shell.execute_reply":"2021-09-26T22:23:22.503460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Colab settings","metadata":{"id":"FItBe5NYi6Gs"}},{"cell_type":"code","source":"try:\n  import google.colab\n  colab = True\nexcept:\n  colab = False\nframe_color = 'black'\ngpu = torch.cuda.is_available()\nif colab:\n    dir = 'drive/MyDrive/studies/My projects/data'\nelse:\n    dir = '/kaggle/input/digit-recognizer/'\nprint(gpu)","metadata":{"id":"MAPOdOyjjCXc","executionInfo":{"status":"ok","timestamp":1632680801971,"user_tz":-180,"elapsed":9,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"5c598be4-fe95-40b0-918f-58c37a76a563","execution":{"iopub.status.busy":"2021-09-26T22:23:22.505811Z","iopub.execute_input":"2021-09-26T22:23:22.506053Z","iopub.status.idle":"2021-09-26T22:23:22.552361Z","shell.execute_reply.started":"2021-09-26T22:23:22.506021Z","shell.execute_reply":"2021-09-26T22:23:22.551566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data import and visualization","metadata":{"id":"CZdjhJ5-YnSy"}},{"cell_type":"code","source":"tav_data_csv = pd.read_csv(dir + 'train.csv')\ntest_data_csv = pd.read_csv(dir + 'test.csv')\ndir = './'\nclass MNIST(torch.utils.data.Dataset):\n    def __init__(self, data, transformer=None, is_test_set=False):\n        self.data = data\n        self.transform = transformer\n        self.is_test_set=is_test_set\n\n    def __len__(self):\n        return len(self.data)\n\n    def __getitem__(self, index):\n        item = self.data.iloc[index]\n        if self.is_test_set:\n            img = item.values.astype(np.uint8).reshape(28,28)\n            if self.transform is not None:\n                img = self.transform(img)\n            return img\n        else:\n            img = item[1:].values.astype(np.uint8).reshape(28,28)\n            label = item[0]\n            if self.transform is not None:\n                img = self.transform(img)\n            return img, label\n\n\ntransform = transforms.Compose([transforms.ToPILImage(),\n                                transforms.ToTensor(),\n                                transforms.Normalize(mean=(0.5,), std=(0.5,))])\n\ntav_data = MNIST(tav_data_csv,transform)\ntav_split = 0.85\nindices = list(range(len(tav_data)))\nnp.random.shuffle(indices)\nsplit = int(np.floor((1-tav_split) * len(tav_data)))\ntrain_indices, val_indices = indices[split:], indices[:split]\n\ntrain_sampler = SubsetRandomSampler(train_indices)\nval_sampler =  SequentialSampler(val_indices)\n\nbatch_size = 256\ntrain_loader = torch.utils.data.DataLoader(tav_data, batch_size=batch_size, sampler=train_sampler)\nval_loader = torch.utils.data.DataLoader(tav_data, batch_size=batch_size, sampler=val_sampler)\nprint(f\"Length train: {len(train_indices)}\")\nprint(f\"Length valid: {len(val_indices)}\")","metadata":{"pycharm":{"name":"#%%\n"},"id":"FaNfPmI8YnSz","executionInfo":{"status":"ok","timestamp":1632680806382,"user_tz":-180,"elapsed":4416,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"55ea51d5-d699-4b08-9240-3c0c37dfbf80","execution":{"iopub.status.busy":"2021-09-26T22:23:22.553989Z","iopub.execute_input":"2021-09-26T22:23:22.554523Z","iopub.status.idle":"2021-09-26T22:23:27.598842Z","shell.execute_reply.started":"2021-09-26T22:23:22.554463Z","shell.execute_reply":"2021-09-26T22:23:27.598183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data visualization","metadata":{"pycharm":{"name":"#%% md\n"},"id":"soMqNHwxYnS1"}},{"cell_type":"code","source":"print(tav_data_csv.shape)\nprint(test_data_csv.shape)\nlabel_train = tav_data_csv.label\nplt.tick_params(colors=frame_color)\nplt.hist(label_train, rwidth=0.85)\nplt.xticks(range(10))\nplt.xlabel('Class', color=frame_color)\nplt.ylabel('Examples', color=frame_color)\nplt.show()\nfig = plt.figure(figsize=(10,5))\nimages, labels = next(iter(train_loader))\nfor i in range(16):\n    fig.add_subplot(4, 4, i+1)\n    plt.imshow(images[i].reshape(28,28), cmap='gray')\n    plt.axis('off')\n    plt.tight_layout()\n    plt.title('Digit: ' + str(int(labels[i])),color=frame_color)","metadata":{"pycharm":{"name":"#%%\n"},"id":"ZqgTtFEqYnS1","executionInfo":{"status":"ok","timestamp":1632680808166,"user_tz":-180,"elapsed":1795,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"9a8d017d-a64f-4a45-d923-e0d0ed7f1714","execution":{"iopub.status.busy":"2021-09-26T22:23:27.603232Z","iopub.execute_input":"2021-09-26T22:23:27.605241Z","iopub.status.idle":"2021-09-26T22:23:29.173987Z","shell.execute_reply.started":"2021-09-26T22:23:27.605188Z","shell.execute_reply":"2021-09-26T22:23:29.173264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Model building","metadata":{"id":"p27uZWUFYnS3"}},{"cell_type":"code","source":"class DCmodel(torch.nn.Module):\n    def __init__(self):\n        super(DCmodel, self).__init__()\n        self.conv1 = nn.Sequential(nn.Conv2d(1,16,(3,3),padding=1),\n                                   nn.ReLU(),\n                                   nn.Conv2d(16,16,(3,3),padding=1),\n                                   nn.ReLU(),\n                                   nn.BatchNorm2d(16))\n        self.max_pool = nn.Sequential(nn.MaxPool2d(2))\n        self.conv2 = nn.Sequential(nn.Conv2d(16,32,(3,3),padding=1),\n                                   nn.ReLU(),\n                                   nn.Conv2d(32,32,(3,3),padding=1),\n                                   nn.ReLU(),\n                                   nn.BatchNorm2d(32))\n        self.conv3 = nn.Sequential(nn.Conv2d(32,64,(3,3),padding=1),\n                                   nn.ReLU(),\n                                   nn.Conv2d(64,64,(3,3),padding=1),\n                                   nn.ReLU(),\n                                   nn.BatchNorm2d(64))\n        self.fc1 = nn.Sequential(nn.Linear(3136,256),\n                                 nn.ReLU())\n        self.fc2 = nn.Linear(256, 10)\n\n    def forward(self,x):\n        x = self.conv1(x) + x\n        x = self.max_pool(x)\n        doublex = torch.stack([x,x],dim=1).view(x.shape[0],x.shape[1]*2,14,14)\n        x = self.conv2(x) + doublex\n        x = self.max_pool(x)\n        doublex = torch.stack([x,x],dim=1).view(x.shape[0],x.shape[1]*2,7,7)\n        x = self.conv3(x) + doublex\n        x = x.view(x.size(0), -1)\n        x = self.fc1(x)\n        x = self.fc2(x)\n        return x","metadata":{"pycharm":{"name":"#%%\n"},"id":"2UId6oJLYnS3","executionInfo":{"status":"ok","timestamp":1632680808167,"user_tz":-180,"elapsed":6,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"execution":{"iopub.status.busy":"2021-09-26T22:23:29.175384Z","iopub.execute_input":"2021-09-26T22:23:29.175639Z","iopub.status.idle":"2021-09-26T22:23:29.189392Z","shell.execute_reply.started":"2021-09-26T22:23:29.175607Z","shell.execute_reply":"2021-09-26T22:23:29.188737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train!","metadata":{"id":"ng23aGmJYnS5"}},{"cell_type":"code","source":"model = DCmodel()\nlearning_rate = 0.001\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=learning_rate)\nscheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, 'min',verbose=True, patience=3)\nif gpu:\n  model = model.cuda()\n  criterion = criterion.cuda()\n\nrunning_loss = 0\nepochs = 35\ntrain_losses, val_losses = [], []\nhistory_accuracy = []\nval_loss_min = np.inf\nfor e in range(1, epochs + 1):\n    if gpu: torch.cuda.synchronize\n    start = time.perf_counter()\n    for images, labels in train_loader:\n        if gpu:\n          images = images.cuda()\n          labels = labels.cuda()\n        running_loss = 0\n        optimizer.zero_grad()\n        predicted_labels = model(images)\n        loss = criterion(predicted_labels,labels)\n        loss.backward()\n        optimizer.step()\n        running_loss += loss.item()\n    val_loss = 0\n    accuracy = 0\n    with torch.no_grad():\n        model.eval()\n        for images,labels in val_loader:\n            if gpu:\n              images = images.cuda()\n              labels = labels.cuda()\n            predicted_labels = model(images)\n            _, top_class = predicted_labels.topk(1, dim=1)\n            equals = top_class == labels.view(*top_class.shape)\n            val_loss += criterion(predicted_labels,labels)\n            accuracy += torch.mean(equals.type(torch.FloatTensor)).cpu()\n        scheduler.step(val_loss)\n    model.train()\n    train_losses.append(running_loss/len(train_loader))\n    val_losses.append(val_loss/len(val_loader))\n    history_accuracy.append(accuracy/len(val_loader))\n    print(\"Epoch: {}/{} \".format(e, epochs),\n                  \"Training Loss: {:.4f}\".format(train_losses[-1]),\n                  \"Val Loss: {:.4f}\".format(val_losses[-1]),\n                  \"Val Accuracy: {:.4f}\".format(accuracy/len(val_loader)))\n    network_learned = val_loss < val_loss_min\n    if network_learned:\n            val_loss_min = val_loss\n            torch.save(model.state_dict(), dir + 'model_mtl_mnist.pt')\n            print('Detected network improvement, saving current model')\n    end = time.perf_counter()\n    total = (end - start)*(epochs - e)\n    print('Estimated time left for training: {} hours, {} minutes, {} seconds'.format(total//3600, total%3600//60,int(total%60)))\nmodel = DCmodel()\noptimizer = torch.optim.Adam(model.parameters(), lr=1e-3)\ncheckpoint = torch.load(dir + 'model_mtl_mnist.pt')\nmodel.load_state_dict(checkpoint)","metadata":{"pycharm":{"name":"#%%\n","is_executing":true},"id":"0b4FmdeDYnS6","executionInfo":{"status":"ok","timestamp":1632680050840,"user_tz":-180,"elapsed":1450332,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"619ba4c4-d5e7-4d5b-81f1-5e2601c4c52a","execution":{"iopub.status.busy":"2021-09-26T22:23:29.190590Z","iopub.execute_input":"2021-09-26T22:23:29.190773Z","iopub.status.idle":"2021-09-26T22:36:03.591228Z","shell.execute_reply.started":"2021-09-26T22:23:29.190752Z","shell.execute_reply":"2021-09-26T22:36:03.590388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.tick_params(colors=frame_color)\nplt.plot(train_losses, label='Training Loss')\nplt.plot(val_losses, label='Validation Loss')\nplt.legend(frameon=False)","metadata":{"pycharm":{"name":"#%%\n"},"id":"o2EXIinsYnS8","executionInfo":{"status":"ok","timestamp":1632680162583,"user_tz":-180,"elapsed":580,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"ef408451-5d5d-4672-da4a-15a7ac2c0f07","execution":{"iopub.status.busy":"2021-09-26T22:36:03.592776Z","iopub.execute_input":"2021-09-26T22:36:03.593073Z","iopub.status.idle":"2021-09-26T22:36:03.820883Z","shell.execute_reply.started":"2021-09-26T22:36:03.593038Z","shell.execute_reply":"2021-09-26T22:36:03.820109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.tick_params(colors=frame_color)\nplt.plot(history_accuracy, label='Validation Accuracy')\nplt.legend(frameon=False)","metadata":{"pycharm":{"name":"#%%\n"},"id":"hDYpWPuCYnS9","executionInfo":{"status":"ok","timestamp":1632680184668,"user_tz":-180,"elapsed":407,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"8e9b744b-ebc1-4a7a-d432-559e227dbac8","execution":{"iopub.status.busy":"2021-09-26T22:36:03.821940Z","iopub.execute_input":"2021-09-26T22:36:03.822173Z","iopub.status.idle":"2021-09-26T22:36:04.051167Z","shell.execute_reply.started":"2021-09-26T22:36:03.822138Z","shell.execute_reply":"2021-09-26T22:36:04.050501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Validation prediction visualization\n### Some examples","metadata":{"pycharm":{"name":"#%% md\n"},"id":"pO8qGsY2YnS-"}},{"cell_type":"code","source":"fig = plt.figure(figsize=(10,5))\nimages, labels = next(iter(val_loader))\npredicted_labels = model(images)\npredicted_labels = predicted_labels.topk(1, dim=1)\nfor i in range(16):\n    fig.add_subplot(4, 4, i+1)\n    plt.imshow(images[i].reshape(28,28), cmap='gray')\n    plt.axis('off')\n    plt.tight_layout()\n    plt.title('Digit: ' + str(int(predicted_labels[1][i])),color=frame_color)","metadata":{"pycharm":{"name":"#%%\n"},"id":"wu690xEdYnS_","executionInfo":{"status":"ok","timestamp":1632680193936,"user_tz":-180,"elapsed":2277,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"8088eab1-d2fb-44f2-e7cc-cd32a84b902e","execution":{"iopub.status.busy":"2021-09-26T22:36:04.052438Z","iopub.execute_input":"2021-09-26T22:36:04.052679Z","iopub.status.idle":"2021-09-26T22:36:05.472969Z","shell.execute_reply.started":"2021-09-26T22:36:04.052648Z","shell.execute_reply":"2021-09-26T22:36:05.472281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Heat map","metadata":{"id":"dbSn8IpHYnS_"}},{"cell_type":"code","source":"full_val_loader = torch.utils.data.DataLoader(tav_data,sampler=val_sampler,batch_size=len(val_indices))\nimages, labels = next(iter(full_val_loader))\npredicted_labels = model(images)\npredicted_labels = predicted_labels.topk(1, dim=1)[1]\nfig = plt.figure(dpi=150)\nplt.tick_params(colors=frame_color)\nsns.heatmap(confusion_matrix(predicted_labels, labels), cmap=\"Blues\",\n            square=True, annot=True);","metadata":{"pycharm":{"name":"#%%\n"},"id":"qSqRnOmfYnTA","executionInfo":{"status":"ok","timestamp":1632680210470,"user_tz":-180,"elapsed":8889,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"52df225d-2afb-45c9-cd3c-176b419cc090","execution":{"iopub.status.busy":"2021-09-26T22:36:05.475410Z","iopub.execute_input":"2021-09-26T22:36:05.475678Z","iopub.status.idle":"2021-09-26T22:36:15.156994Z","shell.execute_reply.started":"2021-09-26T22:36:05.475641Z","shell.execute_reply":"2021-09-26T22:36:15.156160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Show incorrect classification","metadata":{"id":"uOc2w7kCYnTB"}},{"cell_type":"code","source":"row_predicted_labels = predicted_labels.view(-1)\nincorrect_indices = (row_predicted_labels != labels).nonzero()\nprint('There is total of {} incorrect classification in the validation set'.format(len(incorrect_indices)))\nfor ex in incorrect_indices:\n    fig = plt.figure(figsize=(1.5, 1.5))\n    plt.title('True label: {}, Predicted: {}'.format(int(labels[ex]),int(row_predicted_labels[ex])),color=frame_color)\n    plt.axis('off')\n    plt.imshow(images[ex].reshape(28,28), cmap='gray')\n    plt.show()","metadata":{"pycharm":{"name":"#%%\n"},"id":"xWjjdEsQYnTB","executionInfo":{"status":"ok","timestamp":1632680242092,"user_tz":-180,"elapsed":534,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"157ad2d7-021c-4d45-fe9d-03b9ca0a5f6a","execution":{"iopub.status.busy":"2021-09-26T22:36:15.158318Z","iopub.execute_input":"2021-09-26T22:36:15.158737Z","iopub.status.idle":"2021-09-26T22:36:15.806617Z","shell.execute_reply.started":"2021-09-26T22:36:15.158699Z","shell.execute_reply":"2021-09-26T22:36:15.805877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Test prediction visualization","metadata":{"id":"_-18H8hBYnTC"}},{"cell_type":"code","source":"test_data = MNIST(test_data_csv,transform,is_test_set=True)\ntest_sampler =  SequentialSampler(range(len(test_data)))\ntest_loader = torch.utils.data.DataLoader(test_data, batch_size=len(test_data), sampler=test_sampler)\nfig = plt.figure(figsize=(10,5))\nimages = next(iter(test_loader))\nwith torch.no_grad():\n    model.eval()\n    predicted_labels = model(images)\n    predicted_labels = predicted_labels.topk(1, dim=1)\n    for i in range(16):\n        fig.add_subplot(4, 4, i+1)\n        plt.imshow(images[i].reshape(28,28), cmap='gray')\n        plt.axis('off')\n        plt.tight_layout()\n        plt.title('Digit: ' + str(int(predicted_labels[1][i])),color=frame_color)","metadata":{"pycharm":{"name":"#%%\n"},"id":"5rNR76unYnTC","executionInfo":{"status":"ok","timestamp":1632680278720,"user_tz":-180,"elapsed":34066,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"f49fc4a8-5341-462c-9437-105076b45652","execution":{"iopub.status.busy":"2021-09-26T22:36:15.807919Z","iopub.execute_input":"2021-09-26T22:36:15.808294Z","iopub.status.idle":"2021-09-26T22:36:50.240569Z","shell.execute_reply.started":"2021-09-26T22:36:15.808260Z","shell.execute_reply":"2021-09-26T22:36:50.239912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submission","metadata":{"id":"5Dpu9UT5YnTD"}},{"cell_type":"code","source":"submission = [['ImageId', 'Label']]\nimage_id = 1\nfor prediction in predicted_labels[1]:\n    submission.append([image_id, int(prediction)])\n    image_id += 1\nprint('Total test images labeled:')\nprint(len(submission) - 1)\nwith open(dir + 'submission.csv', 'w') as file:\n    writer = csv.writer(file)\n    writer.writerows(submission)\nprint('Submission file is ready')\n","metadata":{"pycharm":{"name":"#%%\n"},"id":"avxd2cG5YnTD","executionInfo":{"status":"ok","timestamp":1632680463308,"user_tz":-180,"elapsed":509,"user":{"displayName":"b alon","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14Gj_VAKMxnGPWk7DRs7oaN9sMOpXeSWnOf_tw7PeFQ=s64","userId":"11269807200778368388"}},"outputId":"622f7817-284b-4826-fd74-6f5a2097056a","execution":{"iopub.status.busy":"2021-09-26T22:36:50.241677Z","iopub.execute_input":"2021-09-26T22:36:50.242445Z","iopub.status.idle":"2021-09-26T22:36:50.462224Z","shell.execute_reply.started":"2021-09-26T22:36:50.242408Z","shell.execute_reply":"2021-09-26T22:36:50.461431Z"},"trusted":true},"execution_count":null,"outputs":[]}]}