{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "Vc6_2ntY1bf7" }, "source": [ "# 머신 러닝 교과서 3판" ] }, { "cell_type": "markdown", "metadata": { "id": "zDc0-lf51bgB" }, "source": [ "# 14장 - 텐서플로의 구조 자세히 알아보기 (3/3)" ] }, { "cell_type": "markdown", "metadata": { "id": "5uWGlsyu1bgB" }, "source": [ "**아래 링크를 통해 이 노트북을 주피터 노트북 뷰어(nbviewer.jupyter.org)로 보거나 구글 코랩(colab.research.google.com)에서 실행할 수 있습니다.**\n", "\n", "\n", " \n", " \n", "
\n", " 주피터 노트북 뷰어로 보기\n", " \n", " 구글 코랩(Colab)에서 실행하기\n", "
" ] }, { "cell_type": "markdown", "metadata": { "id": "MNC_qLbl1bgC" }, "source": [ "### 목차" ] }, { "cell_type": "markdown", "metadata": { "id": "hRk4nqAW1bgC" }, "source": [ "- 텐서플로 추정기\n", " - 추정기를 사용해 MNIST 손글씨 숫자 분류하기\n", " - 케라스 모델에서 추정기 만들기" ] }, { "cell_type": "markdown", "metadata": { "id": "xz4vMonracix" }, "source": [ "**중요: 최신 텐서플로에서는 `tf.estimator`가 더이상 제공되지 않으므로 이 노트북의 코드를 실행할 수 없습니다.**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "UoxDNsX-1bgC" }, "outputs": [], "source": [ "import tensorflow as tf\n", "import tensorflow_datasets as tfds\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 36 }, "id": "OE8GOBaS1dzc", "outputId": "97af4d89-c239-4bea-96af-311b1a8ccd22" }, "outputs": [ { "data": { "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" }, "text/plain": [ "'2.14.0'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tf.__version__" ] }, { "cell_type": "markdown", "metadata": { "id": "Ajj9IQD71bgD" }, "source": [ "### 추정기를 사용해 MNIST 손글씨 숫자 분류하기" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Y6Bayxva1bgD" }, "outputs": [], "source": [ "BUFFER_SIZE = 10000\n", "BATCH_SIZE = 64\n", "NUM_EPOCHS = 20\n", "steps_per_epoch = np.ceil(60000 / BATCH_SIZE)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "WYZ_v7tC1bgD" }, "outputs": [], "source": [ "def preprocess(item):\n", " image = item['image']\n", " label = item['label']\n", " image = tf.image.convert_image_dtype(\n", " image, tf.float32)\n", " image = tf.reshape(image, (-1,))\n", "\n", " return {'image-pixels':image}, label[..., tf.newaxis]\n", "\n", "# 단계 1: 입력 함수 두 개를 정의합니다(하나는 훈련용이고 다른 하나는 평가용입니다).\n", "## 훈련용 입력 함수\n", "def train_input_fn():\n", " datasets = tfds.load(name='mnist')\n", " mnist_train = datasets['train']\n", "\n", " dataset = mnist_train.map(preprocess)\n", " dataset = dataset.shuffle(BUFFER_SIZE)\n", " dataset = dataset.batch(BATCH_SIZE)\n", " return dataset.repeat()\n", "\n", "## 평가용 입력 함수\n", "def eval_input_fn():\n", " datasets = tfds.load(name='mnist')\n", " mnist_test = datasets['test']\n", " dataset = mnist_test.map(preprocess).batch(BATCH_SIZE)\n", " return dataset" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "c5NL8mgz1bgD", "outputId": "770f0aa1-cd36-47b5-e5ba-b67eadac4c6e" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tensorflow:From :2: numeric_column (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use Keras preprocessing layers instead, either directly or via the `tf.keras.utils.FeatureSpace` utility. Each of `tf.feature_column.*` has a functional equivalent in `tf.keras.layers` for feature preprocessing when training a Keras model.\n" ] } ], "source": [ "## 단계 2: 특성 열을 정의합니다.\n", "image_feature_column = tf.feature_column.numeric_column(\n", " key='image-pixels', shape=(28*28))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 1000, "referenced_widgets": [ "9c7faf75cc774b85bc088716b86bc45a", "af50f185100145a99ebbd38685daef1e", "2c9e70fcfb4044b2acaf6f2776f56c0c", "8e6152fc5b2545f7b6be179d25efa01c", "48b949d09376456aa2edb361c2916cff", "6fbe9dbd09d04a12b93c61c788a96a8d", "9c43635a242f432b98f8b9189cb28299", "50b79269761e4942abc8d7709baadc2b", "93eb1aee05444ebb805dbc95b28784d9", "950085c8308446b986569c2e0b846282", "6d4c91b1b9594ba8988de2e29cfa9868" ] }, "id": "h1mC7Kl71bgE", "outputId": "0ea5c236-dcc3-4135-d189-855dea3f0c4f" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tensorflow:From :2: DNNClassifierV2.__init__ (from tensorflow_estimator.python.estimator.canned.dnn) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use tf.keras instead.\n", "WARNING:tensorflow:From /usr/local/lib/python3.10/dist-packages/tensorflow_estimator/python/estimator/head/head_utils.py:59: MultiClassHead.__init__ (from tensorflow_estimator.python.estimator.head.multi_class_head) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use tf.keras instead.\n", "WARNING:tensorflow:From /usr/local/lib/python3.10/dist-packages/tensorflow_estimator/python/estimator/canned/dnn.py:759: Estimator.__init__ (from tensorflow_estimator.python.estimator.estimator) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use tf.keras instead.\n", "WARNING:tensorflow:From /usr/local/lib/python3.10/dist-packages/tensorflow_estimator/python/estimator/estimator.py:1844: RunConfig.__init__ (from tensorflow_estimator.python.estimator.run_config) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use tf.keras instead.\n", "WARNING:tensorflow:From /usr/local/lib/python3.10/dist-packages/tensorflow_estimator/python/estimator/estimator.py:385: StopAtStepHook.__init__ (from tensorflow.python.training.basic_session_run_hooks) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use tf.keras instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Downloading and preparing dataset 11.06 MiB (download: 11.06 MiB, generated: 21.00 MiB, total: 32.06 MiB) to /root/tensorflow_datasets/mnist/3.0.1...\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9c7faf75cc774b85bc088716b86bc45a", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Dl Completed...: 0%| | 0/5 [00:00" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## 단계 3: 추정기 객체를 만듭니다.\n", "dnn_classifier = tf.estimator.DNNClassifier(\n", " feature_columns=[image_feature_column],\n", " hidden_units=[32, 16],\n", " n_classes=10,\n", " model_dir='models/mnist-dnn/')\n", "\n", "\n", "## 단계 4: 훈련합니다.\n", "dnn_classifier.train(\n", " input_fn=train_input_fn,\n", " steps=NUM_EPOCHS * steps_per_epoch)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "aXaMFToY1bgF", "outputId": "138acf2d-9b23-4b89-b226-f2ccb57de2b9" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tensorflow:From /usr/local/lib/python3.10/dist-packages/tensorflow/python/training/evaluation.py:260: FinalOpsHook.__init__ (from tensorflow.python.training.basic_session_run_hooks) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use tf.keras instead.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "{'accuracy': 0.8893, 'average_loss': 0.40692627, 'loss': 0.406641, 'global_step': 18760}\n" ] } ], "source": [ "eval_result = dnn_classifier.evaluate(\n", " input_fn=eval_input_fn)\n", "\n", "print(eval_result)" ] }, { "cell_type": "markdown", "metadata": { "id": "PRBS6RHT1bgG" }, "source": [ "### 케라스 모델에서 추정기 만들기" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "xhBhmPZE1bgG" }, "outputs": [], "source": [ "## 결과 재현을 위한 랜덤 시드\n", "tf.random.set_seed(1)\n", "np.random.seed(1)\n", "\n", "## 데이터 생성\n", "x = np.random.uniform(low=-1, high=1, size=(200, 2))\n", "y = np.ones(len(x))\n", "y[x[:, 0] * x[:, 1]<0] = 0\n", "\n", "x_train = x[:100, :]\n", "y_train = y[:100]\n", "x_valid = x[100:, :]\n", "y_valid = y[100:]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "PRu_s75W1bgG" }, "outputs": [], "source": [ "## 단계 1: 입력 함수를 정의합니다.\n", "def train_input_fn(x_train, y_train, batch_size=8):\n", " dataset = tf.data.Dataset.from_tensor_slices(\n", " ({'input-features':x_train}, y_train.reshape(-1, 1)))\n", "\n", " # 셔플, 반복, 배치\n", " return dataset.shuffle(100).repeat().batch(batch_size)\n", "\n", "def eval_input_fn(x_test, y_test=None, batch_size=8):\n", " if y_test is None:\n", " dataset = tf.data.Dataset.from_tensor_slices(\n", " {'input-features':x_test})\n", " else:\n", " dataset = tf.data.Dataset.from_tensor_slices(\n", " ({'input-features':x_test}, y_test.reshape(-1, 1)))\n", "\n", "\n", " # 셔플, 반복, 배치\n", " return dataset.batch(batch_size)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "0HQ9pdHf1bgG", "outputId": "d506e37a-b9ba-4c9a-ba8e-c81a935394a1" }, "outputs": [ { "data": { "text/plain": [ "[NumericColumn(key='input-features:', shape=(2,), default_value=None, dtype=tf.float32, normalizer_fn=None)]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## 단계 2: 특성 열을 정의합니다.\n", "features = [\n", " tf.feature_column.numeric_column(\n", " key='input-features:', shape=(2,))\n", "]\n", "\n", "features" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "RcrqbWpI1bgH", "outputId": "ecf5ecff-8ddf-404d-b61d-9a87f76b6d02" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Model: \"sequential\"\n", "_________________________________________________________________\n", " Layer (type) Output Shape Param # \n", "=================================================================\n", " dense (Dense) (None, 4) 12 \n", " \n", " dense_1 (Dense) (None, 4) 20 \n", " \n", " dense_2 (Dense) (None, 4) 20 \n", " \n", " dense_3 (Dense) (None, 1) 5 \n", " \n", "=================================================================\n", "Total params: 57 (228.00 Byte)\n", "Trainable params: 57 (228.00 Byte)\n", "Non-trainable params: 0 (0.00 Byte)\n", "_________________________________________________________________\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are using `tf.keras.optimizers.experimental.Optimizer` in TF estimator, which only supports `tf.keras.optimizers.legacy.Optimizer`. Automatically converting your optimizer to `tf.keras.optimizers.legacy.Optimizer`.\n", "/usr/local/lib/python3.10/dist-packages/keras/src/backend.py:452: UserWarning: `tf.keras.backend.set_learning_phase` is deprecated and will be removed after 2020-10-11. To update it, simply pass a True/False value to the `training` argument of the `__call__` method of your layer or model.\n", " warnings.warn(\n", "WARNING:tensorflow:From /usr/local/lib/python3.10/dist-packages/tensorflow_estimator/python/estimator/estimator.py:2404: WarmStartSettings.__new__ (from tensorflow_estimator.python.estimator.estimator) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use tf.keras instead.\n" ] } ], "source": [ "## 단계 3: 케라스 모델을 변환하여 추정기를 만듭니다.\n", "model = tf.keras.Sequential([\n", " tf.keras.layers.Input(shape=(2,), name='input-features'),\n", " tf.keras.layers.Dense(units=4, activation='relu'),\n", " tf.keras.layers.Dense(units=4, activation='relu'),\n", " tf.keras.layers.Dense(units=4, activation='relu'),\n", " tf.keras.layers.Dense(1, activation='sigmoid')\n", "])\n", "\n", "model.summary()\n", "\n", "model.compile(optimizer=tf.keras.optimizers.SGD(),\n", " loss=tf.keras.losses.BinaryCrossentropy(),\n", " metrics=[tf.keras.metrics.BinaryAccuracy()])\n", "\n", "my_estimator = tf.keras.estimator.model_to_estimator(\n", " keras_model=model,\n", " model_dir='models/estimator-for-XOR/')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ZIj9G3201bgH", "outputId": "10354bb0-a170-4276-fab7-179b657d75b6" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tensorflow:From /usr/local/lib/python3.10/dist-packages/tensorflow_estimator/python/estimator/keras_lib.py:400: PredictOutput.__init__ (from tensorflow.python.saved_model.model_utils.export_output) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use tf.keras instead.\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## 단계 4: 추정기를 사용합니다: 훈련/평가/예측\n", "\n", "num_epochs = 200\n", "batch_size = 2\n", "steps_per_epoch = np.ceil(len(x_train) / batch_size)\n", "\n", "my_estimator.train(\n", " input_fn=lambda: train_input_fn(x_train, y_train, batch_size),\n", " steps=num_epochs * steps_per_epoch)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "YfaQLO_c1bgI", "outputId": "b8d36c36-ef18-46bb-df43-5815ea3cfeb3" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/lib/python3.10/dist-packages/keras/src/engine/training_v1.py:2335: UserWarning: `Model.state_updates` will be removed in a future version. This property should not be used in TensorFlow 2.0, as `updates` are applied automatically.\n", " updates = self.state_updates\n" ] }, { "data": { "text/plain": [ "{'binary_accuracy': 0.53, 'loss': 0.6913502, 'global_step': 10000}" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_estimator.evaluate(\n", " input_fn=lambda: eval_input_fn(x_valid, y_valid, batch_size))" ] } ], "metadata": { "accelerator": "GPU", "colab": { "name": "ch14_part3.ipynb", "provenance": [] }, "gpuClass": "standard", "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.5" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }