diff --git a/Project_preparation/preparation_03/tf02_premade_estimators.ipynb b/Project_preparation/preparation_03/tf02_premade_estimators.ipynb
new file mode 100644
index 0000000..c3cd414
--- /dev/null
+++ b/Project_preparation/preparation_03/tf02_premade_estimators.ipynb
@@ -0,0 +1,1176 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2.2.0\n",
+ "sys.version_info(major=3, minor=6, micro=9, releaselevel='final', serial=0)\n",
+ "matplotlib 3.2.1\n",
+ "numpy 1.18.5\n",
+ "pandas 1.0.4\n",
+ "sklearn 0.23.1\n",
+ "tensorflow 2.2.0\n",
+ "tensorflow.keras 2.3.0-tf\n"
+ ]
+ }
+ ],
+ "source": [
+ "import matplotlib as mpl\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n",
+ "import numpy as np\n",
+ "import sklearn\n",
+ "import pandas as pd\n",
+ "import os\n",
+ "import sys\n",
+ "import time\n",
+ "import tensorflow as tf\n",
+ "\n",
+ "from tensorflow import keras\n",
+ "\n",
+ "print(tf.__version__)\n",
+ "print(sys.version_info)\n",
+ "for module in mpl, np, pd, sklearn, tf, keras:\n",
+ " print(module.__name__, module.__version__)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# 官方计划删除estimator部分"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(627, 10)\n",
+ " survived sex age n_siblings_spouses parch fare class deck \\\n",
+ "0 0 male 22.0 1 0 7.2500 Third unknown \n",
+ "1 1 female 38.0 1 0 71.2833 First C \n",
+ "2 1 female 26.0 0 0 7.9250 Third unknown \n",
+ "3 1 female 35.0 1 0 53.1000 First C \n",
+ "4 0 male 28.0 0 0 8.4583 Third unknown \n",
+ "\n",
+ " embark_town alone \n",
+ "0 Southampton n \n",
+ "1 Cherbourg n \n",
+ "2 Southampton y \n",
+ "3 Southampton n \n",
+ "4 Queenstown y \n",
+ " survived sex age n_siblings_spouses parch fare class \\\n",
+ "0 0 male 35.0 0 0 8.0500 Third \n",
+ "1 0 male 54.0 0 0 51.8625 First \n",
+ "2 1 female 58.0 0 0 26.5500 First \n",
+ "3 1 female 55.0 0 0 16.0000 Second \n",
+ "4 1 male 34.0 0 0 13.0000 Second \n",
+ "\n",
+ " deck embark_town alone \n",
+ "0 unknown Southampton y \n",
+ "1 E Southampton y \n",
+ "2 C Southampton y \n",
+ "3 unknown Southampton y \n",
+ "4 D Southampton y \n"
+ ]
+ }
+ ],
+ "source": [
+ "# https://storage.googleapis.com/tf-datasets/titanic/train.csv\n",
+ "# https://storage.googleapis.com/tf-datasets/titanic/eval.csv\n",
+ "train_file = \"./data/titanic/train.csv\"\n",
+ "eval_file = \"./data/titanic/eval.csv\"\n",
+ "\n",
+ "train_df = pd.read_csv(train_file)\n",
+ "eval_df = pd.read_csv(eval_file)\n",
+ "print(train_df.shape)\n",
+ "print(train_df.head())\n",
+ "print(eval_df.head())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " sex age n_siblings_spouses parch fare class deck \\\n",
+ "0 male 22.0 1 0 7.2500 Third unknown \n",
+ "1 female 38.0 1 0 71.2833 First C \n",
+ "2 female 26.0 0 0 7.9250 Third unknown \n",
+ "3 female 35.0 1 0 53.1000 First C \n",
+ "4 male 28.0 0 0 8.4583 Third unknown \n",
+ "\n",
+ " embark_town alone \n",
+ "0 Southampton n \n",
+ "1 Cherbourg n \n",
+ "2 Southampton y \n",
+ "3 Southampton n \n",
+ "4 Queenstown y \n",
+ " sex age n_siblings_spouses parch fare class deck \\\n",
+ "0 male 35.0 0 0 8.0500 Third unknown \n",
+ "1 male 54.0 0 0 51.8625 First E \n",
+ "2 female 58.0 0 0 26.5500 First C \n",
+ "3 female 55.0 0 0 16.0000 Second unknown \n",
+ "4 male 34.0 0 0 13.0000 Second D \n",
+ "\n",
+ " embark_town alone \n",
+ "0 Southampton y \n",
+ "1 Southampton y \n",
+ "2 Southampton y \n",
+ "3 Southampton y \n",
+ "4 Southampton y \n",
+ "0 0\n",
+ "1 1\n",
+ "2 1\n",
+ "3 1\n",
+ "4 0\n",
+ "Name: survived, dtype: int64\n",
+ "0 0\n",
+ "1 0\n",
+ "2 1\n",
+ "3 1\n",
+ "4 1\n",
+ "Name: survived, dtype: int64\n"
+ ]
+ }
+ ],
+ "source": [
+ "y_train = train_df.pop('survived')\n",
+ "y_eval = eval_df.pop('survived')\n",
+ "\n",
+ "print(train_df.head())\n",
+ "print(eval_df.head())\n",
+ "print(y_train.head())\n",
+ "print(y_eval.head())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " age | \n",
+ " n_siblings_spouses | \n",
+ " parch | \n",
+ " fare | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | count | \n",
+ " 627.000000 | \n",
+ " 627.000000 | \n",
+ " 627.000000 | \n",
+ " 627.000000 | \n",
+ "
\n",
+ " \n",
+ " | mean | \n",
+ " 29.631308 | \n",
+ " 0.545455 | \n",
+ " 0.379585 | \n",
+ " 34.385399 | \n",
+ "
\n",
+ " \n",
+ " | std | \n",
+ " 12.511818 | \n",
+ " 1.151090 | \n",
+ " 0.792999 | \n",
+ " 54.597730 | \n",
+ "
\n",
+ " \n",
+ " | min | \n",
+ " 0.750000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ "
\n",
+ " \n",
+ " | 25% | \n",
+ " 23.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 7.895800 | \n",
+ "
\n",
+ " \n",
+ " | 50% | \n",
+ " 28.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 15.045800 | \n",
+ "
\n",
+ " \n",
+ " | 75% | \n",
+ " 35.000000 | \n",
+ " 1.000000 | \n",
+ " 0.000000 | \n",
+ " 31.387500 | \n",
+ "
\n",
+ " \n",
+ " | max | \n",
+ " 80.000000 | \n",
+ " 8.000000 | \n",
+ " 5.000000 | \n",
+ " 512.329200 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " age n_siblings_spouses parch fare\n",
+ "count 627.000000 627.000000 627.000000 627.000000\n",
+ "mean 29.631308 0.545455 0.379585 34.385399\n",
+ "std 12.511818 1.151090 0.792999 54.597730\n",
+ "min 0.750000 0.000000 0.000000 0.000000\n",
+ "25% 23.000000 0.000000 0.000000 7.895800\n",
+ "50% 28.000000 0.000000 0.000000 15.045800\n",
+ "75% 35.000000 1.000000 0.000000 31.387500\n",
+ "max 80.000000 8.000000 5.000000 512.329200"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "train_df.describe()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "sex ['male' 'female']\n",
+ "n_siblings_spouses [1 0 3 4 2 5 8]\n",
+ "parch [0 1 2 5 3 4]\n",
+ "class ['Third' 'First' 'Second']\n",
+ "deck ['unknown' 'C' 'G' 'A' 'B' 'D' 'F' 'E']\n",
+ "embark_town ['Southampton' 'Cherbourg' 'Queenstown' 'unknown']\n",
+ "alone ['n' 'y']\n",
+ "age\n",
+ "fare\n"
+ ]
+ }
+ ],
+ "source": [
+ "categorical_columns = ['sex', 'n_siblings_spouses', 'parch', 'class',\n",
+ " 'deck', 'embark_town', 'alone']\n",
+ "numeric_columns = ['age', 'fare']\n",
+ "\n",
+ "feature_columns = []\n",
+ "for categorical_column in categorical_columns:\n",
+ " vocab = train_df[categorical_column].unique()\n",
+ " print(categorical_column, vocab)\n",
+ " feature_columns.append(\n",
+ " tf.feature_column.indicator_column(\n",
+ " #categorical_column_with_vocabulary_list可以直接看官网\n",
+ " tf.feature_column.categorical_column_with_vocabulary_list(\n",
+ " categorical_column, vocab)))\n",
+ "\n",
+ "for categorical_column in numeric_columns:\n",
+ " print(categorical_column)\n",
+ " feature_columns.append(\n",
+ " tf.feature_column.numeric_column(\n",
+ " categorical_column, dtype=tf.float32))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='sex', vocabulary_list=('male', 'female'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),\n",
+ " IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='n_siblings_spouses', vocabulary_list=(1, 0, 3, 4, 2, 5, 8), dtype=tf.int64, default_value=-1, num_oov_buckets=0)),\n",
+ " IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='parch', vocabulary_list=(0, 1, 2, 5, 3, 4), dtype=tf.int64, default_value=-1, num_oov_buckets=0)),\n",
+ " IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='class', vocabulary_list=('Third', 'First', 'Second'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),\n",
+ " IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='deck', vocabulary_list=('unknown', 'C', 'G', 'A', 'B', 'D', 'F', 'E'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),\n",
+ " IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='embark_town', vocabulary_list=('Southampton', 'Cherbourg', 'Queenstown', 'unknown'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),\n",
+ " IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='alone', vocabulary_list=('n', 'y'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),\n",
+ " NumericColumn(key='age', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None),\n",
+ " NumericColumn(key='fare', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)]"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "feature_columns"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "pandas.core.frame.DataFrame"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "type(train_df)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(627, 9)"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "train_df.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "pandas.core.series.Series"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "type(y_train)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "({'sex': , 'age': , 'n_siblings_spouses': , 'parch': , 'fare': , 'class': , 'deck': , 'embark_town': , 'alone': }, )\n"
+ ]
+ }
+ ],
+ "source": [
+ "dataset = tf.data.Dataset.from_tensor_slices(\n",
+ " (dict(train_df), y_train))\n",
+ "\n",
+ "for i in dataset.take(1):\n",
+ " print(i)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def make_dataset(data_df, label_df, epochs = 10, shuffle = True,\n",
+ " batch_size = 32):\n",
+ " dataset = tf.data.Dataset.from_tensor_slices(\n",
+ " (dict(data_df), label_df))\n",
+ " if shuffle:\n",
+ " dataset = dataset.shuffle(10000)\n",
+ " #必须是repeat类型的dataset,进行分批\n",
+ " dataset = dataset.repeat(epochs).batch(batch_size)\n",
+ " return dataset"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "!rm -rf linear_model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "chapter_5.tar.gz\tlinear_model_new_features\r\n",
+ "data\t\t\ttf01_keras_to_estimator.ipynb\r\n",
+ "dnn_model\t\ttf02_premade_estimators.ipynb\r\n",
+ "dnn_model_new_features\ttf03_premade_estimators-new_feature.ipynb\r\n"
+ ]
+ }
+ ],
+ "source": [
+ "!ls"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "INFO:tensorflow:Using default config.\n",
+ "INFO:tensorflow:Using config: {'_model_dir': 'linear_model', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
+ "graph_options {\n",
+ " rewrite_options {\n",
+ " meta_optimizer_iterations: ONE\n",
+ " }\n",
+ "}\n",
+ ", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
+ "INFO:tensorflow:Calling model_fn.\n",
+ "WARNING:tensorflow:Layer linear/linear_model is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2. The layer has dtype float32 because it's dtype defaults to floatx.\n",
+ "\n",
+ "If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.\n",
+ "\n",
+ "To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.\n",
+ "\n",
+ "INFO:tensorflow:Done calling model_fn.\n",
+ "INFO:tensorflow:Create CheckpointSaverHook.\n",
+ "INFO:tensorflow:Graph was finalized.\n",
+ "INFO:tensorflow:Running local_init_op.\n",
+ "INFO:tensorflow:Done running local_init_op.\n",
+ "INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...\n",
+ "INFO:tensorflow:Saving checkpoints for 0 into linear_model/model.ckpt.\n",
+ "INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...\n",
+ "INFO:tensorflow:loss = 0.6931472, step = 0\n",
+ "INFO:tensorflow:global_step/sec: 265.429\n",
+ "INFO:tensorflow:loss = 0.54358184, step = 100 (0.378 sec)\n",
+ "INFO:tensorflow:global_step/sec: 406.564\n",
+ "INFO:tensorflow:loss = 0.40915304, step = 200 (0.252 sec)\n",
+ "INFO:tensorflow:global_step/sec: 405.503\n",
+ "INFO:tensorflow:loss = 0.5051335, step = 300 (0.241 sec)\n",
+ "INFO:tensorflow:global_step/sec: 432.689\n",
+ "INFO:tensorflow:loss = 0.43714678, step = 400 (0.231 sec)\n",
+ "INFO:tensorflow:global_step/sec: 384.13\n",
+ "INFO:tensorflow:loss = 0.601617, step = 500 (0.261 sec)\n",
+ "INFO:tensorflow:global_step/sec: 352.212\n",
+ "INFO:tensorflow:loss = 0.38899624, step = 600 (0.285 sec)\n",
+ "INFO:tensorflow:global_step/sec: 414.072\n",
+ "INFO:tensorflow:loss = 0.42399123, step = 700 (0.241 sec)\n",
+ "INFO:tensorflow:global_step/sec: 403.726\n",
+ "INFO:tensorflow:loss = 0.45739985, step = 800 (0.247 sec)\n",
+ "INFO:tensorflow:global_step/sec: 430.339\n",
+ "INFO:tensorflow:loss = 0.41186857, step = 900 (0.232 sec)\n",
+ "INFO:tensorflow:global_step/sec: 414.636\n",
+ "INFO:tensorflow:loss = 0.3828747, step = 1000 (0.243 sec)\n",
+ "INFO:tensorflow:global_step/sec: 215.999\n",
+ "INFO:tensorflow:loss = 0.45267892, step = 1100 (0.464 sec)\n",
+ "INFO:tensorflow:global_step/sec: 385.851\n",
+ "INFO:tensorflow:loss = 0.57070553, step = 1200 (0.258 sec)\n",
+ "INFO:tensorflow:global_step/sec: 352.149\n",
+ "INFO:tensorflow:loss = 0.3337835, step = 1300 (0.287 sec)\n",
+ "INFO:tensorflow:global_step/sec: 429.843\n",
+ "INFO:tensorflow:loss = 0.3914045, step = 1400 (0.230 sec)\n",
+ "INFO:tensorflow:global_step/sec: 179.18\n",
+ "INFO:tensorflow:loss = 0.48763037, step = 1500 (0.555 sec)\n",
+ "INFO:tensorflow:global_step/sec: 386.195\n",
+ "INFO:tensorflow:loss = 0.31568778, step = 1600 (0.262 sec)\n",
+ "INFO:tensorflow:global_step/sec: 365.156\n",
+ "INFO:tensorflow:loss = 0.38609415, step = 1700 (0.272 sec)\n",
+ "INFO:tensorflow:global_step/sec: 355.98\n",
+ "INFO:tensorflow:loss = 0.41178137, step = 1800 (0.286 sec)\n",
+ "INFO:tensorflow:global_step/sec: 376.441\n",
+ "INFO:tensorflow:loss = 0.38143158, step = 1900 (0.263 sec)\n",
+ "INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 1960...\n",
+ "INFO:tensorflow:Saving checkpoints for 1960 into linear_model/model.ckpt.\n",
+ "INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 1960...\n",
+ "INFO:tensorflow:Loss for final step: 0.33108896.\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "linear_output_dir = 'linear_model'\n",
+ "if not os.path.exists(linear_output_dir):\n",
+ " os.mkdir(linear_output_dir)\n",
+ "#线性分类器模型\n",
+ "linear_estimator = tf.estimator.LinearClassifier(\n",
+ " model_dir = linear_output_dir,#把训练好的模型保存到该文件夹\n",
+ " n_classes = 2,\n",
+ " #之前定义好的feature_columns传入\n",
+ " feature_columns = feature_columns)\n",
+ "linear_estimator.train(input_fn = lambda : make_dataset(\n",
+ " train_df, y_train, epochs = 100))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 线性分类器和逻辑回归公式一样,特征数目多少,对应就有多少的w参数(不重要,用来学习如何对估计器入参)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['global_step',\n",
+ " 'linear/linear_model/age/weights',\n",
+ " 'linear/linear_model/alone_indicator/weights',\n",
+ " 'linear/linear_model/bias_weights',\n",
+ " 'linear/linear_model/class_indicator/weights',\n",
+ " 'linear/linear_model/deck_indicator/weights',\n",
+ " 'linear/linear_model/embark_town_indicator/weights',\n",
+ " 'linear/linear_model/fare/weights',\n",
+ " 'linear/linear_model/n_siblings_spouses_indicator/weights',\n",
+ " 'linear/linear_model/parch_indicator/weights',\n",
+ " 'linear/linear_model/sex_indicator/weights',\n",
+ " 'training/Ftrl/decay',\n",
+ " 'training/Ftrl/l1_regularization_strength',\n",
+ " 'training/Ftrl/l2_regularization_strength',\n",
+ " 'training/Ftrl/learning_rate',\n",
+ " 'training/Ftrl/learning_rate_power',\n",
+ " 'training/Ftrl/linear/linear_model/age/weights/accumulator',\n",
+ " 'training/Ftrl/linear/linear_model/age/weights/linear',\n",
+ " 'training/Ftrl/linear/linear_model/alone_indicator/weights/accumulator',\n",
+ " 'training/Ftrl/linear/linear_model/alone_indicator/weights/linear',\n",
+ " 'training/Ftrl/linear/linear_model/bias_weights/accumulator',\n",
+ " 'training/Ftrl/linear/linear_model/bias_weights/linear',\n",
+ " 'training/Ftrl/linear/linear_model/class_indicator/weights/accumulator',\n",
+ " 'training/Ftrl/linear/linear_model/class_indicator/weights/linear',\n",
+ " 'training/Ftrl/linear/linear_model/deck_indicator/weights/accumulator',\n",
+ " 'training/Ftrl/linear/linear_model/deck_indicator/weights/linear',\n",
+ " 'training/Ftrl/linear/linear_model/embark_town_indicator/weights/accumulator',\n",
+ " 'training/Ftrl/linear/linear_model/embark_town_indicator/weights/linear',\n",
+ " 'training/Ftrl/linear/linear_model/fare/weights/accumulator',\n",
+ " 'training/Ftrl/linear/linear_model/fare/weights/linear',\n",
+ " 'training/Ftrl/linear/linear_model/n_siblings_spouses_indicator/weights/accumulator',\n",
+ " 'training/Ftrl/linear/linear_model/n_siblings_spouses_indicator/weights/linear',\n",
+ " 'training/Ftrl/linear/linear_model/parch_indicator/weights/accumulator',\n",
+ " 'training/Ftrl/linear/linear_model/parch_indicator/weights/linear',\n",
+ " 'training/Ftrl/linear/linear_model/sex_indicator/weights/accumulator',\n",
+ " 'training/Ftrl/linear/linear_model/sex_indicator/weights/linear']"
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "linear_estimator.get_variable_names()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1960"
+ ]
+ },
+ "execution_count": 16,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "linear_estimator.get_variable_value('global_step')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[-1.4050889],\n",
+ " [-3.0595324],\n",
+ " [-1.456432 ],\n",
+ " [ 1.2338951],\n",
+ " [-0.9311088],\n",
+ " [ 2.0698297]], dtype=float32)"
+ ]
+ },
+ "execution_count": 20,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "linear_estimator.get_variable_value('training/Ftrl/linear/linear_model/parch_indicator/weights/linear')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[19.57078]], dtype=float32)"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "linear_estimator.get_variable_value( 'training/Ftrl/linear/linear_model/age/weights/linear')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[7.7724013],\n",
+ " [4.0160937]], dtype=float32)"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "linear_estimator.get_variable_value('training/Ftrl/linear/linear_model/sex_indicator/weights/accumulator')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "总用量 1648\r\n",
+ "-rw-rw-r-- 1 luke luke 130 May 7 15:11 checkpoint\r\n",
+ "-rw-rw-r-- 1 luke luke 925955 May 7 15:11 graph.pbtxt\r\n",
+ "-rw-rw-r-- 1 luke luke 448 May 7 15:11 model.ckpt-0.data-00000-of-00001\r\n",
+ "-rw-rw-r-- 1 luke luke 1777 May 7 15:11 model.ckpt-0.index\r\n",
+ "-rw-rw-r-- 1 luke luke 367755 May 7 15:11 model.ckpt-0.meta\r\n",
+ "-rw-rw-r-- 1 luke luke 448 May 7 15:11 model.ckpt-1960.data-00000-of-00001\r\n",
+ "-rw-rw-r-- 1 luke luke 1777 May 7 15:11 model.ckpt-1960.index\r\n",
+ "-rw-rw-r-- 1 luke luke 367755 May 7 15:11 model.ckpt-1960.meta\r\n"
+ ]
+ }
+ ],
+ "source": [
+ "!ls -l linear_model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "!rm -rf linear_model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "INFO:tensorflow:Calling model_fn.\n",
+ "WARNING:tensorflow:Layer linear/linear_model is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2. The layer has dtype float32 because it's dtype defaults to floatx.\n",
+ "\n",
+ "If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.\n",
+ "\n",
+ "To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.\n",
+ "\n",
+ "INFO:tensorflow:Done calling model_fn.\n",
+ "INFO:tensorflow:Starting evaluation at 2022-07-25T11:34:48Z\n",
+ "INFO:tensorflow:Graph was finalized.\n",
+ "INFO:tensorflow:Restoring parameters from linear_model/model.ckpt-1960\n",
+ "INFO:tensorflow:Running local_init_op.\n",
+ "INFO:tensorflow:Done running local_init_op.\n",
+ "INFO:tensorflow:Inference Time : 1.56176s\n",
+ "INFO:tensorflow:Finished evaluation at 2022-07-25-11:34:50\n",
+ "INFO:tensorflow:Saving dict for global step 1960: accuracy = 0.7689394, accuracy_baseline = 0.625, auc = 0.83728194, auc_precision_recall = 0.7887981, average_loss = 0.47722998, global_step = 1960, label/mean = 0.375, loss = 0.46082607, precision = 0.6792453, prediction/mean = 0.42161626, recall = 0.72727275\n",
+ "INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1960: linear_model/model.ckpt-1960\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "{'accuracy': 0.7689394,\n",
+ " 'accuracy_baseline': 0.625,\n",
+ " 'auc': 0.83728194,\n",
+ " 'auc_precision_recall': 0.7887981,\n",
+ " 'average_loss': 0.47722998,\n",
+ " 'label/mean': 0.375,\n",
+ " 'loss': 0.46082607,\n",
+ " 'precision': 0.6792453,\n",
+ " 'prediction/mean': 0.42161626,\n",
+ " 'recall': 0.72727275,\n",
+ " 'global_step': 1960}"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "linear_estimator.evaluate(input_fn = lambda : make_dataset(\n",
+ " eval_df, y_eval, epochs = 1, shuffle = False))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "chapter_5.tar.gz\tlinear_model_new_features\r\n",
+ "data\t\t\ttf01_keras_to_estimator.ipynb\r\n",
+ "dnn_model_new_features\ttf02_premade_estimators.ipynb\r\n",
+ "linear_model\t\ttf03_premade_estimators-new_feature.ipynb\r\n"
+ ]
+ }
+ ],
+ "source": [
+ "!rm -rf dnn_model\n",
+ "!ls"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "INFO:tensorflow:Using default config.\n",
+ "INFO:tensorflow:Using config: {'_model_dir': './dnn_model', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
+ "graph_options {\n",
+ " rewrite_options {\n",
+ " meta_optimizer_iterations: ONE\n",
+ " }\n",
+ "}\n",
+ ", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
+ "INFO:tensorflow:Calling model_fn.\n",
+ "WARNING:tensorflow:Layer dnn is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2. The layer has dtype float32 because it's dtype defaults to floatx.\n",
+ "\n",
+ "If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.\n",
+ "\n",
+ "To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.\n",
+ "\n",
+ "INFO:tensorflow:Done calling model_fn.\n",
+ "INFO:tensorflow:Create CheckpointSaverHook.\n",
+ "INFO:tensorflow:Graph was finalized.\n",
+ "INFO:tensorflow:Running local_init_op.\n",
+ "INFO:tensorflow:Done running local_init_op.\n",
+ "INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...\n",
+ "INFO:tensorflow:Saving checkpoints for 0 into ./dnn_model/model.ckpt.\n",
+ "INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...\n",
+ "INFO:tensorflow:loss = 1.7517047, step = 0\n",
+ "INFO:tensorflow:global_step/sec: 227.7\n",
+ "INFO:tensorflow:loss = 0.5908904, step = 100 (0.440 sec)\n",
+ "INFO:tensorflow:global_step/sec: 299.554\n",
+ "INFO:tensorflow:loss = 0.72778654, step = 200 (0.334 sec)\n",
+ "INFO:tensorflow:global_step/sec: 280.111\n",
+ "INFO:tensorflow:loss = 0.4129332, step = 300 (0.358 sec)\n",
+ "INFO:tensorflow:global_step/sec: 298.743\n",
+ "INFO:tensorflow:loss = 0.4081448, step = 400 (0.335 sec)\n",
+ "INFO:tensorflow:global_step/sec: 294.901\n",
+ "INFO:tensorflow:loss = 0.34344202, step = 500 (0.340 sec)\n",
+ "INFO:tensorflow:global_step/sec: 197.57\n",
+ "INFO:tensorflow:loss = 0.48251998, step = 600 (0.505 sec)\n",
+ "INFO:tensorflow:global_step/sec: 270.445\n",
+ "INFO:tensorflow:loss = 0.46485394, step = 700 (0.377 sec)\n",
+ "INFO:tensorflow:global_step/sec: 199.444\n",
+ "INFO:tensorflow:loss = 0.43934634, step = 800 (0.497 sec)\n",
+ "INFO:tensorflow:global_step/sec: 172.098\n",
+ "INFO:tensorflow:loss = 0.43851897, step = 900 (0.582 sec)\n",
+ "INFO:tensorflow:global_step/sec: 286.941\n",
+ "INFO:tensorflow:loss = 0.40801227, step = 1000 (0.344 sec)\n",
+ "INFO:tensorflow:global_step/sec: 187.581\n",
+ "INFO:tensorflow:loss = 0.35152194, step = 1100 (0.541 sec)\n",
+ "INFO:tensorflow:global_step/sec: 201.156\n",
+ "INFO:tensorflow:loss = 0.32771125, step = 1200 (0.492 sec)\n",
+ "INFO:tensorflow:global_step/sec: 292.106\n",
+ "INFO:tensorflow:loss = 0.21761335, step = 1300 (0.341 sec)\n",
+ "INFO:tensorflow:global_step/sec: 272.757\n",
+ "INFO:tensorflow:loss = 0.1947256, step = 1400 (0.365 sec)\n",
+ "INFO:tensorflow:global_step/sec: 283.708\n",
+ "INFO:tensorflow:loss = 0.31947747, step = 1500 (0.356 sec)\n",
+ "INFO:tensorflow:global_step/sec: 261.331\n",
+ "INFO:tensorflow:loss = 0.29513022, step = 1600 (0.380 sec)\n",
+ "INFO:tensorflow:global_step/sec: 298.262\n",
+ "INFO:tensorflow:loss = 0.5517792, step = 1700 (0.336 sec)\n",
+ "INFO:tensorflow:global_step/sec: 309.055\n",
+ "INFO:tensorflow:loss = 0.46572062, step = 1800 (0.324 sec)\n",
+ "INFO:tensorflow:global_step/sec: 285.865\n",
+ "INFO:tensorflow:loss = 0.27346686, step = 1900 (0.350 sec)\n",
+ "INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 1960...\n",
+ "INFO:tensorflow:Saving checkpoints for 1960 into ./dnn_model/model.ckpt.\n",
+ "INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 1960...\n",
+ "INFO:tensorflow:Loss for final step: 0.1655132.\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 23,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "#下面是使用dnn估计器\n",
+ "dnn_output_dir = './dnn_model'\n",
+ "if not os.path.exists(dnn_output_dir):\n",
+ " os.mkdir(dnn_output_dir)\n",
+ "#创建dnn估计器\n",
+ "dnn_estimator = tf.estimator.DNNClassifier(\n",
+ " model_dir = dnn_output_dir,\n",
+ " n_classes = 2,\n",
+ " feature_columns=feature_columns,\n",
+ " #因为是dnn,我们定义层,两层,每一层是128\n",
+ " hidden_units = [128, 128,128],\n",
+ " #激活函数\n",
+ " activation_fn = tf.nn.relu,\n",
+ " #在Linear也有这个参数,只不过默认的,我们没有设置\n",
+ " optimizer = 'Adam')\n",
+ "#开始训练\n",
+ "dnn_estimator.train(input_fn = lambda : make_dataset(\n",
+ " train_df, y_train, epochs = 100))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['dnn/hiddenlayer_0/bias',\n",
+ " 'dnn/hiddenlayer_0/kernel',\n",
+ " 'dnn/hiddenlayer_1/bias',\n",
+ " 'dnn/hiddenlayer_1/kernel',\n",
+ " 'dnn/hiddenlayer_2/bias',\n",
+ " 'dnn/hiddenlayer_2/kernel',\n",
+ " 'dnn/logits/bias',\n",
+ " 'dnn/logits/kernel',\n",
+ " 'global_step',\n",
+ " 'training/Adam/beta_1',\n",
+ " 'training/Adam/beta_2',\n",
+ " 'training/Adam/decay',\n",
+ " 'training/Adam/dnn/hiddenlayer_0/bias/m',\n",
+ " 'training/Adam/dnn/hiddenlayer_0/bias/v',\n",
+ " 'training/Adam/dnn/hiddenlayer_0/kernel/m',\n",
+ " 'training/Adam/dnn/hiddenlayer_0/kernel/v',\n",
+ " 'training/Adam/dnn/hiddenlayer_1/bias/m',\n",
+ " 'training/Adam/dnn/hiddenlayer_1/bias/v',\n",
+ " 'training/Adam/dnn/hiddenlayer_1/kernel/m',\n",
+ " 'training/Adam/dnn/hiddenlayer_1/kernel/v',\n",
+ " 'training/Adam/dnn/hiddenlayer_2/bias/m',\n",
+ " 'training/Adam/dnn/hiddenlayer_2/bias/v',\n",
+ " 'training/Adam/dnn/hiddenlayer_2/kernel/m',\n",
+ " 'training/Adam/dnn/hiddenlayer_2/kernel/v',\n",
+ " 'training/Adam/dnn/logits/bias/m',\n",
+ " 'training/Adam/dnn/logits/bias/v',\n",
+ " 'training/Adam/dnn/logits/kernel/m',\n",
+ " 'training/Adam/dnn/logits/kernel/v',\n",
+ " 'training/Adam/learning_rate']"
+ ]
+ },
+ "execution_count": 24,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dnn_estimator.get_variable_names()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(128, 1)"
+ ]
+ },
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dnn_estimator.get_variable_value('training/Adam/dnn/logits/kernel/v').shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(1,)"
+ ]
+ },
+ "execution_count": 29,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dnn_estimator.get_variable_value('dnn/logits/bias').shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(128,)"
+ ]
+ },
+ "execution_count": 27,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dnn_estimator.get_variable_value('dnn/hiddenlayer_0/bias').shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(128,)"
+ ]
+ },
+ "execution_count": 26,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dnn_estimator.get_variable_value('training/Adam/dnn/hiddenlayer_0/bias/m').shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(34, 128)"
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dnn_estimator.get_variable_value('training/Adam/dnn/hiddenlayer_0/kernel/m').shape #adam显示这么多参数不准确"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "INFO:tensorflow:Calling model_fn.\n",
+ "WARNING:tensorflow:Layer dnn is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2. The layer has dtype float32 because it's dtype defaults to floatx.\n",
+ "\n",
+ "If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.\n",
+ "\n",
+ "To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.\n",
+ "\n",
+ "INFO:tensorflow:Done calling model_fn.\n",
+ "INFO:tensorflow:Starting evaluation at 2022-07-25T11:48:35Z\n",
+ "INFO:tensorflow:Graph was finalized.\n",
+ "INFO:tensorflow:Restoring parameters from ./dnn_model/model.ckpt-1960\n",
+ "INFO:tensorflow:Running local_init_op.\n",
+ "INFO:tensorflow:Done running local_init_op.\n",
+ "INFO:tensorflow:Inference Time : 1.12736s\n",
+ "INFO:tensorflow:Finished evaluation at 2022-07-25-11:48:37\n",
+ "INFO:tensorflow:Saving dict for global step 1960: accuracy = 0.78409094, accuracy_baseline = 0.625, auc = 0.84845424, auc_precision_recall = 0.79287136, average_loss = 0.6005163, global_step = 1960, label/mean = 0.375, loss = 0.5904457, precision = 0.66935486, prediction/mean = 0.49685264, recall = 0.83838385\n",
+ "INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1960: ./dnn_model/model.ckpt-1960\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "{'accuracy': 0.78409094,\n",
+ " 'accuracy_baseline': 0.625,\n",
+ " 'auc': 0.84845424,\n",
+ " 'auc_precision_recall': 0.79287136,\n",
+ " 'average_loss': 0.6005163,\n",
+ " 'label/mean': 0.375,\n",
+ " 'loss': 0.5904457,\n",
+ " 'precision': 0.66935486,\n",
+ " 'prediction/mean': 0.49685264,\n",
+ " 'recall': 0.83838385,\n",
+ " 'global_step': 1960}"
+ ]
+ },
+ "execution_count": 32,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# 评估\n",
+ "dnn_estimator.evaluate(input_fn = lambda : make_dataset(\n",
+ " eval_df, y_eval, epochs = 1, shuffle = False))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}