{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n#for dirname, _, filenames in os.walk('/kaggle/input'):\n #   for filename in filenames:\n    #      print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-07-27T06:30:02.889365Z","iopub.execute_input":"2021-07-27T06:30:02.89002Z","iopub.status.idle":"2021-07-27T06:30:02.909886Z","shell.execute_reply.started":"2021-07-27T06:30:02.889897Z","shell.execute_reply":"2021-07-27T06:30:02.909142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install natsort","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:02.916574Z","iopub.execute_input":"2021-07-27T06:30:02.917987Z","iopub.status.idle":"2021-07-27T06:30:10.937841Z","shell.execute_reply.started":"2021-07-27T06:30:02.917936Z","shell.execute_reply":"2021-07-27T06:30:10.936952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install tqdm","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:10.939928Z","iopub.execute_input":"2021-07-27T06:30:10.940339Z","iopub.status.idle":"2021-07-27T06:30:16.713683Z","shell.execute_reply.started":"2021-07-27T06:30:10.940298Z","shell.execute_reply":"2021-07-27T06:30:16.712729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 環境変数\n%matplotlib inline\nimport keras\nfrom keras.datasets import cifar10\nfrom keras.layers import Activation, Conv2D, Dense, Dropout, Flatten, MaxPooling2D, GlobalAveragePooling2D\nfrom keras.models import Sequential, load_model\nfrom keras.utils.np_utils import to_categorical\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import LearningRateScheduler\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport glob\nimport cv2\nfrom natsort import natsorted\nimport re\nimport pathlib\nimport zipfile\nfrom tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:16.7168Z","iopub.execute_input":"2021-07-27T06:30:16.717075Z","iopub.status.idle":"2021-07-27T06:30:21.862334Z","shell.execute_reply.started":"2021-07-27T06:30:16.717045Z","shell.execute_reply":"2021-07-27T06:30:21.861466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **cifar10のデータ読み込み**","metadata":{}},{"cell_type":"code","source":"# データのロード\nnum_classes = 10 # クラス数\n\n(X_train, y_train), (X_test, y_test) = cifar10.load_data()\n# X_train = X_train.astype('float32')\nX_test  = X_test.astype('float32') / 255.0   # 0.0～1.0に補正\ny_train = to_categorical(y_train, num_classes)\ny_test  = to_categorical(y_test, num_classes)","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:21.882409Z","iopub.execute_input":"2021-07-27T06:30:21.883146Z","iopub.status.idle":"2021-07-27T06:30:27.888611Z","shell.execute_reply.started":"2021-07-27T06:30:21.88311Z","shell.execute_reply":"2021-07-27T06:30:27.887759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **ハイパーパラメータ**","metadata":{}},{"cell_type":"code","source":"# 学習率の減衰設定\n# Epochが30以降は学習するごとに0.98倍\ndef lr_decay(epoch):\n    lr = 0.001\n    \n    if epoch > 30: \n        for e in range(epoch - 30):\n            lr*=0.98\n            \n    return lr","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:27.891314Z","iopub.execute_input":"2021-07-27T06:30:27.891677Z","iopub.status.idle":"2021-07-27T06:30:27.895819Z","shell.execute_reply.started":"2021-07-27T06:30:27.891642Z","shell.execute_reply":"2021-07-27T06:30:27.895028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 学習のハイパーパラメータ\nEPOCHS = 1000              # 学習回数\nhidden_nodes1 = 128        # 中間層ノード数1\nhidden_nodes2 = 256        # 中間層ノード数2\nhidden_nodes3 = 512        # 中間層ノード数3\noutput_nodes  = 1024       # 全結合層ノード数\nvalidation_rate = 0.2      # trainデータに対するvalidationデータの割合\nIMAGE_SIZE = 32            # 入力画像サイズ\nBATCH_SIZE = 500           # 学習する画像枚数","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:27.897745Z","iopub.execute_input":"2021-07-27T06:30:27.898355Z","iopub.status.idle":"2021-07-27T06:30:27.908583Z","shell.execute_reply.started":"2021-07-27T06:30:27.898302Z","shell.execute_reply":"2021-07-27T06:30:27.907681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 内部データ確認\nprint('X_train[0][0][0] ->', X_train[0][0][0])\nprint('y_train[0]       ->', y_train[0])\n\nfor i in range(10):\n    plt.subplot(2, 5, i+1)\n    plt.imshow(X_train[i])\n    plt.axis(\"off\")\nplt.suptitle('The original image', fontsize=18)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:27.909756Z","iopub.execute_input":"2021-07-27T06:30:27.910308Z","iopub.status.idle":"2021-07-27T06:30:28.4324Z","shell.execute_reply.started":"2021-07-27T06:30:27.910268Z","shell.execute_reply":"2021-07-27T06:30:28.431574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# trainデータからtrainデータとvalidationデータに分割\n# test_size：trainデータからvalデータにする割合\nX_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=validation_rate)\n\nsteps_per_epoch = X_train.shape[0] // BATCH_SIZE\nvalidation_steps = X_test.shape[0] // BATCH_SIZE","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:28.433473Z","iopub.execute_input":"2021-07-27T06:30:28.433808Z","iopub.status.idle":"2021-07-27T06:30:28.495589Z","shell.execute_reply.started":"2021-07-27T06:30:28.433774Z","shell.execute_reply":"2021-07-27T06:30:28.494742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 各形状確認\n# X_ ：画像枚数，幅，高さ，チャンネル(赤，青，緑)\n# y_ ：画像枚数．ラベル数\nprint(\"X_train.shape ->\", X_train.shape)\nprint(\"y_train.shape ->\", y_train.shape)\nprint(\"X_val.shape   ->\", X_val.shape)\nprint(\"y_val.shape   ->\", y_val.shape)\nprint(\"X_test.shape  ->\", X_test.shape)\nprint(\"y_test.shape  ->\", y_test.shape)","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:28.496837Z","iopub.execute_input":"2021-07-27T06:30:28.497351Z","iopub.status.idle":"2021-07-27T06:30:28.504294Z","shell.execute_reply.started":"2021-07-27T06:30:28.497313Z","shell.execute_reply":"2021-07-27T06:30:28.503388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **データの水増し条件**","metadata":{}},{"cell_type":"code","source":"# trainデータの水増し\ntrain_datagen = ImageDataGenerator(\n    rescale=1.0 / 255,       # 画素値を0.0～1.0に補正\n    rotation_range=20,       # 整数．画像をランダムに回転する回転範囲．\n    width_shift_range=0.2,   # 浮動小数点数（横幅に対する割合）．ランダムに水平シフトする範囲．\n    height_shift_range=0.2,  # 浮動小数点数（縦幅に対する割合）．ランダムに垂直シフトする範囲．\n    shear_range=0.2,         # 浮動小数点数．シアー強度（反時計回りのシアー角度）．\n    zoom_range=0.2,          # 浮動小数点数または[lower，upper]．ランダムにズームする範囲．浮動小数点数\n    horizontal_flip=True,    # 真理値．垂直方向に入力をランダムに反転します．\n    channel_shift_range=0.2  # 画像の明るさをランダムに変化\n    #samplewise_center=True,           # チャンネルごとの平均を0に\n    #samplewise_std_normalization=True,# チャンネルごとの分散を1に\n    #zca_epsilon=1e-6,                 # 白色化の度合い\n    #zca_whitening=True,                # 白色化\n)\n\n# 与えられたサンプルデータに基づいて，データに依存する統計量を計算\n# featurewise_center，featurewise_std_normalization，zca_whiteningが指定されたときに必要\n# train_datagen.fit(X_train, augment=True, rounds=1, seed=None)\n\n# データとラベルの配列を取得し、拡張データのバッチを生成\ntrain_generator = train_datagen.flow(\n    X_train,\n    y_train,\n    batch_size=BATCH_SIZE,\n)\n\n# trainデータ\nvalidation_datagen = ImageDataGenerator(\n   rescale=1.0 / 255,\n)\n\nvalidation_generator = validation_datagen.flow(\n    X_val,\n    y_val,\n    batch_size=BATCH_SIZE,\n)\n\n\n# 表示\nX_batch, y_batch = train_generator.next()\n\nfor i in range(10):  # 水増し仕様の10枚を表示\n    plt.subplot(2, 5, i+1)\n    plt.imshow(X_batch[i])\n    plt.axis(\"off\")\n    \n    \nplt.suptitle('Standardization result', fontsize=18)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:28.50551Z","iopub.execute_input":"2021-07-27T06:30:28.506016Z","iopub.status.idle":"2021-07-27T06:30:29.299168Z","shell.execute_reply.started":"2021-07-27T06:30:28.50598Z","shell.execute_reply":"2021-07-27T06:30:29.298343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 識別器の構築","metadata":{}},{"cell_type":"code","source":"# CNNの構築\nmodel = Sequential()\n\n# 入力層，中間層01\nmodel.add(Conv2D(hidden_nodes1, (3, 3), padding='same', input_shape=X_train.shape[1:]))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(hidden_nodes1, (3, 3), padding='same'))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\n# 中間層02\nmodel.add(Conv2D(hidden_nodes2, (3, 3), padding='same'))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(hidden_nodes2, (3, 3), padding='same'))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\n# 中間層03\nmodel.add(Conv2D(hidden_nodes3, (3, 3), padding='same'))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(hidden_nodes3, (3, 3), padding='same'))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\n# 全結合層\nmodel.add(GlobalAveragePooling2D())\nmodel.add(Dense(output_nodes))\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.50))\n\n# 10クラスの分類\nmodel.add(Dense(10))\nmodel.add(Activation('softmax'))","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:29.300505Z","iopub.execute_input":"2021-07-27T06:30:29.300863Z","iopub.status.idle":"2021-07-27T06:30:31.455858Z","shell.execute_reply.started":"2021-07-27T06:30:29.300827Z","shell.execute_reply":"2021-07-27T06:30:31.455053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 現状のモデルの層を確認\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:31.457074Z","iopub.execute_input":"2021-07-27T06:30:31.457407Z","iopub.status.idle":"2021-07-27T06:30:31.474792Z","shell.execute_reply.started":"2021-07-27T06:30:31.457374Z","shell.execute_reply":"2021-07-27T06:30:31.473839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **学習過程の設定**","metadata":{}},{"cell_type":"code","source":"# 訓練過程の設定\nmodel.compile(\n    loss='categorical_crossentropy', # 損失関数，ラベルがone-hot エンコーディングで表現されている場合に使用\n    optimizer='Adam',                # 最適化アルゴリズム\n    metrics=['accuracy']\n)","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:31.476814Z","iopub.execute_input":"2021-07-27T06:30:31.47716Z","iopub.status.idle":"2021-07-27T06:30:31.49225Z","shell.execute_reply.started":"2021-07-27T06:30:31.477127Z","shell.execute_reply":"2021-07-27T06:30:31.491504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# EarlyStoppingの設定\nes = keras.callbacks.EarlyStopping(\n    monitor='val_loss', # 監視する変数   \n    patience=20,        # 何エポックの間，monitorに変化がないことを許容するか\n    verbose=0,\n    mode='min'\n)\n\n# 更新された学習率を適用させる．\nlr_change = LearningRateScheduler(lr_decay)","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:31.493462Z","iopub.execute_input":"2021-07-27T06:30:31.493801Z","iopub.status.idle":"2021-07-27T06:30:31.500552Z","shell.execute_reply.started":"2021-07-27T06:30:31.493768Z","shell.execute_reply":"2021-07-27T06:30:31.499615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **学習**","metadata":{}},{"cell_type":"code","source":"history=model.fit_generator(\n    train_generator,                       # trainデータ\n    epochs=EPOCHS,                         # 学習回数\n    steps_per_epoch=steps_per_epoch,       \n    validation_data=validation_generator,  # validationデータ\n    validation_steps=validation_steps,\n    verbose=1,\n    callbacks=[lr_change,es],\n)","metadata":{"execution":{"iopub.status.busy":"2021-07-27T06:30:31.502532Z","iopub.execute_input":"2021-07-27T06:30:31.50283Z","iopub.status.idle":"2021-07-27T07:36:10.384414Z","shell.execute_reply.started":"2021-07-27T06:30:31.502805Z","shell.execute_reply":"2021-07-27T07:36:10.383513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **識別器の評価**","metadata":{}},{"cell_type":"code","source":"# 精度の評価\nprint('＜Test_data＞')\nscores = model.evaluate(X_test, y_test, verbose=1)\nprint('Test_loss   ：', scores[0])\nprint('Test_accuray：', scores[1])\n\n\nprint('\\n＜Train_data＞')\nscores = model.evaluate(train_generator, verbose=1)\nprint('Train_loss   ：', scores[0])\nprint('Train_accuray：', scores[1])","metadata":{"execution":{"iopub.status.busy":"2021-07-27T07:36:10.386018Z","iopub.execute_input":"2021-07-27T07:36:10.386281Z","iopub.status.idle":"2021-07-27T07:36:40.477031Z","shell.execute_reply.started":"2021-07-27T07:36:10.386255Z","shell.execute_reply":"2021-07-27T07:36:40.47621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 学習過程における識別精度の推移\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('Accuracy')\nplt.xlabel('epoch')\nplt.ylabel('accuracy')\nplt.ylim([0.00, 1.00])\nplt.legend(['acc', 'val_acc'], loc='lower right')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T07:36:40.4784Z","iopub.execute_input":"2021-07-27T07:36:40.478756Z","iopub.status.idle":"2021-07-27T07:36:40.64411Z","shell.execute_reply.started":"2021-07-27T07:36:40.478718Z","shell.execute_reply":"2021-07-27T07:36:40.642995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 学習過程における損失の推移\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Loss')\nplt.xlabel('epoch')\nplt.ylabel('loss')\nplt.legend(['loss', 'val_loss'])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T07:36:40.645648Z","iopub.execute_input":"2021-07-27T07:36:40.646213Z","iopub.status.idle":"2021-07-27T07:36:40.818825Z","shell.execute_reply.started":"2021-07-27T07:36:40.646168Z","shell.execute_reply":"2021-07-27T07:36:40.817882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **識別器の保存**","metadata":{}},{"cell_type":"code","source":"#resultsディレクトリを作成\nresult_dir = 'results'\nif not os.path.exists(result_dir):\n    os.mkdir(result_dir)\n\nprint('save the architecture of a model')\njson_string = model.to_json()\nopen(os.path.join(result_dir,'cnn_model.json'), 'w').write(json_string)\nyaml_string = model.to_yaml()\nopen(os.path.join(result_dir,'cnn_model.yaml'), 'w').write(yaml_string)\nprint('save weights')\nmodel.save_weights(os.path.join(result_dir,'cnn_model_weights.hdf5'))","metadata":{"execution":{"iopub.status.busy":"2021-07-27T07:36:40.82032Z","iopub.execute_input":"2021-07-27T07:36:40.820669Z","iopub.status.idle":"2021-07-27T07:36:40.918568Z","shell.execute_reply.started":"2021-07-27T07:36:40.820634Z","shell.execute_reply":"2021-07-27T07:36:40.917715Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ***提出用ファイルの構築***","metadata":{}},{"cell_type":"code","source":"files = []\n\nfor i in range(1,300001):\n    path_name = '../input/cifar10-submit-ds/test/' + str(i) + '.png'\n    files.append(path_name)\n    \nprint(files[:5])","metadata":{"execution":{"iopub.status.busy":"2021-07-27T07:36:40.922261Z","iopub.execute_input":"2021-07-27T07:36:40.922509Z","iopub.status.idle":"2021-07-27T07:36:41.103426Z","shell.execute_reply.started":"2021-07-27T07:36:40.922484Z","shell.execute_reply":"2021-07-27T07:36:41.102536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **提出形式に変換**","metadata":{}},{"cell_type":"code","source":"df = pd.DataFrame(pd.read_csv('../input/cifar-10/sampleSubmission.csv'))\n#df = df.drop('label', axis=1)\n\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T07:36:41.104943Z","iopub.execute_input":"2021-07-27T07:36:41.105312Z","iopub.status.idle":"2021-07-27T07:36:41.248118Z","shell.execute_reply.started":"2021-07-27T07:36:41.105275Z","shell.execute_reply":"2021-07-27T07:36:41.247296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']","metadata":{"execution":{"iopub.status.busy":"2021-07-27T07:36:41.249457Z","iopub.execute_input":"2021-07-27T07:36:41.249836Z","iopub.status.idle":"2021-07-27T07:36:41.256216Z","shell.execute_reply.started":"2021-07-27T07:36:41.249783Z","shell.execute_reply":"2021-07-27T07:36:41.254946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred2 = []\n\nfor i, file in enumerate(files):    \n    x = []\n    \n    image = cv2.imread(file)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    x.append(image)\n        \n    if i == 0: \n        plt.subplot(1, 1, 1)\n        plt.imshow(x[0])\n        plt.axis(\"off\")\n        \n    # 画素値を0から1の範囲に変換\n    x = np.asarray(x)\n    x = x.astype('float32')\n    x /= 255.0\n    \n    pred = model.predict(x)\n    pred2.append(labels[np.argmax(pred)])\n    \n    if i == 0: \n        print(file, \"\\n\")\n        print(x[0][0][0], \"\\n\")\n    print(\"\\r{:.10f}[%]\".format(i+1/len(files)), end=\"\")","metadata":{"execution":{"iopub.status.busy":"2021-07-27T07:36:41.257571Z","iopub.execute_input":"2021-07-27T07:36:41.257914Z","iopub.status.idle":"2021-07-27T10:59:19.63564Z","shell.execute_reply.started":"2021-07-27T07:36:41.25788Z","shell.execute_reply":"2021-07-27T10:59:19.634885Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['label'] = pred2\ndf.head(20)","metadata":{"execution":{"iopub.status.busy":"2021-07-27T10:59:19.695746Z","iopub.execute_input":"2021-07-27T10:59:19.696176Z","iopub.status.idle":"2021-07-27T10:59:19.735603Z","shell.execute_reply.started":"2021-07-27T10:59:19.696134Z","shell.execute_reply":"2021-07-27T10:59:19.734657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-07-27T10:59:19.73688Z","iopub.execute_input":"2021-07-27T10:59:19.737254Z","iopub.status.idle":"2021-07-27T10:59:20.297489Z","shell.execute_reply.started":"2021-07-27T10:59:19.737218Z","shell.execute_reply":"2021-07-27T10:59:20.296644Z"},"trusted":true},"execution_count":null,"outputs":[]}]}