{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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 in \n\nfrom __future__ import division, print_function, unicode_literals\nimport numpy as np # linear algebra\nimport pandas as pd# data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport tensorflow.compat.v1 as tf\nfrom keras.utils.np_utils import to_categorical\nfrom sklearn.model_selection import train_test_split\ntf.disable_v2_behavior()\n\n\n# Input data files are available in the \"../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\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"tf.reset_default_graph()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data=pd.read_csv(\"/kaggle/input/Kannada-MNIST/train.csv\")\ntest_data=pd.read_csv('/kaggle/input/Kannada-MNIST/test.csv')\nsample_sub=pd.read_csv('/kaggle/input/Kannada-MNIST/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.head(1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples=5\nplt.figure(figsize=(samples*6,700))\nfor index in range(samples):\n    plt.subplot(1, samples, index+1)\n    image=np.array(train_data.iloc[index, 1:]).reshape(28,28)\n    plt.imshow(image, cmap=\"binary\")\n    plt.axis(\"off\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.label[:samples]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train=train_data.drop('label', axis=1)\nY_train=train_data.label\ntest_data=test_data.drop('id', axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train=X_train/255\ntest_data=test_data/255","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train=X_train.astype('float32')\ntest_data=test_data.astype('float32')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train=X_train.values.reshape(-1,28,28,1)\ntest_data=test_data.values.reshape(-1,28,28,1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train,X_test,y_train,y_test=train_test_split(X_train,Y_train,random_state=42,test_size=0.15)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"abc=np.zeros(5000, dtype='int64')\nabc.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size=50\ntrain_dataset_data = tf.data.Dataset.from_tensor_slices(X_train)\ntrain_dataset_labels = tf.data.Dataset.from_tensor_slices(y_train)\ntrain_dataset = tf.data.Dataset.zip((train_dataset_data, train_dataset_labels)).shuffle(500).repeat().batch(batch_size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_dataset_data = tf.data.Dataset.from_tensor_slices(X_test)\nvalid_dataset_labels= tf.data.Dataset.from_tensor_slices(y_test)\nvalid_dataset = tf.data.Dataset.zip((valid_dataset_data, valid_dataset_labels)).shuffle(500).repeat().batch(batch_size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dataset_data=tf.data.Dataset.from_tensor_slices(test_data)\ntest_data_labels=tf.data.Dataset.from_tensor_slices(np.zeros(5000, dtype='int64'))\ntest_dataset=tf.data.Dataset.zip((test_dataset_data, test_data_labels)).batch(50)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"iterator = tf.data.Iterator.from_structure(train_dataset.output_types,\n                                               train_dataset.output_shapes)\nnext_element = iterator.get_next()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"training_init_op = iterator.make_initializer(train_dataset)\ninit_op = tf.global_variables_initializer()\nvalidation_init_op = iterator.make_initializer(valid_dataset)\ntest_init_op=iterator.make_initializer(test_dataset)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with tf.Session() as sess:\n    sess.run(init_op)\n    sess.run(training_init_op)\n    for i in range(1):\n        data=sess.run(next_element)\n        print(data[1])\n        temp=tf.reshape(data[0], [-1, 28*28], name=\"temp\")\n        print(temp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#X=tf.placeholder(shape=[None, 28, 28, 1], dtype=tf.float32, name=\"X\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#X.dtype","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_layer1_params={\n    \"filters\" : 256,\n    \"kernel_size\" : 9,\n    \"strides\" : 1,\n    \"padding\" : \"valid\",\n    \"activation\" : tf.nn.relu,\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps1_maps=32\ncaps1_caps=caps=caps1_maps*6*6\ncaps1_dims=8","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_layer2_params={\n    \"filters\" : caps1_maps*caps1_dims,\n    \"kernel_size\" : 9,\n    \"strides\" : 2,\n    \"padding\" : \"valid\",\n    \"activation\" : tf.nn.relu\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv1=tf.layers.conv2d(next_element[0], name=\"conv1\", **conv_layer1_params)\nconv2=tf.layers.conv2d(conv1, name=\"conv2\", **conv_layer2_params)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps1_reshape=tf.reshape(conv2, [-1, caps1_caps, caps1_dims], name=\"caps1_reshape\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def squash(s, axis=-1, epsilon=1e-7, name=None):\n    with tf.name_scope(name, default_name=\"squash\"):\n        squared_s=tf.reduce_sum(tf.square(s), axis=axis, keep_dims=True)\n        mod_s=tf.sqrt(squared_s+epsilon)\n        squash_factor=squared_s/(1.+squared_s)\n        unit_vector=s/mod_s\n        return squash_factor*unit_vector","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps1_output=squash(caps1_reshape, name=\"caps1_output\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps1_output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_caps=10\ncaps2_dims=16","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sigma=0.1\nW_init=tf.random_normal(\n        shape=(1, caps1_caps, caps2_caps, caps2_dims, caps1_dims ),\n        stddev=sigma, dtype=tf.float32, name=\"W_init\"\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"W=tf.Variable(W_init, name=\"W\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"W_tiled=tf.tile(W, [batch_size, 1,1,1,1], name=\"W_tiled\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps1_output_extended=tf.expand_dims(caps1_output, -1, name=\"caps1_output_extended\")\ncaps1_output_tile=tf.expand_dims(caps1_output_extended, 2, name=\"caps1_output_tile\")\ncaps1_output_tiled=tf.tile(caps1_output_tile, [1,1,caps2_caps,1,1], name=\"caps1_output_tiled\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"W_tiled","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps1_output_tiled","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_predicted=tf.matmul(W_tiled, caps1_output_tiled, name=\"caps2_predicted\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\ncaps2_predicted","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_bij=tf.zeros([batch_size, caps1_caps, caps2_caps, 1, 1], dtype=np.float32, name=\"caps2_bij\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"softmax_bij=tf.nn.softmax(caps2_bij, dim=2, name=\"softmax_bij\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weighted_pred=tf.multiply(softmax_bij, caps2_predicted, name=\"weighted_pred\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weighted_pred","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weighted_sum=tf.reduce_sum(weighted_pred, axis=1, keep_dims=True, name=\"weighted_sum\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weighted_sum","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_output1=squash(weighted_sum, axis=-2, name=\"caps2_output1\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_output1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_output1_tiled=tf.tile(caps2_output1, [1, caps1_caps, 1,1,1], name=\"caps2_output1_tiled\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_output1_tiled","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"agreement_prod=tf.matmul(caps2_predicted, caps2_output1_tiled, transpose_a=True, name=\"agreement_prod\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"agreement_prod","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_bij=tf.add(caps2_bij, agreement_prod)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"softmax_bij_2=tf.nn.softmax(caps2_bij, dim=2, name=\"softmax_bij_2\")\nweighted_pred_2=tf.multiply(softmax_bij_2, caps2_predicted, name=\"weighted_pred_2\")\nweighted_sum_2=tf.reduce_sum(weighted_pred_2, axis=1, keep_dims=True, name=\"weighted_sum_2\")\ncaps2_output2=squash(weighted_sum_2, axis=-2, name=\"caps2_output2\")\ncaps2_output2_tiled=tf.tile(caps2_output2, [1, caps1_caps, 1,1,1], name=\"caps2_output2_tiled\")\nagreement_prod=tf.matmul(caps2_predicted, caps2_output2_tiled, transpose_a=True, name=\"agreement_prod\")\ncaps2_bij=tf.add(caps2_bij, agreement_prod)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_output_final=caps2_output2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_output_final","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def find_class(output_tensor, axis=-1,  epsilon=1e-7, keep_dims=False, name=None):\n    with tf.name_scope(name, default_name=\"find_class\"):\n        squared_prob=tf.reduce_sum(tf.square(output_tensor), axis=axis, keep_dims=keep_dims)\n        return tf.sqrt(squared_prob+epsilon)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"final_prob=find_class(caps2_output_final, axis=-2, name=\"final_prob\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"final_prob","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"max_prob_digit=tf.argmax(final_prob, axis=2, name=\"final_prob\" )\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"max_prob_digit","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred = tf.squeeze(max_prob_digit, axis=[1,2], name=\"y_pred\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#y=tf.placeholder(shape=[None], dtype=tf.int64, name=\"y\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"m_plus=0.9\nm_minus=0.1\nlambdaa=0.5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"T=tf.one_hot(next_element[1], caps2_caps, name=\"T\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_output_T=find_class(caps2_output_final, axis=-2, keep_dims=True,\n                              name=\"caps2_output_T\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"True_class_margin_loss=tf.square(tf.maximum(0., m_plus-caps2_output_T), name=\"True_class_margin_loss\")\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"True_class_margin_loss","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"True_class_loss_reshape=tf.reshape(True_class_margin_loss, shape=(-1, 10), name=\"True_class_loss_reshape\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"True_class_loss_reshape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"False_class_margin_loss = tf.square(tf.maximum(0., caps2_output_T - m_minus),\n                             name=\"False_class_margin_loss\")\nFalse_class_loss_reshape = tf.reshape(False_class_margin_loss, shape=(-1, 10),\n                          name=\"False_class_oss_reshape\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"L=tf.add(T*True_class_loss_reshape, lambdaa*(1.0-T)*False_class_loss_reshape, name=\"L\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"L","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"margin_loss=tf.reduce_mean(tf.reduce_sum(L, axis=1), name=\"margin_loss\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mask_output_label=tf.placeholder_with_default(True, shape=(), name=\"mask_output_label\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mask_output_label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"reconstruction_targets=tf.cond(mask_output_label, lambda:next_element[1], lambda:y_pred, name=\"reconstruction_targets\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"reconstruction_targets","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"reconstruction_mask = tf.one_hot(reconstruction_targets,\n                                 depth=caps2_caps,\n                                 name=\"reconstruction_mask\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"reconstruction_mask_reshape=tf.reshape(reconstruction_mask, [-1, 1, caps2_caps, 1, 1], name=\"reconstruction_mask_reshape\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_output_mask=tf.multiply(caps2_output_final, reconstruction_mask_reshape, name=\"caps2_output_mask\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"decoder_input=tf.reshape(caps2_output_mask, [-1, caps2_caps*caps2_dims], name=\"decoder_input\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"decoder_input","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"hidden1_units=512\nhidden2_units=1024\noutput_image=28*28","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with tf.name_scope(\"decoder\"):\n    hidden1=tf.layers.dense(decoder_input, hidden1_units, activation=tf.nn.relu, name=\"hidden1\")\n    hidden2=tf.layers.dense(hidden1, hidden2_units, activation=tf.nn.relu, name=\"hidden2\")\n    decoder_output=tf.layers.dense(hidden2, output_image, activation=tf.nn.sigmoid, name=\"decoder_output\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Input_flat=tf.reshape(next_element[0], [-1, output_image], name=\"Input_flat\")\nsquared_difference=tf.square(Input_flat-decoder_output, name=\"squared_difference\")\nreconstruction_loss=tf.reduce_mean(squared_difference, name=\"reconstruction_loss\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"alpha=0.0005\nloss=tf.add(margin_loss, alpha*reconstruction_loss, name=\"loss\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"correct = tf.equal(next_element[1], y_pred, name=\"correct\")\naccuracy = tf.reduce_mean(tf.cast(correct, tf.float32), name=\"accuracy\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"optimizer = tf.train.AdamOptimizer()\ntraining_op = optimizer.minimize(loss, name=\"training_op\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"init = tf.global_variables_initializer()\nsaver = tf.train.Saver()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs=10\nrestore_checkpoint=True\niterations_per_epoch_train=X_train.shape[0] // batch_size\niterations_per_epoch_test=X_test.shape[0] // batch_size\nbest_loss_value=np.infty\ncheckpoint_path= \"../input/Kannada-MNIST/capsule_params\"\n\nwith tf.Session() as sess:\n    if restore_checkpoint and tf.train.checkpoint_exists(checkpoint_path):\n        saver.restore(sess, checkpoint_path)\n    else:\n        init.run()\n        \n    sess.run(init_op)\n    for epoch in range(epochs):\n        \n        sess.run(training_init_op)\n        for iteration in range(1, iterations_per_epoch_train + 1):\n            \n            _,loss_train=sess.run([training_op, loss])\n            print(\"\\rIteration: {}/{} ({:.1f}%)  Loss: {:.5f}\".format(\n                      iteration, iterations_per_epoch_train,\n                      iteration * 100 / iterations_per_epoch_train,\n                      loss_train),\n                  end=\"\")\n            \n        \n        \n        sess.run(validation_init_op)\n        loss_vals=[]\n        acc_vals=[]\n        for iteration in range(1, iterations_per_epoch_test + 1):\n            \n            loss_val,acc_val=sess.run([loss, accuracy], feed_dict={mask_output_label : False})\n            loss_vals.append(loss_val)\n            acc_vals.append(acc_val)\n            print(\"\\rEvaluating the model: {}/{} ({:.1f}%)\".format(\n                      iteration, iterations_per_epoch_test,\n                      iteration * 100 / iterations_per_epoch_test),\n                  end=\" \" * 10)\n                \n        Mean_loss=np.mean(loss_vals)\n        Mean_accuracy=np.mean(acc_vals)\n        print(\"\\rEpoch: {}  Val accuracy: {:.4f}%  Loss: {:.6f}{}\".format(\n            epoch + 1, Mean_accuracy * 100, Mean_loss,\n            \" (improved)\" if Mean_loss < best_loss_value else \"\"))\n        if Mean_loss < best_loss_value:\n            #save_path=saver.save(sess, checkpoint_path)\n            best_loss_value=Mean_loss\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred=[]\nwith tf.Session() as sess:\n    sess.run(init)\n    sess.run(init_op)\n    sess.run(test_init_op)\n    for i in range(100):\n        caps2_output_value, y_pred_value=sess.run([caps2_output_final, y_pred])\n        sample_sub['label'][50*i : 50*i + 50]= y_pred_value\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred_value","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_sub.to_csv('submission.csv',index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":1}