From d9a000ea69ab6b7c8fa08607c38094bfc13c231e Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Sat, 16 Mar 2019 15:42:59 +0900 Subject: [PATCH 01/19] Start a traslation --- .../eager/automatic_differentiation.ipynb | 323 ++++++++++++++++++ 1 file changed, 323 insertions(+) create mode 100644 site/ko/tutorials/eager/automatic_differentiation.ipynb diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb new file mode 100644 index 00000000000..ad6746c6de8 --- /dev/null +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -0,0 +1,323 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "t09eeeR5prIJ" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "form", + "colab": {}, + "colab_type": "code", + "id": "GCCk8_dHpuNf" + }, + "outputs": [], + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "xh8WkEwWpnm7" + }, + "source": [ + "# Automatic differentiation and gradient tape" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "idv0bPeCp325" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " View on TensorFlow.org\n", + " \n", + " Run in Google Colab\n", + " \n", + " View source on GitHub\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "vDJ4XzMqodTy" + }, + "source": [ + "이전 튜토리얼에서 우리는 Tensor와 연산자들에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술인 [자동미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "GQJysDM__Qb0" + }, + "source": [ + "## 설정\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "OiMPZStlibBv" + }, + "outputs": [], + "source": [ + "import tensorflow as tf\n", + "\n", + "tf.enable_eager_execution()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "1CLWJl0QliB0" + }, + "source": [ + "## 그래디언트 테이프(Gradient Tape)\n", + "\n", + "텐서플로우는 자동미분(주어진 입력 변수에 따른 기울기 계산)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape` 내에서 실행된 모든 연산자들을 tape에 \"기록\"합니다. 그리고 [역방향 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 기록된 계산의 그래디언트를 계산하기 위해 각각의 기록된 연산자들과 관련된 테이프와 그래디언트들을 사용합니다. \n", + "\n", + "예를 들면:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "bAFeIE8EuVIq" + }, + "outputs": [], + "source": [ + "x = tf.ones((2, 2))\n", + " \n", + "with tf.GradientTape() as t:\n", + " t.watch(x)\n", + " y = tf.reduce_sum(x)\n", + " z = tf.multiply(y, y)\n", + "\n", + "# 입력 tensor x에 관한 z의 도함수\n", + "dz_dx = t.gradient(z, x)\n", + "for i in [0, 1]:\n", + " for j in [0, 1]:\n", + " assert dz_dx[i][j].numpy() == 8.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "N4VlqKFzzGaC" + }, + "source": [ + "또한 `tf.GradientTape` 컨텍스트에 기록되는 동안 계산된 중간 출력값의 그래디언트를 계산할 수 있습니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "7XaPRAwUyYms" + }, + "outputs": [], + "source": [ + "x = tf.ones((2, 2))\n", + " \n", + "with tf.GradientTape() as t:\n", + " t.watch(x)\n", + " y = tf.reduce_sum(x)\n", + " z = tf.multiply(y, y)\n", + "\n", + "# 중간값 y에 관한 z의 도함수 계산을 위한 테이프 사용\n", + "# intermediate value y.\n", + "dz_dy = t.gradient(z, y)\n", + "assert dz_dy.numpy() == 8.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "ISkXuY7YzIcS" + }, + "source": [ + "초기값으로 GradientTape.gradient() 메소드가 호출되면 GradientTape에 포함된 리소스가 해체되게 설정돼있습니다. 동일한 계산을 통해서 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. `persistent`는 `gradient()` 메소드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "zZaCm3-9zVCi" + }, + "outputs": [], + "source": [ + "x = tf.constant(3.0)\n", + "with tf.GradientTape(persistent=True) as t:\n", + " t.watch(x)\n", + " y = x * x\n", + " z = y * y\n", + "dz_dx = t.gradient(z, x) # 108.0 (4*x^3 at x = 3)\n", + "dy_dx = t.gradient(y, x) # 6.0\n", + "del t # 리소스가 해체됩니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "6kADybtQzYj4" + }, + "source": [ + "### 제어흐름(Control Flow) 기록\n", + "\n", + "테이프가 실행되는데로 연산자를 기록하기 때문에, 파이썬 제어흐름(예를 들어 `if` `while`, `for`문 같은)은 자연스럽게 처리됩니다. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "9FViq92UX7P8" + }, + "outputs": [], + "source": [ + "def f(x, y):\n", + " output = 1.0\n", + " for i in range(y):\n", + " if i > 1 and i < 5:\n", + " output = tf.multiply(output, x)\n", + " return output\n", + "\n", + "def grad(x, y):\n", + " with tf.GradientTape() as t:\n", + " t.watch(x)\n", + " out = f(x, y)\n", + " return t.gradient(out, x) \n", + "\n", + "x = tf.convert_to_tensor(2.0)\n", + "\n", + "assert grad(x, 6).numpy() == 12.0\n", + "assert grad(x, 5).numpy() == 12.0\n", + "assert grad(x, 4).numpy() == 4.0\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "DK05KXrAAld3" + }, + "source": [ + "### 고차원(Higher-order) 그래디언트\n", + "\n", + "`GradientTape` 컨텍스트 매니저안에 있는 연산자들은 자동미분을 이해 기록됩니다. 만약 그래디언트가 컨텍스트 안에서 계산되어지면 그래디언트 계산 또한 기록되어집니다. 그 결과 똑같은 API가 고차원 그래디언트에서 잘 작동합니다. 예를 들면:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "cPQgthZ7ugRJ" + }, + "outputs": [], + "source": [ + "x = tf.Variable(1.0) # 1.0으로 초기화된 텐서플로우 변수 생성\n", + "\n", + "with tf.GradientTape() as t:\n", + " with tf.GradientTape() as t2:\n", + " y = x * x * x\n", + " # t 컨텍스트 매니저 안의 그래디언트 계산\n", + " # 이것은 또한 그래디언트 계산이 미분가능하다는것을 의미합니다. \n", + " dy_dx = t2.gradient(y, x)\n", + "d2y_dx2 = t.gradient(dy_dx, x)\n", + "\n", + "assert dy_dx.numpy() == 3.0\n", + "assert d2y_dx2.numpy() == 6.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "4U1KKzUpNl58" + }, + "source": [ + "## 다음 단계\n", + "\n", + "이번 튜토리얼에서는 텐서플로우에서 그래디언트 계산법을 배웠습니다. 이를 통해 우리는 신경망을 구축하고 훈련시키는 데 필요한 기본 요소를 충분히 확보 할 수 있습니다." + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "automatic_differentiation.ipynb", + "private_outputs": true, + "provenance": [], + "toc_visible": true, + "version": "0.3.2" + }, + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From fd3887924b9fb3b46952cfca86ab3fd5016ff292 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Sat, 23 Mar 2019 17:44:47 +0900 Subject: [PATCH 02/19] Start translation of other files 1. automatic_differentiation 2. custom_layers 3. custom_training 4. custom_training_walkthrough 5. eager_basisc 6. index.md --- .../eager/automatic_differentiation.ipynb | 2 +- site/ko/tutorials/eager/custom_layers.ipynb | 371 ++++++ site/ko/tutorials/eager/custom_training.ipynb | 466 +++++++ .../eager/custom_training_walkthrough.ipynb | 1106 +++++++++++++++++ site/ko/tutorials/eager/eager_basics.ipynb | 467 +++++++ site/ko/tutorials/eager/index.md | 13 + 6 files changed, 2424 insertions(+), 1 deletion(-) create mode 100644 site/ko/tutorials/eager/custom_layers.ipynb create mode 100644 site/ko/tutorials/eager/custom_training.ipynb create mode 100644 site/ko/tutorials/eager/custom_training_walkthrough.ipynb create mode 100644 site/ko/tutorials/eager/eager_basics.ipynb create mode 100644 site/ko/tutorials/eager/index.md diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index ad6746c6de8..e835160ebd7 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -251,7 +251,7 @@ "source": [ "### 고차원(Higher-order) 그래디언트\n", "\n", - "`GradientTape` 컨텍스트 매니저안에 있는 연산자들은 자동미분을 이해 기록됩니다. 만약 그래디언트가 컨텍스트 안에서 계산되어지면 그래디언트 계산 또한 기록되어집니다. 그 결과 똑같은 API가 고차원 그래디언트에서 잘 작동합니다. 예를 들면:" + "`GradientTape` 컨텍스트 매니저안에 있는 연산자들은 자동미분을 위해 기록됩니다. 만약 그래디언트가 컨텍스트 안에서 계산되면 그래디언트 계산 또한 기록되어집니다. 그 결과 똑같은 API가 고차원 그래디언트에서도 잘 작동합니다. 예를 들면:" ] }, { diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb new file mode 100644 index 00000000000..cb1a6022b24 --- /dev/null +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -0,0 +1,371 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "tDnwEv8FtJm7" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "form", + "colab": {}, + "colab_type": "code", + "id": "JlknJBWQtKkI" + }, + "outputs": [], + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "60RdWsg1tETW" + }, + "source": [ + "# Custom layers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "BcJg7Enms86w" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " View on TensorFlow.org\n", + " \n", + " Run in Google Colab\n", + " \n", + " View source on GitHub\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "UEu3q4jmpKVT" + }, + "source": [ + "We recommend using `tf.keras` as a high-level API for building neural networks. That said, most TensorFlow APIs are usable with eager execution.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "pwX7Fii1rwsJ" + }, + "outputs": [], + "source": [ + "import tensorflow as tf\n", + "\n", + "tf.enable_eager_execution()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "zSFfVVjkrrsI" + }, + "source": [ + "## Layers: common sets of useful operations\n", + "\n", + "Most of the time when writing code for machine learning models you want to operate at a higher level of abstraction than individual operations and manipulation of individual variables.\n", + "\n", + "Many machine learning models are expressible as the composition and stacking of relatively simple layers, and TensorFlow provides both a set of many common layers as a well as easy ways for you to write your own application-specific layers either from scratch or as the composition of existing layers.\n", + "\n", + "TensorFlow includes the full [Keras](https://keras.io) API in the tf.keras package, and the Keras layers are very useful when building your own models.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "8PyXlPl-4TzQ" + }, + "outputs": [], + "source": [ + "# In the tf.keras.layers package, layers are objects. To construct a layer,\n", + "# simply construct the object. Most layers take as a first argument the number\n", + "# of output dimensions / channels.\n", + "layer = tf.keras.layers.Dense(100)\n", + "# The number of input dimensions is often unnecessary, as it can be inferred\n", + "# the first time the layer is used, but it can be provided if you want to \n", + "# specify it manually, which is useful in some complex models.\n", + "layer = tf.keras.layers.Dense(10, input_shape=(None, 5))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Fn69xxPO5Psr" + }, + "source": [ + "The full list of pre-existing layers can be seen in [the documentation](https://www.tensorflow.org/api_docs/python/tf/keras/layers). It includes Dense (a fully-connected layer),\n", + "Conv2D, LSTM, BatchNormalization, Dropout, and many others." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "E3XKNknP5Mhb" + }, + "outputs": [], + "source": [ + "# To use a layer, simply call it.\n", + "layer(tf.zeros([10, 5]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "Wt_Nsv-L5t2s" + }, + "outputs": [], + "source": [ + "# Layers have many useful methods. For example, you can inspect all variables\n", + "# in a layer using `layer.variables` and trainable variables using \n", + "# `layer.trainable_variables`. In this case a fully-connected layer\n", + "# will have variables for weights and biases.\n", + "layer.variables" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "6ilvKjz8_4MQ" + }, + "outputs": [], + "source": [ + "# The variables are also accessible through nice accessors\n", + "layer.kernel, layer.bias" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "O0kDbE54-5VS" + }, + "source": [ + "## Implementing custom layers\n", + "The best way to implement your own layer is extending the tf.keras.Layer class and implementing:\n", + " * `__init__` , where you can do all input-independent initialization\n", + " * `build`, where you know the shapes of the input tensors and can do the rest of the initialization\n", + " * `call`, where you do the forward computation\n", + "\n", + "Note that you don't have to wait until `build` is called to create your variables, you can also create them in `__init__`. However, the advantage of creating them in `build` is that it enables late variable creation based on the shape of the inputs the layer will operate on. On the other hand, creating variables in `__init__` would mean that shapes required to create the variables will need to be explicitly specified." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "5Byl3n1k5kIy" + }, + "outputs": [], + "source": [ + "class MyDenseLayer(tf.keras.layers.Layer):\n", + " def __init__(self, num_outputs):\n", + " super(MyDenseLayer, self).__init__()\n", + " self.num_outputs = num_outputs\n", + " \n", + " def build(self, input_shape):\n", + " self.kernel = self.add_variable(\"kernel\", \n", + " shape=[int(input_shape[-1]), \n", + " self.num_outputs])\n", + " \n", + " def call(self, input):\n", + " return tf.matmul(input, self.kernel)\n", + " \n", + "layer = MyDenseLayer(10)\n", + "print(layer(tf.zeros([10, 5])))\n", + "print(layer.trainable_variables)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "tk8E2vY0-z4Z" + }, + "source": [ + "Note that you don't have to wait until `build` is called to create your variables, you can also create them in `__init__`.\n", + "\n", + "Overall code is easier to read and maintain if it uses standard layers whenever possible, as other readers will be familiar with the behavior of standard layers. If you want to use a layer which is not present in tf.keras.layers or tf.contrib.layers, consider filing a [github issue](http://github.com/tensorflow/tensorflow/issues/new) or, even better, sending us a pull request!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Qhg4KlbKrs3G" + }, + "source": [ + "## Models: composing layers\n", + "\n", + "Many interesting layer-like things in machine learning models are implemented by composing existing layers. For example, each residual block in a resnet is a composition of convolutions, batch normalizations, and a shortcut.\n", + "\n", + "The main class used when creating a layer-like thing which contains other layers is tf.keras.Model. Implementing one is done by inheriting from tf.keras.Model." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "N30DTXiRASlb" + }, + "outputs": [], + "source": [ + "class ResnetIdentityBlock(tf.keras.Model):\n", + " def __init__(self, kernel_size, filters):\n", + " super(ResnetIdentityBlock, self).__init__(name='')\n", + " filters1, filters2, filters3 = filters\n", + "\n", + " self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1))\n", + " self.bn2a = tf.keras.layers.BatchNormalization()\n", + "\n", + " self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same')\n", + " self.bn2b = tf.keras.layers.BatchNormalization()\n", + "\n", + " self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1))\n", + " self.bn2c = tf.keras.layers.BatchNormalization()\n", + "\n", + " def call(self, input_tensor, training=False):\n", + " x = self.conv2a(input_tensor)\n", + " x = self.bn2a(x, training=training)\n", + " x = tf.nn.relu(x)\n", + "\n", + " x = self.conv2b(x)\n", + " x = self.bn2b(x, training=training)\n", + " x = tf.nn.relu(x)\n", + "\n", + " x = self.conv2c(x)\n", + " x = self.bn2c(x, training=training)\n", + "\n", + " x += input_tensor\n", + " return tf.nn.relu(x)\n", + "\n", + " \n", + "block = ResnetIdentityBlock(1, [1, 2, 3])\n", + "print(block(tf.zeros([1, 2, 3, 3])))\n", + "print([x.name for x in block.trainable_variables])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "wYfucVw65PMj" + }, + "source": [ + "Much of the time, however, models which compose many layers simply call one layer after the other. This can be done in very little code using tf.keras.Sequential" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "L9frk7Ur4uvJ" + }, + "outputs": [], + "source": [ + " my_seq = tf.keras.Sequential([tf.keras.layers.Conv2D(1, (1, 1)),\n", + " tf.keras.layers.BatchNormalization(),\n", + " tf.keras.layers.Conv2D(2, 1, \n", + " padding='same'),\n", + " tf.keras.layers.BatchNormalization(),\n", + " tf.keras.layers.Conv2D(3, (1, 1)),\n", + " tf.keras.layers.BatchNormalization()])\n", + "my_seq(tf.zeros([1, 2, 3, 3]))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "c5YwYcnuK-wc" + }, + "source": [ + "# Next steps\n", + "\n", + "Now you can go back to the previous notebook and adapt the linear regression example to use layers and models to be better structured." + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "custom_layers.ipynb", + "private_outputs": true, + "provenance": [], + "toc_visible": true, + "version": "0.3.2" + }, + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/site/ko/tutorials/eager/custom_training.ipynb b/site/ko/tutorials/eager/custom_training.ipynb new file mode 100644 index 00000000000..56c0ab00fa9 --- /dev/null +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -0,0 +1,466 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "5rmpybwysXGV" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "form", + "colab": {}, + "colab_type": "code", + "id": "m8y3rGtQsYP2" + }, + "outputs": [], + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "hrXv0rU9sIma" + }, + "source": [ + "# 사용자 지정 학습: 기초" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "7S0BwJ_8sLu7" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " View on TensorFlow.org\n", + " \n", + " Run in Google Colab\n", + " \n", + " View source on GitHub\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "k2o3TTG4TFpt" + }, + "source": [ + "이전 튜토리얼에서 우리는 머신러닝을 위한 기초 빌딩 블록인 자동미분(automatic differentiation)을 위한 텐서플로우 API들을 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 초기 타입의 텐서플로우를 사용하여 간단한 머신러닝을 구축해보겠습니다. \n", + "\n", + "텐서플로우는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망 API인 (`tf.keras`)를 포함하고 있습니다. 신경망에 관련하여 일을 하고 있는 사람들에게는 이러한 고수준의 API들을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3LXMVuV0VhDr" + }, + "source": [ + "## 설정" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "PJ64L90aVir3" + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\82108\\Anaconda3\\lib\\site-packages\\h5py\\__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n", + " from ._conv import register_converters as _register_converters\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "\n", + "tf.enable_eager_execution()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "eMAWbDJFVmMk" + }, + "source": [ + "## 변수\n", + "\n", + "텐서플로우 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝은 상태가 변경될 필요가 있습니다(stateful). 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로, 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 계산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어에 의존한 선택이 가능합니다. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "VkJwtLS_Jbn8" + }, + "outputs": [], + "source": [ + "# 파이썬 state 사용\n", + "x = tf.zeros([10, 10])\n", + "x += 2 # 이것은 x = x + 2 같으며, 초기값 x를 변경하지 않습니다.\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "wfneTXy7JcUz" + }, + "source": [ + "그러나 텐서플로우는 상태가 변경 가능한 연산자들이 내장되어 있으며, 이 연산자들은 상태를 표현하기 위한 저수준 파이썬 표현보다 사용하기가 더 좋습니다. 예를 들어, 모델에서 가중치를 나타내기 위해서 텐서플로우 변수를 사용하는것이 편하고 효율적입니다. \n", + "\n", + "텐서플로우 변수는 값을 저장하고 텐서플로우 계산에 사용될 때 묵시적으로 저장된 값을 읽어오는 객체입니다. `tf.assign_sub`, `tf.scatter_update` 등은 텐서플로우 변수에 저장되있는 값을 조작하는 연산자들입니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "itxmrMil6DQi" + }, + "outputs": [], + "source": [ + "v = tf.Variable(1.0)\n", + "assert v.numpy() == 1.0\n", + "\n", + "# 값 재배열\n", + "v.assign(3.0)\n", + "assert v.numpy() == 3.0\n", + "\n", + "# 텐서플로우 연산자 내에서 `v` 사용 \n", + "v.assign(tf.square(v))\n", + "assert v.numpy() == 9.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "-paSaeq1JzwC" + }, + "source": [ + "변수들을 사용한 계산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 초기값으로부터 드물게 업데이트됩니다. 이는 계산과 메모리에 있어 더욱 효율적입니다. \n", + "\n", + "또한 변수를 사용하는 것은 코드를 읽는 과정에서 변경 가능한 상태(state mutable)의 조각을 빠르게 인식하는 방법입니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "BMiFcDzE7Qu3" + }, + "source": [ + "## 예: 선형모델 피팅\n", + "\n", + "몇가지 개념들을 설명해보겠습니다. 우리는 지금까지 간단한 모델을 구축하고 학습시키기 위해 ---`Tensor`, `GradientTape`, `Variable` --- 등을 사용하였습니다. 이것은 전형적으로 다음의 과정을 포함합니다.\n", + "\n", + "1. 모델 정의\n", + "2. 손실함수 정의\n", + "3. 훈련 데이터 가져오기\n", + "4. 훈련 데이터를 통한 실행, 데이터에 최적화하기 위한 \"옵티마이저(optimizer)\" 사용한 변수 조정\n", + "\n", + "이번 튜토리얼에서는 선형모델의 간단한 예제를 살펴보겠습니다. `f(x) = x * W + b`, `W` and `b` 두 변수를 가지고 있는 선형모델입니다. 더욱이 잘 학습된 모델이 `W = 3.0` and `b = 2.0`의 값을 갖도록 데이터를 합성할 것입니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "gFzH64Jn9PIm" + }, + "source": [ + "### 모델 정의\n", + "\n", + "변수들과 계산을 요약하기 위한 간단한 클래스를 정의해봅시다." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "_WRu7Pze7wk8" + }, + "outputs": [], + "source": [ + "class Model(object):\n", + " def __init__(self):\n", + " # 변수 초기화 (5.0, 0.0)\n", + " # 실제로는 임의의 값으로 초기화 되어야합니다.\n", + " self.W = tf.Variable(5.0)\n", + " self.b = tf.Variable(0.0)\n", + " \n", + " def __call__(self, x):\n", + " return self.W * x + self.b\n", + " \n", + "model = Model()\n", + "\n", + "assert model(3.0).numpy() == 15.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "xa6j_yXa-j79" + }, + "source": [ + "### 손실 함수 정의\n", + "\n", + "손실 함수는 주어진 입력에 대한 모델의 출력이 원하는 출력과 얼마나 잘 일치하는지 측정합니다. L2 규제항(regularization)을 적용한 손실 함수를 사용하겠습니다." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "Y0ysUFGY924U" + }, + "outputs": [], + "source": [ + "def loss(predicted_y, desired_y):\n", + " return tf.reduce_mean(tf.square(predicted_y - desired_y))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "qutT_fkl_CBc" + }, + "source": [ + "### 훈련 데이터 얻기\n", + "\n", + "약간의 잡음과 훈련 데이터를 합칩니다." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "gxPTb-kt_N5m" + }, + "outputs": [], + "source": [ + "TRUE_W = 3.0\n", + "TRUE_b = 2.0\n", + "NUM_EXAMPLES = 1000\n", + "\n", + "inputs = tf.random_normal(shape=[NUM_EXAMPLES])\n", + "noise = tf.random_normal(shape=[NUM_EXAMPLES])\n", + "outputs = inputs * TRUE_W + TRUE_b + noise" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "-50nq-wPBsAW" + }, + "source": [ + "모델을 훈련시키기 전에, 모델의 현재 상태를 시각화합시다. 모델의 예측을 빨간색으로, 훈련데이터를 파란색으로 구성합니다." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "_eb83LtrB4nt" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Current loss: \n", + "9.401943\n" + ] + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "plt.scatter(inputs, outputs, c='b')\n", + "plt.scatter(inputs, model(inputs), c='r')\n", + "plt.show()\n", + "\n", + "print('Current loss: '),\n", + "print(loss(model(inputs), outputs).numpy())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "sSDP-yeq_4jE" + }, + "source": [ + "### 훈련 루프 정의\n", + "\n", + "현재 우리는 네트워크와 훈련 데이터를 가지고 있습니다. 모델의 변수(`W` 와 `b`)를 업데이트하기 위해 훈련 데이터를 사용하여 훈련시킵니다. 그리고 [gradient descent](https://en.wikipedia.org/wiki/Gradient_descent)를 사용하여 손실을 감소시킵니다. 경사하강에는 여러가지 방법이 있으며, `tf.train.Optimizer` 에 구현되어있습니다. 이러한 구현을 사용하는것을 강력히 추천드립니다. 그러나 이번 튜토리얼에서는 기본적인 방법을 사용하겠습니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "MBIACgdnA55X" + }, + "outputs": [], + "source": [ + "def train(model, inputs, outputs, learning_rate):\n", + " with tf.GradientTape() as t:\n", + " current_loss = loss(model(inputs), outputs)\n", + " dW, db = t.gradient(current_loss, [model.W, model.b])\n", + " model.W.assign_sub(learning_rate * dW)\n", + " model.b.assign_sub(learning_rate * db)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "RwWPaJryD2aN" + }, + "source": [ + "마지막으로, 훈련 데이터를 반복적으로 실행하고, `W` 와 `b`의 변화과정을 확인합니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "XdfkR223D9dW" + }, + "outputs": [], + "source": [ + "model = Model()\n", + "\n", + "# Collect the history of W-values and b-values to plot later\n", + "Ws, bs = [], []\n", + "epochs = range(10)\n", + "for epoch in epochs:\n", + " Ws.append(model.W.numpy())\n", + " bs.append(model.b.numpy())\n", + " current_loss = loss(model(inputs), outputs)\n", + "\n", + " train(model, inputs, outputs, learning_rate=0.1)\n", + " print('Epoch %2d: W=%1.2f b=%1.2f, loss=%2.5f' %\n", + " (epoch, Ws[-1], bs[-1], current_loss))\n", + "\n", + "# Let's plot it all\n", + "plt.plot(epochs, Ws, 'r',\n", + " epochs, bs, 'b')\n", + "plt.plot([TRUE_W] * len(epochs), 'r--',\n", + " [TRUE_b] * len(epochs), 'b--')\n", + "plt.legend(['W', 'b', 'true W', 'true_b'])\n", + "plt.show()\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "vPnIVuaSJwWz" + }, + "source": [ + "## 다음 단계\n", + "\n", + "이번 튜토리얼에서는 `Variable`를 다루었으며, 지금까지 논의된 초기 타입의 텐서플로우를 사용하여 간단한 선형모델을 구축하고 훈련시켰습니다.\n", + "\n", + "이론적으로, 이것은 머신러닝 연구에 텐서플로우를 사용하는데 필요한 대부분입니다. 실제로, 신경망에 있어 `tf.keras`와 고수준 API들은 고수준 빌딩 블록(\"layer\"로 불리는)을 제공하고, 저장 및 복원을 위한 유틸리티, 손실함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "Custom training: basics", + "private_outputs": true, + "provenance": [], + "toc_visible": true, + "version": "0.3.2" + }, + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb new file mode 100644 index 00000000000..055fab9b058 --- /dev/null +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -0,0 +1,1106 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rwxGnsA92emp" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "form", + "colab": {}, + "colab_type": "code", + "id": "CPII1rGR2rF9" + }, + "outputs": [], + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "JtEZ1pCPn--z" + }, + "source": [ + "# 사용자 지정 학습: walkthrough" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "GV1F7tVTN3Dn" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " View on TensorFlow.org\n", + " \n", + " Run in Google Colab\n", + " \n", + " View source on GitHub\n", + "
" + ] + }, + { + "cell_type": "raw", + "metadata": { + "colab_type": "text", + "id": "LDrzLFXE8T1l" + }, + "source": [ + "이번 튜토리얼은 붓꽃의 품종을 분류하기 위한 머신러닝 모델을 구축할 것입니다. 다음을 위해 즉시실행[eager execution](https://www.tensorflow.org/guide/eager)을 사용합니다.\n", + "1. 모델 구축\n", + "2. 모델 훈련\n", + "3. 예측을 위한 모델 사용\n", + "\n", + "## 텐서플로우 프로그래밍\n", + "\n", + "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로우의 개념들을 사용합니다.\n", + "\n", + "* 즉시실행[eager execution](https://www.tensorflow.org/guide/eager) 개발환경,\n", + "* [Datasets API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 불러오기,\n", + "* [Keras API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 레이어(layer) 구축 .\n", + "\n", + "이번 튜토리얼은 다른 텐서플로우 프로그램과 유사하게 구성되어있습니다.\n", + "\n", + "1. 데이터 불러오기 및 분석.\n", + "2. 모델 타입 선정.\n", + "3. 모델 학습.\n", + "4. 모델 효과 검증.\n", + "5. 예측을 위한 학습된 모델 사용." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "yNr7H-AIoLOR" + }, + "source": [ + "## 프로그램 설정" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "1J3AuPBT9gyR" + }, + "source": [ + "### 임포트 및 즉시실행 구성\n", + "\n", + "텐서플로우를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시실행을 활성화할 것입니다. 즉시실행은 텐서플로우가 나중에 실행되는 [computational graph](https://www.tensorflow.org/guide/graphs)를 만드는데신, 연산자를 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", + "\n", + "즉시실행이 활성화 될때, 동일한 프로그램내에서는 비활성화를 할 수 없습니다. 더 많은 세부사항은 [eager execution guide](https://www.tensorflow.org/guide/eager)을 참조하세요." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "g4Wzg69bnwK2" + }, + "outputs": [], + "source": [ + "from __future__ import absolute_import, division, print_function\n", + "\n", + "import os\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import tensorflow as tf\n", + "\n", + "tf.enable_eager_execution()\n", + "\n", + "print(\"TensorFlow version: {}\".format(tf.__version__))\n", + "print(\"Eager execution: {}\".format(tf.executing_eagerly()))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Zx7wc0LuuxaJ" + }, + "source": [ + "## 붓꽃 분류 문제\n", + "\n", + "당신이 식물학자라고 상상하고, 주어진 붓꽃을 자동적으로 분류하는 방법을 찾고있다고 가정합시다. 머신러닝은 통계적으로 꽃을 분류할 수 있는 다양한 알고리즘을 제공합니다. 예를 들어, 정교한 머신러닝 프로그램은 사진을 통해 꽃을 분류할 수 있습니다. 우리의 목적은 좀 더 겸손하게 측정된 [꽃받침](https://en.wikipedia.org/wiki/Sepal)과 [꽃잎](https://en.wikipedia.org/wiki/Petal)의 길이와 폭을 토대로 붓꽃을 분류하는것입니다.\n", + "\n", + "이 붓꽃은 약 300종 입니다. 하지만 이번 튜토리얼에서는 오직 3가지 품종을 기준으로 분류할 것입니다. \n", + "\n", + "* Iris setosa\n", + "* Iris virginica\n", + "* Iris versicolor\n", + "\n", + "\n", + " \n", + " \n", + "
\n", + " \"Petal\n", + "
\n", + " Figure 1. Iris setosa (by Radomil, CC BY-SA 3.0), Iris versicolor, (by Dlanglois, CC BY-SA 3.0), and Iris virginica (by Frank Mayfield, CC BY-SA 2.0).
 \n", + "
\n", + "\n", + "다행이도 다른사람들이 먼저 꽃받침과 꽃임이 측정된 [120개의 붓꽃 데이터](https://en.wikipedia.org/wiki/Iris_flower_data_set)를 만들어 놓았습니다. 이것은 머신러닝 분류문제에 있어 초보자에게 유명한 고전 데이터셋입니다. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3Px6KAg0Jowz" + }, + "source": [ + "## 훈련 데이터 불러오기 및 분석\n", + "\n", + "데이터를 불러오고 파이썬 프로그램이 사용할 수 있는 구조로 전환합니다.\n", + "\n", + "### 데이터셋 다운로드\n", + "\n", + "[tf.keras.utils.get_file](https://www.tensorflow.org/api_docs/python/tf/keras/utils/get_file)함수를 사용하여 데이터셋을 다운로드합니다. 이 함수는 다운로드된 파일의 경로를 반환합니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "J6c7uEU9rjRM" + }, + "outputs": [], + "source": [ + "train_dataset_url = \"https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv\"\n", + "\n", + "train_dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(train_dataset_url),\n", + " origin=train_dataset_url)\n", + "\n", + "print(\"Local copy of the dataset file: {}\".format(train_dataset_fp))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "qnX1-aLors4S" + }, + "source": [ + "### 데이터 관찰\n", + "\n", + "이 데이터셋(`iris_training.csv`)은 ','로 구분된 CSV 파일입니다. `head -n5` 명령을 사용하여 처음 5개 항목을 확인합니다. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "FQvb_JYdrpPm" + }, + "outputs": [], + "source": [ + "!head -n5 {train_dataset_fp}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "kQhzD6P-uBoq" + }, + "source": [ + "From this view of the dataset, notice the following:\n", + "\n", + "1. 첫번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", + " * 총 120개의 예가 있다. 각 예들은 4가지의 특성(feature)을 가지고 3가지 가능한 레이블(label)을 가지고 있습니다.\n", + "2. 후속행은 데이터 레코드입니다. one *[example](https://developers.google.com/machine-learning/glossary/#example)* per line, where:\n", + " * The first four fields are *[features](https://developers.google.com/machine-learning/glossary/#feature)*: these are characteristics of an example. Here, the fields hold float numbers representing flower measurements.\n", + " * The last column is the *[label](https://developers.google.com/machine-learning/glossary/#label)*: this is the value we want to predict. For this dataset, it's an integer value of 0, 1, or 2 that corresponds to a flower name.\n", + "\n", + "Let's write that out in code:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "9Edhevw7exl6" + }, + "outputs": [], + "source": [ + "# column order in CSV file\n", + "column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']\n", + "\n", + "feature_names = column_names[:-1]\n", + "label_name = column_names[-1]\n", + "\n", + "print(\"Features: {}\".format(feature_names))\n", + "print(\"Label: {}\".format(label_name))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "CCtwLoJhhDNc" + }, + "source": [ + "각각의 레이블은 \"setosa\"와 같은 문자형 이름과 연관되어있습니다. 하지만 머신러닝은 전형적이로 숫자형값에 의존합니다. 레이블을 다음과 같이 맵핑(mapping) 합니다. \n", + "\n", + "* `0`: Iris setosa\n", + "* `1`: Iris versicolor\n", + "* `2`: Iris virginica\n", + "\n", + "특성과 레이블에 관한 더 많은 정보를 위해서 다음을 참조하세요.[ML Terminology section of the Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/framing/ml-terminology)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "sVNlJlUOhkoX" + }, + "outputs": [], + "source": [ + "class_names = ['Iris setosa', 'Iris versicolor', 'Iris virginica']" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "dqPkQExM2Pwt" + }, + "source": [ + "### `tf.data.Dataset` 생성\n", + "\n", + "TensorFlow's [Dataset API](https://www.tensorflow.org/guide/datasets) handles many common cases for loading data into a model. This is a high-level API for reading data and transforming it into a form used for training. See the [Datasets Quick Start guide](https://www.tensorflow.org/get_started/datasets_quickstart) for more information.\n", + "\n", + "\n", + "Since the dataset is a CSV-formatted text file, use the [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) function to parse the data into a suitable format. Since this function generates data for training models, the default behavior is to shuffle the data (`shuffle=True, shuffle_buffer_size=10000`), and repeat the dataset forever (`num_epochs=None`). We also set the [batch_size](https://developers.google.com/machine-learning/glossary/#batch_size) parameter." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "WsxHnz1ebJ2S" + }, + "outputs": [], + "source": [ + "batch_size = 32\n", + "\n", + "train_dataset = tf.contrib.data.make_csv_dataset(\n", + " train_dataset_fp,\n", + " batch_size, \n", + " column_names=column_names,\n", + " label_name=label_name,\n", + " num_epochs=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "gB_RSn62c-3G" + }, + "source": [ + "The `make_csv_dataset` function returns a `tf.data.Dataset` of `(features, label)` pairs, where `features` is a dictionary: `{'feature_name': value}`\n", + "\n", + "With eager execution enabled, these `Dataset` objects are iterable. Let's look at a batch of features:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "iDuG94H-C122" + }, + "outputs": [], + "source": [ + "features, labels = next(iter(train_dataset))\n", + "\n", + "features" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "E63mArnQaAGz" + }, + "source": [ + "Notice that like-features are grouped together, or *batched*. Each example row's fields are appended to the corresponding feature array. Change the `batch_size` to set the number of examples stored in these feature arrays.\n", + "\n", + "You can start to see some clusters by plotting a few features from the batch:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "me5Wn-9FcyyO" + }, + "outputs": [], + "source": [ + "plt.scatter(features['petal_length'].numpy(),\n", + " features['sepal_length'].numpy(),\n", + " c=labels.numpy(),\n", + " cmap='viridis')\n", + "\n", + "plt.xlabel(\"Petal length\")\n", + "plt.ylabel(\"Sepal length\");" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "YlxpSyHlhT6M" + }, + "source": [ + "To simplify the model building step, create a function to repackage the features dictionary into a single array with shape: `(batch_size, num_features)`.\n", + "\n", + "This function uses the [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) method which takes values from a list of tensors and creates a combined tensor at the specified dimension." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "jm932WINcaGU" + }, + "outputs": [], + "source": [ + "def pack_features_vector(features, labels):\n", + " \"\"\"Pack the features into a single array.\"\"\"\n", + " features = tf.stack(list(features.values()), axis=1)\n", + " return features, labels" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "V1Vuph_eDl8x" + }, + "source": [ + "Then use the [tf.data.Dataset.map](https://www.tensorflow.org/api_docs/python/tf/data/dataset/map) method to pack the `features` of each `(features,label)` pair into the training dataset:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "ZbDkzGZIkpXf" + }, + "outputs": [], + "source": [ + "train_dataset = train_dataset.map(pack_features_vector)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "NLy0Q1xCldVO" + }, + "source": [ + "The features element of the `Dataset` are now arrays with shape `(batch_size, num_features)`. Let's look at the first few examples:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "kex9ibEek6Tr" + }, + "outputs": [], + "source": [ + "features, labels = next(iter(train_dataset))\n", + "\n", + "print(features[:5])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "LsaVrtNM3Tx5" + }, + "source": [ + "## Select the type of model\n", + "\n", + "### Why model?\n", + "\n", + "A *[model](https://developers.google.com/machine-learning/crash-course/glossary#model)* is a relationship between features and the label. For the Iris classification problem, the model defines the relationship between the sepal and petal measurements and the predicted Iris species. Some simple models can be described with a few lines of algebra, but complex machine learning models have a large number of parameters that are difficult to summarize.\n", + "\n", + "Could you determine the relationship between the four features and the Iris species *without* using machine learning? That is, could you use traditional programming techniques (for example, a lot of conditional statements) to create a model? Perhaps—if you analyzed the dataset long enough to determine the relationships between petal and sepal measurements to a particular species. And this becomes difficult—maybe impossible—on more complicated datasets. A good machine learning approach *determines the model for you*. If you feed enough representative examples into the right machine learning model type, the program will figure out the relationships for you.\n", + "\n", + "### Select the model\n", + "\n", + "We need to select the kind of model to train. There are many types of models and picking a good one takes experience. This tutorial uses a neural network to solve the Iris classification problem. *[Neural networks](https://developers.google.com/machine-learning/glossary/#neural_network)* can find complex relationships between features and the label. It is a highly-structured graph, organized into one or more *[hidden layers](https://developers.google.com/machine-learning/glossary/#hidden_layer)*. Each hidden layer consists of one or more *[neurons](https://developers.google.com/machine-learning/glossary/#neuron)*. There are several categories of neural networks and this program uses a dense, or *[fully-connected neural network](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*: the neurons in one layer receive input connections from *every* neuron in the previous layer. For example, Figure 2 illustrates a dense neural network consisting of an input layer, two hidden layers, and an output layer:\n", + "\n", + "\n", + " \n", + " \n", + "
\n", + " \n", + "
\n", + " Figure 2. A neural network with features, hidden layers, and predictions.
 \n", + "
\n", + "\n", + "When the model from Figure 2 is trained and fed an unlabeled example, it yields three predictions: the likelihood that this flower is the given Iris species. This prediction is called *[inference](https://developers.google.com/machine-learning/crash-course/glossary#inference)*. For this example, the sum of the output predictions is 1.0. In Figure 2, this prediction breaks down as: `0.02` for *Iris setosa*, `0.95` for *Iris versicolor*, and `0.03` for *Iris virginica*. This means that the model predicts—with 95% probability—that an unlabeled example flower is an *Iris versicolor*." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "W23DIMVPQEBt" + }, + "source": [ + "### Create a model using Keras\n", + "\n", + "The TensorFlow [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API is the preferred way to create models and layers. This makes it easy to build models and experiment while Keras handles the complexity of connecting everything together.\n", + "\n", + "The [tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential) model is a linear stack of layers. Its constructor takes a list of layer instances, in this case, two [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense) layers with 10 nodes each, and an output layer with 3 nodes representing our label predictions. The first layer's `input_shape` parameter corresponds to the number of features from the dataset, and is required." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "2fZ6oL2ig3ZK" + }, + "outputs": [], + "source": [ + "model = tf.keras.Sequential([\n", + " tf.keras.layers.Dense(10, activation=tf.nn.relu, input_shape=(4,)), # input shape required\n", + " tf.keras.layers.Dense(10, activation=tf.nn.relu),\n", + " tf.keras.layers.Dense(3)\n", + "])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "FHcbEzMpxbHL" + }, + "source": [ + "The *[activation function](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)* determines the output shape of each node in the layer. These non-linearities are important—without them the model would be equivalent to a single layer. There are many [available activations](https://www.tensorflow.org/api_docs/python/tf/keras/activations), but [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU) is common for hidden layers.\n", + "\n", + "The ideal number of hidden layers and neurons depends on the problem and the dataset. Like many aspects of machine learning, picking the best shape of the neural network requires a mixture of knowledge and experimentation. As a rule of thumb, increasing the number of hidden layers and neurons typically creates a more powerful model, which requires more data to train effectively." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "2wFKnhWCpDSS" + }, + "source": [ + "### Using the model\n", + "\n", + "Let's have a quick look at what this model does to a batch of features:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "xe6SQ5NrpB-I" + }, + "outputs": [], + "source": [ + "predictions = model(features)\n", + "predictions[:5]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "wxyXOhwVr5S3" + }, + "source": [ + "Here, each example returns a [logit](https://developers.google.com/machine-learning/crash-course/glossary#logits) for each class. \n", + "\n", + "To convert these logits to a probability for each class, use the [softmax](https://developers.google.com/machine-learning/crash-course/glossary#softmax) function:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "_tRwHZmTNTX2" + }, + "outputs": [], + "source": [ + "tf.nn.softmax(predictions[:5])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "uRZmchElo481" + }, + "source": [ + "Taking the `tf.argmax` across classes gives us the predicted class index. But, the model hasn't been trained yet, so these aren't good predictions." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "-Jzm_GoErz8B" + }, + "outputs": [], + "source": [ + "print(\"Prediction: {}\".format(tf.argmax(predictions, axis=1)))\n", + "print(\" Labels: {}\".format(labels))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Vzq2E5J2QMtw" + }, + "source": [ + "## Train the model\n", + "\n", + "*[Training](https://developers.google.com/machine-learning/crash-course/glossary#training)* is the stage of machine learning when the model is gradually optimized, or the model *learns* the dataset. The goal is to learn enough about the structure of the training dataset to make predictions about unseen data. If you learn *too much* about the training dataset, then the predictions only work for the data it has seen and will not be generalizable. This problem is called *[overfitting](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)*—it's like memorizing the answers instead of understanding how to solve a problem.\n", + "\n", + "The Iris classification problem is an example of *[supervised machine learning](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*: the model is trained from examples that contain labels. In *[unsupervised machine learning](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*, the examples don't contain labels. Instead, the model typically finds patterns among the features." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "RaKp8aEjKX6B" + }, + "source": [ + "### Define the loss and gradient function\n", + "\n", + "Both training and evaluation stages need to calculate the model's *[loss](https://developers.google.com/machine-learning/crash-course/glossary#loss)*. This measures how off a model's predictions are from the desired label, in other words, how bad the model is performing. We want to minimize, or optimize, this value.\n", + "\n", + "Our model will calculate its loss using the [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) function which takes the model's class probability predictions and the desired label, and returns the average loss across the examples." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "tMAT4DcMPwI-" + }, + "outputs": [], + "source": [ + "def loss(model, x, y):\n", + " y_ = model(x)\n", + " return tf.losses.sparse_softmax_cross_entropy(labels=y, logits=y_)\n", + "\n", + "\n", + "l = loss(model, features, labels)\n", + "print(\"Loss test: {}\".format(l))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3IcPqA24QM6B" + }, + "source": [ + "Use the [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) context to calculate the *[gradients](https://developers.google.com/machine-learning/crash-course/glossary#gradient)* used to optimize our model. For more examples of this, see the [eager execution guide](https://www.tensorflow.org/guide/eager)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "x57HcKWhKkei" + }, + "outputs": [], + "source": [ + "def grad(model, inputs, targets):\n", + " with tf.GradientTape() as tape:\n", + " loss_value = loss(model, inputs, targets)\n", + " return loss_value, tape.gradient(loss_value, model.trainable_variables)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "lOxFimtlKruu" + }, + "source": [ + "### Create an optimizer\n", + "\n", + "An *[optimizer](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)* applies the computed gradients to the model's variables to minimize the `loss` function. You can think of the loss function as a curved surface (see Figure 3) and we want to find its lowest point by walking around. The gradients point in the direction of steepest ascent—so we'll travel the opposite way and move down the hill. By iteratively calculating the loss and gradient for each batch, we'll adjust the model during training. Gradually, the model will find the best combination of weights and bias to minimize loss. And the lower the loss, the better the model's predictions.\n", + "\n", + "\n", + " \n", + " \n", + "
\n", + " \"Optimization\n", + "
\n", + " Figure 3. Optimization algorithms visualized over time in 3D space.
(Source: Stanford class CS231n, MIT License, Image credit: Alec Radford)\n", + "
\n", + "\n", + "TensorFlow has many [optimization algorithms](https://www.tensorflow.org/api_guides/python/train) available for training. This model uses the [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer) that implements the *[stochastic gradient descent](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* (SGD) algorithm. The `learning_rate` sets the step size to take for each iteration down the hill. This is a *hyperparameter* that you'll commonly adjust to achieve better results." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "XkUd6UiZa_dF" + }, + "source": [ + "Let's setup the optimizer and the `global_step` counter:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "8xxi2NNGKwG_" + }, + "outputs": [], + "source": [ + "optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)\n", + "\n", + "global_step = tf.Variable(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "pJVRZ0hP52ZB" + }, + "source": [ + "We'll use this to calculate a single optimization step:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "rxRNTFVe56RG" + }, + "outputs": [], + "source": [ + "loss_value, grads = grad(model, features, labels)\n", + "\n", + "print(\"Step: {}, Initial Loss: {}\".format(global_step.numpy(),\n", + " loss_value.numpy()))\n", + "\n", + "optimizer.apply_gradients(zip(grads, model.trainable_variables), global_step)\n", + "\n", + "print(\"Step: {}, Loss: {}\".format(global_step.numpy(),\n", + " loss(model, features, labels).numpy()))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "7Y2VSELvwAvW" + }, + "source": [ + "### Training loop\n", + "\n", + "With all the pieces in place, the model is ready for training! A training loop feeds the dataset examples into the model to help it make better predictions. The following code block sets up these training steps:\n", + "\n", + "1. Iterate each *epoch*. An epoch is one pass through the dataset.\n", + "2. Within an epoch, iterate over each example in the training `Dataset` grabbing its *features* (`x`) and *label* (`y`).\n", + "3. Using the example's features, make a prediction and compare it with the label. Measure the inaccuracy of the prediction and use that to calculate the model's loss and gradients.\n", + "4. Use an `optimizer` to update the model's variables.\n", + "5. Keep track of some stats for visualization.\n", + "6. Repeat for each epoch.\n", + "\n", + "The `num_epochs` variable is the number of times to loop over the dataset collection. Counter-intuitively, training a model longer does not guarantee a better model. `num_epochs` is a *[hyperparameter](https://developers.google.com/machine-learning/glossary/#hyperparameter)* that you can tune. Choosing the right number usually requires both experience and experimentation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "AIgulGRUhpto" + }, + "outputs": [], + "source": [ + "## Note: Rerunning this cell uses the same model variables\n", + "\n", + "from tensorflow import contrib\n", + "tfe = contrib.eager\n", + "\n", + "# keep results for plotting\n", + "train_loss_results = []\n", + "train_accuracy_results = []\n", + "\n", + "num_epochs = 201\n", + "\n", + "for epoch in range(num_epochs):\n", + " epoch_loss_avg = tfe.metrics.Mean()\n", + " epoch_accuracy = tfe.metrics.Accuracy()\n", + "\n", + " # Training loop - using batches of 32\n", + " for x, y in train_dataset:\n", + " # Optimize the model\n", + " loss_value, grads = grad(model, x, y)\n", + " optimizer.apply_gradients(zip(grads, model.trainable_variables),\n", + " global_step)\n", + "\n", + " # Track progress\n", + " epoch_loss_avg(loss_value) # add current batch loss\n", + " # compare predicted label to actual label\n", + " epoch_accuracy(tf.argmax(model(x), axis=1, output_type=tf.int32), y)\n", + "\n", + " # end epoch\n", + " train_loss_results.append(epoch_loss_avg.result())\n", + " train_accuracy_results.append(epoch_accuracy.result())\n", + " \n", + " if epoch % 50 == 0:\n", + " print(\"Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}\".format(epoch,\n", + " epoch_loss_avg.result(),\n", + " epoch_accuracy.result()))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "2FQHVUnm_rjw" + }, + "source": [ + "### Visualize the loss function over time" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "j3wdbmtLVTyr" + }, + "source": [ + "While it's helpful to print out the model's training progress, it's often *more* helpful to see this progress. [TensorBoard](https://www.tensorflow.org/guide/summaries_and_tensorboard) is a nice visualization tool that is packaged with TensorFlow, but we can create basic charts using the `matplotlib` module.\n", + "\n", + "Interpreting these charts takes some experience, but you really want to see the *loss* go down and the *accuracy* go up." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "agjvNd2iUGFn" + }, + "outputs": [], + "source": [ + "fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))\n", + "fig.suptitle('Training Metrics')\n", + "\n", + "axes[0].set_ylabel(\"Loss\", fontsize=14)\n", + "axes[0].plot(train_loss_results)\n", + "\n", + "axes[1].set_ylabel(\"Accuracy\", fontsize=14)\n", + "axes[1].set_xlabel(\"Epoch\", fontsize=14)\n", + "axes[1].plot(train_accuracy_results);" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Zg8GoMZhLpGH" + }, + "source": [ + "## Evaluate the model's effectiveness\n", + "\n", + "Now that the model is trained, we can get some statistics on its performance.\n", + "\n", + "*Evaluating* means determining how effectively the model makes predictions. To determine the model's effectiveness at Iris classification, pass some sepal and petal measurements to the model and ask the model to predict what Iris species they represent. Then compare the model's prediction against the actual label. For example, a model that picked the correct species on half the input examples has an *[accuracy](https://developers.google.com/machine-learning/glossary/#accuracy)* of `0.5`. Figure 4 shows a slightly more effective model, getting 4 out of 5 predictions correct at 80% accuracy:\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Example featuresLabelModel prediction
5.93.04.31.511
6.93.15.42.122
5.13.31.70.500
6.0 3.4 4.5 1.6 12
5.52.54.01.311
\n", + " Figure 4. An Iris classifier that is 80% accurate.
 \n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "z-EvK7hGL0d8" + }, + "source": [ + "### Setup the test dataset\n", + "\n", + "Evaluating the model is similar to training the model. The biggest difference is the examples come from a separate *[test set](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* rather than the training set. To fairly assess a model's effectiveness, the examples used to evaluate a model must be different from the examples used to train the model.\n", + "\n", + "The setup for the test `Dataset` is similar to the setup for training `Dataset`. Download the CSV text file and parse that values, then give it a little shuffle:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "Ps3_9dJ3Lodk" + }, + "outputs": [], + "source": [ + "test_url = \"https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv\"\n", + "\n", + "test_fp = tf.keras.utils.get_file(fname=os.path.basename(test_url),\n", + " origin=test_url)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "SRMWCu30bnxH" + }, + "outputs": [], + "source": [ + "test_dataset = tf.contrib.data.make_csv_dataset(\n", + " test_fp,\n", + " batch_size, \n", + " column_names=column_names,\n", + " label_name='species',\n", + " num_epochs=1,\n", + " shuffle=False)\n", + "\n", + "test_dataset = test_dataset.map(pack_features_vector)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "HFuOKXJdMAdm" + }, + "source": [ + "### Evaluate the model on the test dataset\n", + "\n", + "Unlike the training stage, the model only evaluates a single [epoch](https://developers.google.com/machine-learning/glossary/#epoch) of the test data. In the following code cell, we iterate over each example in the test set and compare the model's prediction against the actual label. This is used to measure the model's accuracy across the entire test set." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "Tw03-MK1cYId" + }, + "outputs": [], + "source": [ + "test_accuracy = tfe.metrics.Accuracy()\n", + "\n", + "for (x, y) in test_dataset:\n", + " logits = model(x)\n", + " prediction = tf.argmax(logits, axis=1, output_type=tf.int32)\n", + " test_accuracy(prediction, y)\n", + "\n", + "print(\"Test set accuracy: {:.3%}\".format(test_accuracy.result()))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "HcKEZMtCOeK-" + }, + "source": [ + "We can see on the last batch, for example, the model is usually correct:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "uNwt2eMeOane" + }, + "outputs": [], + "source": [ + "tf.stack([y,prediction],axis=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "7Li2r1tYvW7S" + }, + "source": [ + "## Use the trained model to make predictions\n", + "\n", + "We've trained a model and \"proven\" that it's good—but not perfect—at classifying Iris species. Now let's use the trained model to make some predictions on [unlabeled examples](https://developers.google.com/machine-learning/glossary/#unlabeled_example); that is, on examples that contain features but not a label.\n", + "\n", + "In real-life, the unlabeled examples could come from lots of different sources including apps, CSV files, and data feeds. For now, we're going to manually provide three unlabeled examples to predict their labels. Recall, the label numbers are mapped to a named representation as:\n", + "\n", + "* `0`: Iris setosa\n", + "* `1`: Iris versicolor\n", + "* `2`: Iris virginica" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "kesTS5Lzv-M2" + }, + "outputs": [], + "source": [ + "predict_dataset = tf.convert_to_tensor([\n", + " [5.1, 3.3, 1.7, 0.5,],\n", + " [5.9, 3.0, 4.2, 1.5,],\n", + " [6.9, 3.1, 5.4, 2.1]\n", + "])\n", + "\n", + "predictions = model(predict_dataset)\n", + "\n", + "for i, logits in enumerate(predictions):\n", + " class_idx = tf.argmax(logits).numpy()\n", + " p = tf.nn.softmax(logits)[class_idx]\n", + " name = class_names[class_idx]\n", + " print(\"Example {} prediction: {} ({:4.1f}%)\".format(i, name, 100*p))" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "custom_training_walkthrough", + "private_outputs": true, + "provenance": [], + "toc_visible": true, + "version": "0.3.2" + }, + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb new file mode 100644 index 00000000000..89f6487d193 --- /dev/null +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -0,0 +1,467 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "iPpI7RaYoZuE" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "form", + "colab": {}, + "colab_type": "code", + "id": "hro2InpHobKk" + }, + "outputs": [], + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "U9i2Dsh-ziXr" + }, + "source": [ + "# 즉시실행(eager execution) 기초" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Hndw-YcxoOJK" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " View on TensorFlow.org\n", + " \n", + " Run in Google Colab\n", + " \n", + " View source on GitHub\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "6sILUVbHoSgH" + }, + "source": [ + "이것은 텐서플로우를 사용하기위한 입문 튜토리얼입니다. 다음 내용을 다룹니다 : \n", + "\n", + "* 필요한 패키지 임포트\n", + "* 텐서(Tensor) 생성 및 사용\n", + "* GPU 가속기 사용\n", + "* 데이터 세트" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "z1JcS5iBXMRO" + }, + "source": [ + "## 텐서플로우 임포트\n", + "\n", + "시작하기 위해서 텐서플로우 모듈을 임포트하고 즉시실행을 활성화합니다. 즉시실행으로 텐서플로우에 대한 대화형 프론트엔드(frontend)가 가능합니다. 세부사항은 나중에 이야기할 것입니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "code", + "colab": {}, + "colab_type": "code", + "id": "RlIWhyeLoYnG" + }, + "outputs": [], + "source": [ + "import tensorflow as tf\n", + "\n", + "tf.enable_eager_execution()" + ] + }, + { + "cell_type": "raw", + "metadata": { + "colab_type": "text", + "id": "H9UySOPLXdaw" + }, + "source": [ + "## 텐서\n", + "\n", + "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 형태를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로우는 텐서를 생성하고 계산하는 풍부한 연산자 라이브러리를 제공합니다. ([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.). 이러한 연산자들은 자동적으로 파이썬 타입을 전환합니다. 예를 들어:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "code", + "colab": {}, + "colab_type": "code", + "id": "ngUe237Wt48W" + }, + "outputs": [], + "source": [ + "print(tf.add(1, 2))\n", + "print(tf.add([1, 2], [3, 4]))\n", + "print(tf.square(5))\n", + "print(tf.reduce_sum([1, 2, 3]))\n", + "print(tf.encode_base64(\"hello world\"))\n", + "\n", + "# Operator overloading is also supported\n", + "print(tf.square(2) + tf.square(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "IDY4WsYRhP81" + }, + "source": [ + "각각의 텐서는 형태와 데이터 타입을 가지고 있습니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "srYWH1MdJNG7" + }, + "outputs": [], + "source": [ + "x = tf.matmul([[1]], [[2, 3]])\n", + "print(x.shape)\n", + "print(x.dtype)" + ] + }, + { + "cell_type": "raw", + "metadata": { + "colab_type": "text", + "id": "eBPw8e8vrsom" + }, + "source": [ + "넘파이 배열과 텐서의 가장 확실한 차이는 다음과 같습니다:\n", + "\n", + "1. 가속기 메모리(GPU, TPU와 같은)로 텐서를 뒷받침할 수 있습니다. \n", + "2. 텐서는 불변성(immutable)을 가집니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Dwi1tdW3JBw6" + }, + "source": [ + "### NumPy 적합성\n", + "\n", + "Tensor와 ndarray사이의 전환은 다소 간단합니다.\n", + "\n", + "* 텐서플로우 연산자는 자동적으로 Numpy ndarray를 Tensor로 전환합니다.\n", + "* 넘파이 연산자는 자동적으로 텐서플로우 텐서를 넘이파 ndarray로 전환합니다.\n", + "\n", + "텐서는 `.numpy()` 메소드(method)를 호출하여 Numpy ndarray로 전환할 수 있습니다.\n", + "가능한 경우, 텐서와 배열은 메모리 표현을 공유하기 때문에 이러한 전환은 일반적으로 간단(저렴)합니다. 그러나 텐서는 GPU 메모리에 저장될 수 있고, 넘파이 배열은 항상 호스트 메모리에 백업이 되므로, 이러한 전환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 포함됩니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "lCUWzso6mbqR" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "ndarray = np.ones([3, 3])\n", + "\n", + "print(\"TensorFlow operations convert numpy arrays to Tensors automatically\")\n", + "tensor = tf.multiply(ndarray, 42)\n", + "print(tensor)\n", + "\n", + "\n", + "print(\"And NumPy operations convert Tensors to numpy arrays automatically\")\n", + "print(np.add(tensor, 1))\n", + "\n", + "print(\"The .numpy() method explicitly converts a Tensor to a numpy array\")\n", + "print(tensor.numpy())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "PBNP8yTRfu_X" + }, + "source": [ + "## GPU acceleration\n", + "\n", + "Many TensorFlow operations can be accelerated by using the GPU for computation. Without any annotations, TensorFlow automatically decides whether to use the GPU or CPU for an operation (and copies the tensor between CPU and GPU memory if necessary). Tensors produced by an operation are typically backed by the memory of the device on which the operation executed. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "code", + "colab": {}, + "colab_type": "code", + "id": "3Twf_Rw-gQFM" + }, + "outputs": [], + "source": [ + "x = tf.random_uniform([3, 3])\n", + "\n", + "print(\"Is there a GPU available: \"),\n", + "print(tf.test.is_gpu_available())\n", + "\n", + "print(\"Is the Tensor on GPU #0: \"),\n", + "print(x.device.endswith('GPU:0'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "vpgYzgVXW2Ud" + }, + "source": [ + "### Device Names\n", + "\n", + "The `Tensor.device` property provides a fully qualified string name of the device hosting the contents of the tensor. This name encodes many details, such as an identifier of the network address of the host on which this program is executing and the device within that host. This is required for distributed execution of a TensorFlow program. The string ends with `GPU:` if the tensor is placed on the `N`-th GPU on the host." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "ZWZQCimzuqyP" + }, + "source": [ + "\n", + "\n", + "### Explicit Device Placement\n", + "\n", + "The term \"placement\" in TensorFlow refers to how individual operations are assigned (placed on) a device for execution. As mentioned above, when there is no explicit guidance provided, TensorFlow automatically decides which device to execute an operation, and copies Tensors to that device if needed. However, TensorFlow operations can be explicitly placed on specific devices using the `tf.device` context manager. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "RjkNZTuauy-Q" + }, + "outputs": [], + "source": [ + "import time\n", + "\n", + "def time_matmul(x):\n", + " start = time.time()\n", + " for loop in range(10):\n", + " tf.matmul(x, x)\n", + "\n", + " result = time.time()-start\n", + " \n", + " print(\"10 loops: {:0.2f}ms\".format(1000*result))\n", + "\n", + "\n", + "# Force execution on CPU\n", + "print(\"On CPU:\")\n", + "with tf.device(\"CPU:0\"):\n", + " x = tf.random_uniform([1000, 1000])\n", + " assert x.device.endswith(\"CPU:0\")\n", + " time_matmul(x)\n", + "\n", + "# Force execution on GPU #0 if available\n", + "if tf.test.is_gpu_available():\n", + " with tf.device(\"GPU:0\"): # Or GPU:1 for the 2nd GPU, GPU:2 for the 3rd etc.\n", + " x = tf.random_uniform([1000, 1000])\n", + " assert x.device.endswith(\"GPU:0\")\n", + " time_matmul(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "o1K4dlhhHtQj" + }, + "source": [ + "## Datasets\n", + "\n", + "This section demonstrates the use of the [`tf.data.Dataset` API](https://www.tensorflow.org/guide/datasets) to build pipelines to feed data to your model. It covers:\n", + "\n", + "* Creating a `Dataset`.\n", + "* Iteration over a `Dataset` with eager execution enabled.\n", + "\n", + "We recommend using the `Dataset`s API for building performant, complex input pipelines from simple, re-usable pieces that will feed your model's training or evaluation loops.\n", + "\n", + "If you're familiar with TensorFlow graphs, the API for constructing the `Dataset` object remains exactly the same when eager execution is enabled, but the process of iterating over elements of the dataset is slightly simpler.\n", + "You can use Python iteration over the `tf.data.Dataset` object and do not need to explicitly create an `tf.data.Iterator` object.\n", + "As a result, the discussion on iterators in the [TensorFlow Guide](https://www.tensorflow.org/guide/datasets) is not relevant when eager execution is enabled." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "zI0fmOynH-Ne" + }, + "source": [ + "### Create a source `Dataset`\n", + "\n", + "Create a _source_ dataset using one of the factory functions like [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices) or using objects that read from files like [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) or [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset). See the [TensorFlow Guide](https://www.tensorflow.org/guide/datasets#reading_input_data) for more information." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "F04fVOHQIBiG" + }, + "outputs": [], + "source": [ + "ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6])\n", + "\n", + "# Create a CSV file\n", + "import tempfile\n", + "_, filename = tempfile.mkstemp()\n", + "\n", + "with open(filename, 'w') as f:\n", + " f.write(\"\"\"Line 1\n", + "Line 2\n", + "Line 3\n", + " \"\"\")\n", + "\n", + "ds_file = tf.data.TextLineDataset(filename)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "vbxIhC-5IPdf" + }, + "source": [ + "### Apply transformations\n", + "\n", + "Use the transformations functions like [`map`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`batch`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`shuffle`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle) etc. to apply transformations to the records of the dataset. See the [API documentation for `tf.data.Dataset`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset) for details." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "uXSDZWE-ISsd" + }, + "outputs": [], + "source": [ + "ds_tensors = ds_tensors.map(tf.square).shuffle(2).batch(2)\n", + "\n", + "ds_file = ds_file.batch(2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "A8X1GNfoIZKJ" + }, + "source": [ + "### Iterate\n", + "\n", + "When eager execution is enabled `Dataset` objects support iteration.\n", + "If you're familiar with the use of `Dataset`s in TensorFlow graphs, note that there is no need for calls to `Dataset.make_one_shot_iterator()` or `get_next()` calls." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "ws-WKRk5Ic6-" + }, + "outputs": [], + "source": [ + "print('Elements of ds_tensors:')\n", + "for x in ds_tensors:\n", + " print(x)\n", + "\n", + "print('\\nElements in ds_file:')\n", + "for x in ds_file:\n", + " print(x)" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "eager_basics.ipynb", + "private_outputs": true, + "provenance": [], + "toc_visible": true, + "version": "0.3.2" + }, + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md new file mode 100644 index 00000000000..9c28180b352 --- /dev/null +++ b/site/ko/tutorials/eager/index.md @@ -0,0 +1,13 @@ +# Research and experimentation + +Eager execution provides an imperative, define-by-run interface for advanced +operations. Write custom layers, forward passes, and training loops with +auto differentiation. Start with these notebooks, then read the +[eager execution guide](../../guide/eager). + +1. [Eager execution](eager_basics.ipynb) +2. [Automatic differentiation and gradient tape](automatic_differentiation.ipynb) +3. [Custom training: basics](custom_training.ipynb) +4. [Custom layers](custom_layers.ipynb) +5. [Custom training: walkthrough](custom_training_walkthrough.ipynb) + From 340fcffaf7a389a0f5a6a3a76163bce446c8315e Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Tue, 26 Mar 2019 01:10:30 +0900 Subject: [PATCH 03/19] Update from bd099118 --- .../eager/automatic_differentiation.ipynb | 14 +- site/ko/tutorials/eager/custom_layers.ipynb | 74 +++----- .../eager/custom_training_walkthrough.ipynb | 179 +++++++++--------- site/ko/tutorials/eager/eager_basics.ipynb | 65 ++++--- site/ko/tutorials/eager/index.md | 24 ++- 5 files changed, 174 insertions(+), 182 deletions(-) diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index e835160ebd7..de7ea83a46b 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -41,7 +41,7 @@ "id": "xh8WkEwWpnm7" }, "source": [ - "# Automatic differentiation and gradient tape" + "# 자동미분(Automatic differentiation) 과 그래디언트 테이프" ] }, { @@ -71,7 +71,7 @@ "id": "vDJ4XzMqodTy" }, "source": [ - "이전 튜토리얼에서 우리는 Tensor와 연산자들에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술인 [자동미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." + "이전 튜토리얼에서 우리는 Tensor와 Tensor의 연산들에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술인 [자동미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." ] }, { @@ -108,7 +108,7 @@ "source": [ "## 그래디언트 테이프(Gradient Tape)\n", "\n", - "텐서플로우는 자동미분(주어진 입력 변수에 따른 기울기 계산)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape` 내에서 실행된 모든 연산자들을 tape에 \"기록\"합니다. 그리고 [역방향 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 기록된 계산의 그래디언트를 계산하기 위해 각각의 기록된 연산자들과 관련된 테이프와 그래디언트들을 사용합니다. \n", + "텐서플로우는 자동미분(주어진 입력 변수에 따른 기울기 연산)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape`는 안에서 실행된 모든 연산을 tape에 \"기록\"합니다. 그리고 [역방향 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 기록된 연산의 그래디언트를 계산하기 위해 각각의 기록된 연산들과 관련된 테이프와 그래디언트들을 사용합니다. \n", "\n", "예를 들면:" ] @@ -177,7 +177,7 @@ "id": "ISkXuY7YzIcS" }, "source": [ - "초기값으로 GradientTape.gradient() 메소드가 호출되면 GradientTape에 포함된 리소스가 해체되게 설정돼있습니다. 동일한 계산을 통해서 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. `persistent`는 `gradient()` 메소드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다." + "초기값으로 GradientTape.gradient() 메소드가 호출되면 GradientTape에 포함된 리소스가 해체되게 설정돼있습니다. 동일한 연산을 통해서 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. `persistent`는 `gradient()` 메소드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다." ] }, { @@ -209,7 +209,7 @@ "source": [ "### 제어흐름(Control Flow) 기록\n", "\n", - "테이프가 실행되는데로 연산자를 기록하기 때문에, 파이썬 제어흐름(예를 들어 `if` `while`, `for`문 같은)은 자연스럽게 처리됩니다. " + "테이프가 실행되는데로 연산을 기록하기 때문에, 파이썬 제어흐름(예를 들어 `if` `while`, `for`문 같은)은 자연스럽게 처리됩니다. " ] }, { @@ -251,7 +251,7 @@ "source": [ "### 고차원(Higher-order) 그래디언트\n", "\n", - "`GradientTape` 컨텍스트 매니저안에 있는 연산자들은 자동미분을 위해 기록됩니다. 만약 그래디언트가 컨텍스트 안에서 계산되면 그래디언트 계산 또한 기록되어집니다. 그 결과 똑같은 API가 고차원 그래디언트에서도 잘 작동합니다. 예를 들면:" + "`GradientTape` 컨텍스트 매니저안에 있는 연산들은 자동미분을 위해 기록됩니다. 만약 그래디언트가 컨텍스트 안에서 연산되면 그래디언트 연산 또한 기록되어집니다. 그 결과 똑같은 API가 고차원 그래디언트에서도 잘 작동합니다. 예를 들면:" ] }, { @@ -269,7 +269,7 @@ "with tf.GradientTape() as t:\n", " with tf.GradientTape() as t2:\n", " y = x * x * x\n", - " # t 컨텍스트 매니저 안의 그래디언트 계산\n", + " # t 컨텍스트 매니저 안의 그래디언트 연산\n", " # 이것은 또한 그래디언트 계산이 미분가능하다는것을 의미합니다. \n", " dy_dx = t2.gradient(y, x)\n", "d2y_dx2 = t.gradient(dy_dx, x)\n", diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index cb1a6022b24..97091da1efb 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -41,7 +41,7 @@ "id": "60RdWsg1tETW" }, "source": [ - "# Custom layers" + "# 사용자 정의 레이어" ] }, { @@ -71,7 +71,7 @@ "id": "UEu3q4jmpKVT" }, "source": [ - "We recommend using `tf.keras` as a high-level API for building neural networks. That said, most TensorFlow APIs are usable with eager execution.\n" + "신경망을 구축하기 위해서 고수준 API인 `tf.keras`를 사용하길 권합니다. 대부분의 텐서플로우 API는 즉시실행(eager execution)을 활성화할 수 있습니다." ] }, { @@ -96,13 +96,13 @@ "id": "zSFfVVjkrrsI" }, "source": [ - "## Layers: common sets of useful operations\n", + "## 레이어(layer): 유용한 연산자 집합\n", "\n", - "Most of the time when writing code for machine learning models you want to operate at a higher level of abstraction than individual operations and manipulation of individual variables.\n", + "머신러닝을 위한 코드를 작성하는 대부분의 시간에 우리는, 개별적인 연산과 변수를 조작하는 것보다는 고수준의 추상화 수준에서 작업하기를 원합니다.\n", "\n", - "Many machine learning models are expressible as the composition and stacking of relatively simple layers, and TensorFlow provides both a set of many common layers as a well as easy ways for you to write your own application-specific layers either from scratch or as the composition of existing layers.\n", + "많은 머신러닝 모델은 비교적 단순한 레이어의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로우는 여러 표준 레이어 세트를 제공하므로 사용자 고유의 응용 프로그램에 관련된 레이어를 처음부터 작성하거나, 기존 레이어의 구성으로 쉽게 작성할 수 있습니다.\n", "\n", - "TensorFlow includes the full [Keras](https://keras.io) API in the tf.keras package, and the Keras layers are very useful when building your own models.\n" + "텐서플로우는 [Keras](https://keras.io) API 의 풀페키지를 tf.keras package에 포함하고 있습니다. Keras 레이어는 모델을 구축하는데 매우 유용합니다." ] }, { @@ -115,13 +115,11 @@ }, "outputs": [], "source": [ - "# In the tf.keras.layers package, layers are objects. To construct a layer,\n", - "# simply construct the object. Most layers take as a first argument the number\n", - "# of output dimensions / channels.\n", + "# tf.keras.layers 패키지에서 레이어는 객체입니다. 레이어를 구성하려면 간단히 객체를 생성하십시오.\n", + "# 대부분의 레이어는 첫번째 인수로 출력 차원(크기) 또는 채널을 취합니다.\n", "layer = tf.keras.layers.Dense(100)\n", - "# The number of input dimensions is often unnecessary, as it can be inferred\n", - "# the first time the layer is used, but it can be provided if you want to \n", - "# specify it manually, which is useful in some complex models.\n", + "# 입력 차원의 수는 유추될 수 있기 때문에 종종 불필요합니다. \n", + "# 일부 복잡한 모델에서는 수동으로 입력 차원의 수를 제공하는것이 유용할 수 있습니다.\n", "layer = tf.keras.layers.Dense(10, input_shape=(None, 5))" ] }, @@ -132,8 +130,7 @@ "id": "Fn69xxPO5Psr" }, "source": [ - "The full list of pre-existing layers can be seen in [the documentation](https://www.tensorflow.org/api_docs/python/tf/keras/layers). It includes Dense (a fully-connected layer),\n", - "Conv2D, LSTM, BatchNormalization, Dropout, and many others." + "미리 구성되어있는 레이어는 다음 [문서](https://www.tensorflow.org/api_docs/python/tf/keras/layers)에서 확인할 수 있습니다. Dense, Conv2D, LSTM, BatchNormalization, Dropout, 등을 포함하고 있습니다." ] }, { @@ -146,7 +143,7 @@ }, "outputs": [], "source": [ - "# To use a layer, simply call it.\n", + "# 레이어를 사용하기 위해서 간단하게 호출합니다.\n", "layer(tf.zeros([10, 5]))" ] }, @@ -160,10 +157,9 @@ }, "outputs": [], "source": [ - "# Layers have many useful methods. For example, you can inspect all variables\n", - "# in a layer using `layer.variables` and trainable variables using \n", - "# `layer.trainable_variables`. In this case a fully-connected layer\n", - "# will have variables for weights and biases.\n", + "# 레이어는 유용한 메소드들을 내재하고있습니다. 예를 들어, `layer.variables`를 사용하여 레이어안에 있는 모든 변수들을 확인할 수 있으며, \n", + "# `layer.trainable_variables`를 사용하여 학습가능한 변수들을 확인할 수 있습니다. \n", + "# 이번 케이스에서 완전 연결(fully-connected) 레이어는 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", "layer.variables" ] }, @@ -177,7 +173,7 @@ }, "outputs": [], "source": [ - "# The variables are also accessible through nice accessors\n", + "# 또한 변수는 여러 accessors를 통해 접근가능합니다. \n", "layer.kernel, layer.bias" ] }, @@ -188,13 +184,13 @@ "id": "O0kDbE54-5VS" }, "source": [ - "## Implementing custom layers\n", - "The best way to implement your own layer is extending the tf.keras.Layer class and implementing:\n", - " * `__init__` , where you can do all input-independent initialization\n", - " * `build`, where you know the shapes of the input tensors and can do the rest of the initialization\n", - " * `call`, where you do the forward computation\n", + "## 사용자 정의 레이어 구현\n", + "사용자 정의 레이어를 구현하는 가장 좋은 방법은 tf.keras.Layer 클래스를 상속하고 다음과 같이 구현하는 것입니다.\n", + " * `__init__` , 여기서 모든 입력 독립적인 초기화를 할 수 있습니다.\n", + " * `build`, 입력 텐서의 형태를 알고 나머지를 초기화 할 수 있습니다.\n", + " * `call`, 정방향 계산을 진행 할 수 있습니다.\n", "\n", - "Note that you don't have to wait until `build` is called to create your variables, you can also create them in `__init__`. However, the advantage of creating them in `build` is that it enables late variable creation based on the shape of the inputs the layer will operate on. On the other hand, creating variables in `__init__` would mean that shapes required to create the variables will need to be explicitly specified." + "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 레이어가 작동할 입력의 형태를 기준으로 나중에 변수를 만들 수 있습니다. 반면에, `__init__`에 변수를 생성하는것은 변수 생성에 필요한 형태가 명시적으로 지정되어야 함을 의미합니다.변수를 생성하는 데 필요한 모양이 명시적으로 지정되어야 함을 의미합니다." ] }, { @@ -232,9 +228,9 @@ "id": "tk8E2vY0-z4Z" }, "source": [ - "Note that you don't have to wait until `build` is called to create your variables, you can also create them in `__init__`.\n", + "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. \n", "\n", - "Overall code is easier to read and maintain if it uses standard layers whenever possible, as other readers will be familiar with the behavior of standard layers. If you want to use a layer which is not present in tf.keras.layers or tf.contrib.layers, consider filing a [github issue](http://github.com/tensorflow/tensorflow/issues/new) or, even better, sending us a pull request!" + "다른 독자가 표준 레이어의 동작을 잘 알고 있기 때문에, 가능한 경우 표준 레이어를 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers, tf.keras.layers 또는 tf.contrib.layers에 없는 레이어를 사용하기 원하면 [github issue](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀리퀘스트를 요청하세요." ] }, { @@ -244,11 +240,11 @@ "id": "Qhg4KlbKrs3G" }, "source": [ - "## Models: composing layers\n", + "## 모델: 레이어 구성\n", "\n", - "Many interesting layer-like things in machine learning models are implemented by composing existing layers. For example, each residual block in a resnet is a composition of convolutions, batch normalizations, and a shortcut.\n", + "머신러닝 모델에서 많은 흥미로운 유사 레이어(layer-likely)는 레이어들의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 residual block은 합성곱(convolution), 배치정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", "\n", - "The main class used when creating a layer-like thing which contains other layers is tf.keras.Model. Implementing one is done by inheriting from tf.keras.Model." + "레이어 집합을 포함한 유사 레이어를 생성하기위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(Inheritance)하여 구현합니다." ] }, { @@ -296,16 +292,6 @@ "print([x.name for x in block.trainable_variables])" ] }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "wYfucVw65PMj" - }, - "source": [ - "Much of the time, however, models which compose many layers simply call one layer after the other. This can be done in very little code using tf.keras.Sequential" - ] - }, { "cell_type": "code", "execution_count": null, @@ -327,15 +313,15 @@ ] }, { - "cell_type": "markdown", + "cell_type": "raw", "metadata": { "colab_type": "text", "id": "c5YwYcnuK-wc" }, "source": [ - "# Next steps\n", + "# 다음 단계\n", "\n", - "Now you can go back to the previous notebook and adapt the linear regression example to use layers and models to be better structured." + "이제 여러분들은 이전 노트북으로 돌아가서 선형 회귀 예제에 레이어와 모델을 적용하여 좀 더 나은 구조를 만들 수 있습니다." ] } ], diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index 055fab9b058..cc5f9e4f43a 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -41,7 +41,7 @@ "id": "JtEZ1pCPn--z" }, "source": [ - "# 사용자 지정 학습: walkthrough" + "# 사용자 정의 학습: walkthrough" ] }, { @@ -65,13 +65,13 @@ ] }, { - "cell_type": "raw", + "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "LDrzLFXE8T1l" }, "source": [ - "이번 튜토리얼은 붓꽃의 품종을 분류하기 위한 머신러닝 모델을 구축할 것입니다. 다음을 위해 즉시실행[eager execution](https://www.tensorflow.org/guide/eager)을 사용합니다.\n", + "이번 튜토리얼은 붓꽃의 품종을 분류하기 위한 머신러닝 모델을 구축할 것입니다. 다음을 위해 즉시실행[(eager execution)](https://www.tensorflow.org/guide/eager)을 사용합니다.\n", "1. 모델 구축\n", "2. 모델 훈련\n", "3. 예측을 위한 모델 사용\n", @@ -80,7 +80,7 @@ "\n", "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로우의 개념들을 사용합니다.\n", "\n", - "* 즉시실행[eager execution](https://www.tensorflow.org/guide/eager) 개발환경,\n", + "* 즉시실행([eager execution])(https://www.tensorflow.org/guide/eager) 개발환경,\n", "* [Datasets API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 불러오기,\n", "* [Keras API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 레이어(layer) 구축 .\n", "\n", @@ -112,7 +112,7 @@ "source": [ "### 임포트 및 즉시실행 구성\n", "\n", - "텐서플로우를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시실행을 활성화할 것입니다. 즉시실행은 텐서플로우가 나중에 실행되는 [computational graph](https://www.tensorflow.org/guide/graphs)를 만드는데신, 연산자를 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", + "텐서플로우를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시실행을 활성화할 것입니다. 즉시실행은 텐서플로우가 나중에 실행되는 [computational graph](https://www.tensorflow.org/guide/graphs)를 만드는데신, 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", "\n", "즉시실행이 활성화 될때, 동일한 프로그램내에서는 비활성화를 할 수 없습니다. 더 많은 세부사항은 [eager execution guide](https://www.tensorflow.org/guide/eager)을 참조하세요." ] @@ -183,7 +183,7 @@ "\n", "### 데이터셋 다운로드\n", "\n", - "[tf.keras.utils.get_file](https://www.tensorflow.org/api_docs/python/tf/keras/utils/get_file)함수를 사용하여 데이터셋을 다운로드합니다. 이 함수는 다운로드된 파일의 경로를 반환합니다." + "[tf.keras.utils.get_file](https://www.tensorflow.org/api_docs/python/tf/keras/utils/get_file) 함수를 사용하여 데이터셋을 다운로드합니다. 이 함수는 다운로드된 파일의 경로를 반환합니다." ] }, { @@ -211,7 +211,7 @@ "id": "qnX1-aLors4S" }, "source": [ - "### 데이터 관찰\n", + "### 데이터 탐색\n", "\n", "이 데이터셋(`iris_training.csv`)은 ','로 구분된 CSV 파일입니다. `head -n5` 명령을 사용하여 처음 5개 항목을 확인합니다. " ] @@ -236,15 +236,15 @@ "id": "kQhzD6P-uBoq" }, "source": [ - "From this view of the dataset, notice the following:\n", + "처음 5개의 데이터로부터 다음을 주목하세요.\n", "\n", "1. 첫번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", - " * 총 120개의 예가 있다. 각 예들은 4가지의 특성(feature)을 가지고 3가지 가능한 레이블(label)을 가지고 있습니다.\n", - "2. 후속행은 데이터 레코드입니다. one *[example](https://developers.google.com/machine-learning/glossary/#example)* per line, where:\n", - " * The first four fields are *[features](https://developers.google.com/machine-learning/glossary/#feature)*: these are characteristics of an example. Here, the fields hold float numbers representing flower measurements.\n", - " * The last column is the *[label](https://developers.google.com/machine-learning/glossary/#label)*: this is the value we want to predict. For this dataset, it's an integer value of 0, 1, or 2 that corresponds to a flower name.\n", + " * 총 120개의 예가 있다. 각 예들은 4가지의 특성(feature)을 가지며 3가지 가능한 레이블(label)을 가지고 있습니다.\n", + "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[예](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", + " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 예제의 특징을 나타냅니다. 이 필드는 붓꽃의 측정값을 나타내는 부동소수점을 나타냅니다.\n", + " * 마지막 컬럼(column)은 *[레이블(label)](https://developers.google.com/machine-learning/glossary/#label)*입니다.: 레이블은 우리가 에측하고자 하는 값을 나타냅니다. 이 데이터셋에서는 꽃의 이름과 관련된 정수값 0, 1, 2를 나타냅니다.\n", "\n", - "Let's write that out in code:" + "코드로 표현하면 다음과 같습니다.:" ] }, { @@ -274,13 +274,13 @@ "id": "CCtwLoJhhDNc" }, "source": [ - "각각의 레이블은 \"setosa\"와 같은 문자형 이름과 연관되어있습니다. 하지만 머신러닝은 전형적이로 숫자형값에 의존합니다. 레이블을 다음과 같이 맵핑(mapping) 합니다. \n", + "각각의 레이블은 \"setosa\"와 같은 문자형 이름과 연관되어있습니다. 하지만 머신러닝은 전형적으로 숫자형값에 의존합니다. 레이블을 다음과 같이 맵핑(mapping) 합니다. \n", "\n", "* `0`: Iris setosa\n", "* `1`: Iris versicolor\n", "* `2`: Iris virginica\n", "\n", - "특성과 레이블에 관한 더 많은 정보를 위해서 다음을 참조하세요.[ML Terminology section of the Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/framing/ml-terminology)." + "특성과 레이블에 관한 더 많은 정보를 위해서 다음을 참조하세요. [ML Terminology section of the Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/framing/ml-terminology)." ] }, { @@ -305,10 +305,10 @@ "source": [ "### `tf.data.Dataset` 생성\n", "\n", - "TensorFlow's [Dataset API](https://www.tensorflow.org/guide/datasets) handles many common cases for loading data into a model. This is a high-level API for reading data and transforming it into a form used for training. See the [Datasets Quick Start guide](https://www.tensorflow.org/get_started/datasets_quickstart) for more information.\n", + "텐서플로우의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위한 많은 케이스를 다룹니다. 이는 훈련을 위한 형태로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 다음을 참조하세요. [Datasets Quick Start guide](https://www.tensorflow.org/get_started/datasets_quickstart) \n", "\n", "\n", - "Since the dataset is a CSV-formatted text file, use the [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) function to parse the data into a suitable format. Since this function generates data for training models, the default behavior is to shuffle the data (`shuffle=True, shuffle_buffer_size=10000`), and repeat the dataset forever (`num_epochs=None`). We also set the [batch_size](https://developers.google.com/machine-learning/glossary/#batch_size) parameter." + "데이터셋이 CSV 형태의 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 배치 사이즈[batch_size](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." ] }, { @@ -338,9 +338,9 @@ "id": "gB_RSn62c-3G" }, "source": [ - "The `make_csv_dataset` function returns a `tf.data.Dataset` of `(features, label)` pairs, where `features` is a dictionary: `{'feature_name': value}`\n", - "\n", - "With eager execution enabled, these `Dataset` objects are iterable. Let's look at a batch of features:" + "`make_csv_dataset` 함수는 `tf.data.Dataset` 의 `(features, label)` 쌍을 반환합니다., where \n", + "`features` 가 사전형 객체인: `{'feature_name': value}`로 주어집니다.\n", + "즉시실행 활성화로 이 `Dataset`은 반복가능합니다. 특성(feature)을 살펴봅시다." ] }, { @@ -365,9 +365,9 @@ "id": "E63mArnQaAGz" }, "source": [ - "Notice that like-features are grouped together, or *batched*. Each example row's fields are appended to the corresponding feature array. Change the `batch_size` to set the number of examples stored in these feature arrays.\n", + "유사한 특성의 값들은 같이 그룹되어있거나, *배치* 되있다는 사실에 주목하세요. 각 예제행의 필드는 해당 특성 배열에 추가됩니다. `batch_size` 조절하여 이 특성 배열에 저장된 예제의 수를 설정하세요.\n", "\n", - "You can start to see some clusters by plotting a few features from the batch:" + "또한 여러분들은 배치(batch)로부터 약간의 특성을 도식화하여 군집되있는 데이터를 확인할 수 있습니다. " ] }, { @@ -396,9 +396,9 @@ "id": "YlxpSyHlhT6M" }, "source": [ - "To simplify the model building step, create a function to repackage the features dictionary into a single array with shape: `(batch_size, num_features)`.\n", + "모델 구축단계를 단순화하기 위해서, 특성 사전 객체를 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", "\n", - "This function uses the [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) method which takes values from a list of tensors and creates a combined tensor at the specified dimension." + "이 함수는 `Tensor`의 list로부터 값을 취하고 특정한 차원으로 결합된 `Tensor`를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메소드(method)를 사용합니다." ] }, { @@ -424,7 +424,7 @@ "id": "V1Vuph_eDl8x" }, "source": [ - "Then use the [tf.data.Dataset.map](https://www.tensorflow.org/api_docs/python/tf/data/dataset/map) method to pack the `features` of each `(features,label)` pair into the training dataset:" + "그 후 각 `(features,label)`쌍의 `features`을 훈련 데이터셋에 적재하기위해 [tf.data.Dataset.map](https://www.tensorflow.org/api_docs/python/tf/data/dataset/map) 메소드를 사용합니다. " ] }, { @@ -447,7 +447,7 @@ "id": "NLy0Q1xCldVO" }, "source": [ - "The features element of the `Dataset` are now arrays with shape `(batch_size, num_features)`. Let's look at the first few examples:" + "데이터셋의 특성 요소들은 이제 형태가 `(batch_size, num_features)`인 배열입니다. 첫 5행의 예제를 살펴봅시다." ] }, { @@ -472,17 +472,17 @@ "id": "LsaVrtNM3Tx5" }, "source": [ - "## Select the type of model\n", + "## 모델 타입 선정\n", "\n", - "### Why model?\n", + "### 왜 모델을 사용해야하는가?\n", "\n", - "A *[model](https://developers.google.com/machine-learning/crash-course/glossary#model)* is a relationship between features and the label. For the Iris classification problem, the model defines the relationship between the sepal and petal measurements and the predicted Iris species. Some simple models can be described with a few lines of algebra, but complex machine learning models have a large number of parameters that are difficult to summarize.\n", + " *[모델](https://developers.google.com/machine-learning/crash-course/glossary#model)*은 특성(feature)들과 레이블(label)과의 관계입니다. 붓꽃 분류 문제에서 모델은 측정된 꽃받침과 꽃잎 사이의 관계를 정의하고 붓꽃의 품종을 예측합니다. 몇가지 간단한 모델은 몇 줄의 대수학으로 표현할 수 있으나, 복잡한 머신러닝 모델은 요약하기 힘든 굉장히 많은 수의 매개변수를 가지고 있습니다.\n", "\n", - "Could you determine the relationship between the four features and the Iris species *without* using machine learning? That is, could you use traditional programming techniques (for example, a lot of conditional statements) to create a model? Perhaps—if you analyzed the dataset long enough to determine the relationships between petal and sepal measurements to a particular species. And this becomes difficult—maybe impossible—on more complicated datasets. A good machine learning approach *determines the model for you*. If you feed enough representative examples into the right machine learning model type, the program will figure out the relationships for you.\n", + "머신러닝을 사용하지 않고 4가지의 특성사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 아마 여러분들이 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문들)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 여러분들을 위한 모델을 결정합니다. 만약 여러분들이 충분한 예제를 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 여러분들을 위한 특성들간의 관계를 이해합니다. \n", "\n", - "### Select the model\n", + "### 모델 선정\n", "\n", - "We need to select the kind of model to train. There are many types of models and picking a good one takes experience. This tutorial uses a neural network to solve the Iris classification problem. *[Neural networks](https://developers.google.com/machine-learning/glossary/#neural_network)* can find complex relationships between features and the label. It is a highly-structured graph, organized into one or more *[hidden layers](https://developers.google.com/machine-learning/glossary/#hidden_layer)*. Each hidden layer consists of one or more *[neurons](https://developers.google.com/machine-learning/glossary/#neuron)*. There are several categories of neural networks and this program uses a dense, or *[fully-connected neural network](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*: the neurons in one layer receive input connections from *every* neuron in the previous layer. For example, Figure 2 illustrates a dense neural network consisting of an input layer, two hidden layers, and an output layer:\n", + "우리는 학습을 위한 모델의 종류를 선정해야합니다. 여러정류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡환 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*들로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[dense(또는 fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전연결 신경망(fully-connected neural network)는 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전연결 신경망입니다. \n", "\n", "\n", " \n", " \n", "
\n", @@ -490,11 +490,11 @@ " alt=\"A diagram of the network architecture: Inputs, 2 hidden layers, and outputs\">\n", "
\n", - " Figure 2. A neural network with features, hidden layers, and predictions.
 \n", + " 그림 2. A neural network with features, hidden layers, and predictions.
 \n", "
\n", "\n", - "When the model from Figure 2 is trained and fed an unlabeled example, it yields three predictions: the likelihood that this flower is the given Iris species. This prediction is called *[inference](https://developers.google.com/machine-learning/crash-course/glossary#inference)*. For this example, the sum of the output predictions is 1.0. In Figure 2, this prediction breaks down as: `0.02` for *Iris setosa*, `0.95` for *Iris versicolor*, and `0.03` for *Iris virginica*. This means that the model predicts—with 95% probability—that an unlabeled example flower is an *Iris versicolor*." + "그림 2의 모델이 훈련되고 레이블 되어있지 않은 데이터를 제공했을때, 모델은 주어진 데이터의 3가지 예측을 출력(주어진 레이블의 개수)합니다. 이러한 예측은 *[추론(inference)](https://developers.google.com/machine-learning/crash-course/glossary#inference)*이라고 정의합니다. 이 예제에서 출력의 합은 1.0입니다. 그림 2에서 예측은 `0.02` for *Iris setosa*, `0.95` for *Iris versicolor*, `0.03` for *Iris virginica*로 주어집니다. 이는 모델이 95%의 확률로 주어진 데이터를 *Iris versicolor*로 예측한다는 것을 의미합니다. " ] }, { @@ -504,11 +504,11 @@ "id": "W23DIMVPQEBt" }, "source": [ - "### Create a model using Keras\n", + "### Keras를 사용한 모델 생성\n", "\n", - "The TensorFlow [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API is the preferred way to create models and layers. This makes it easy to build models and experiment while Keras handles the complexity of connecting everything together.\n", + "텐서플로우의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 레이어를 생성하기위한 풍부한 라이브러리를 가지고있습니다. 이는 연결되있는 모든것들을 케라스가 처리하여 모델의 구축하기 쉽게 만듭니다.\n", "\n", - "The [tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential) model is a linear stack of layers. Its constructor takes a list of layer instances, in this case, two [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense) layers with 10 nodes each, and an output layer with 3 nodes representing our label predictions. The first layer's `input_shape` parameter corresponds to the number of features from the dataset, and is required." + "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 레이어의 선형 적층 모델입니다. 이 구조는 레이어의 인스턴스를 취하며, 아래의 케이스의 경우 각 레이어당 10개의 노드(node)를 가지는 2개의 [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense) 레이어와 3개의 예측(레이블의 개수)노드를 가지는 출력 레이어로 구성되어있습니다. 첫번째 레이어의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." ] }, { @@ -535,9 +535,9 @@ "id": "FHcbEzMpxbHL" }, "source": [ - "The *[activation function](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)* determines the output shape of each node in the layer. These non-linearities are important—without them the model would be equivalent to a single layer. There are many [available activations](https://www.tensorflow.org/api_docs/python/tf/keras/activations), but [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU) is common for hidden layers.\n", + "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 레이어의 출력의 형태를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 단일 레이어와 동일하다고 생각할 수 있습니다. 사용가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", "\n", - "The ideal number of hidden layers and neurons depends on the problem and the dataset. Like many aspects of machine learning, picking the best shape of the neural network requires a mixture of knowledge and experimentation. As a rule of thumb, increasing the number of hidden layers and neurons typically creates a more powerful model, which requires more data to train effectively." + "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 좌우됩니다. 머신러닝의 여러측면과 마찬가지로, 신경망의 최적의 형태를 결정하는것은 많은 경험과 지식이 필요합니다. 경험을 토대로, 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." ] }, { @@ -547,9 +547,9 @@ "id": "2wFKnhWCpDSS" }, "source": [ - "### Using the model\n", + "### 모델 사용\n", "\n", - "Let's have a quick look at what this model does to a batch of features:" + "이 모델이 배치 특성에 대해 수행하는 작업을 간단히 살펴보겠습니다. " ] }, { @@ -573,9 +573,9 @@ "id": "wxyXOhwVr5S3" }, "source": [ - "Here, each example returns a [logit](https://developers.google.com/machine-learning/crash-course/glossary#logits) for each class. \n", + "각 예제는 각 클래스에 대한 [로짓(logit)](https://developers.google.com/machine-learning/crash-course/glossary#logits)을 반환합니다. \n", "\n", - "To convert these logits to a probability for each class, use the [softmax](https://developers.google.com/machine-learning/crash-course/glossary#softmax) function:" + "이 로짓(logit)을 각 클래스에 대한 확률로 변환하기 위하서 [소프트맥스(softmax)](https://developers.google.com/machine-learning/crash-course/glossary#softmax) 함수를 사용하겠습니다." ] }, { @@ -598,7 +598,7 @@ "id": "uRZmchElo481" }, "source": [ - "Taking the `tf.argmax` across classes gives us the predicted class index. But, the model hasn't been trained yet, so these aren't good predictions." + "`tf.argmax`는 예측된 값들 중 가장 큰 확률(우리가 원하는 클래스)을 반환합니다. 하지만 모델이 아직 훈련되지 않았으므로 이는 좋은 예측이 아닙니다." ] }, { @@ -622,11 +622,11 @@ "id": "Vzq2E5J2QMtw" }, "source": [ - "## Train the model\n", + "## 모델 훈련하기\n", "\n", - "*[Training](https://developers.google.com/machine-learning/crash-course/glossary#training)* is the stage of machine learning when the model is gradually optimized, or the model *learns* the dataset. The goal is to learn enough about the structure of the training dataset to make predictions about unseen data. If you learn *too much* about the training dataset, then the predictions only work for the data it has seen and will not be generalizable. This problem is called *[overfitting](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)*—it's like memorizing the answers instead of understanding how to solve a problem.\n", + "*[훈련 단계](https://developers.google.com/machine-learning/crash-course/glossary#training)*는 모델이 점진적으로 최적화되거나 데이터셋을 학습하는 머신러닝의 과정입니다. 훈련의 목적은 미지의 데이터를 예측하기위해, 훈련 데이터셋의 구조에 대해서 충분히 학습하는것 입니다. 만약 모델이 훈련 데이터셋에 대해서 과하게 학습된다면, 오직 훈련 데이터셋에 대해서 작동할 것이며, 일반화되기 힘들것입니다. 이러한 문제를 *[overfitting](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)* 이라고 합니다. 이는 마치 문제를 이해하고 해결한다기 보다는 답을 기억하는 것이라고 생각할 수 있습니다. \n", "\n", - "The Iris classification problem is an example of *[supervised machine learning](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*: the model is trained from examples that contain labels. In *[unsupervised machine learning](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*, the examples don't contain labels. Instead, the model typically finds patterns among the features." + "붓꽃 분류 문제는 지도학습 *[지도학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도 학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고있지않습니다. 대신에 모델은 특성들의 패턴을 찾습니다. " ] }, { @@ -636,11 +636,11 @@ "id": "RaKp8aEjKX6B" }, "source": [ - "### Define the loss and gradient function\n", + "### 손실 함수와 그래디언트 함수 정의하기\n", "\n", - "Both training and evaluation stages need to calculate the model's *[loss](https://developers.google.com/machine-learning/crash-course/glossary#loss)*. This measures how off a model's predictions are from the desired label, in other words, how bad the model is performing. We want to minimize, or optimize, this value.\n", + "훈련과 평가단계는 모델의 *[손실(loss)](https://developers.google.com/machine-learning/crash-course/glossary#loss)* 계산할 필요가 있습니다. 손실은 모델의 예측이 원하는 레이블과 얼마나 일치하는지, 또한 모델이 잘 작동하는지에 대한 척도로 사용됩니다. 우리는 이 값은 최소화하고, 최적화하기를 원합니다. \n", "\n", - "Our model will calculate its loss using the [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) function which takes the model's class probability predictions and the desired label, and returns the average loss across the examples." + "모델의 손실은 [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) 함수를 사용하여 계산할 것입니다. 이 함수는 모델의 클래스(레이블)과 예측된 값(logit)을 입력받아 예제를 통한 평균 손실을 반환합니다." ] }, { @@ -669,7 +669,7 @@ "id": "3IcPqA24QM6B" }, "source": [ - "Use the [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) context to calculate the *[gradients](https://developers.google.com/machine-learning/crash-course/glossary#gradient)* used to optimize our model. For more examples of this, see the [eager execution guide](https://www.tensorflow.org/guide/eager)." + "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)* 계산하기위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 다음을 확인하세요. [eager execution guide](https://www.tensorflow.org/guide/eager)." ] }, { @@ -695,9 +695,9 @@ "id": "lOxFimtlKruu" }, "source": [ - "### Create an optimizer\n", + "### Optimizer 생성 \n", "\n", - "An *[optimizer](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)* applies the computed gradients to the model's variables to minimize the `loss` function. You can think of the loss function as a curved surface (see Figure 3) and we want to find its lowest point by walking around. The gradients point in the direction of steepest ascent—so we'll travel the opposite way and move down the hill. By iteratively calculating the loss and gradient for each batch, we'll adjust the model during training. Gradually, the model will find the best combination of weights and bias to minimize loss. And the lower the loss, the better the model's predictions.\n", + "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 `손실`함수를 최소화하기위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 우리는 이 함수의 최저점을 찾고자합니다. The gradients point in the direction of steepest ascent—so we'll travel the opposite way and move down the hill. By iteratively calculating the loss and gradient for each batch, we'll adjust the model during training. Gradually, the model will find the best combination of weights and bias to minimize loss. And the lower the loss, the better the model's predictions.\n", "\n", "\n", " \n", "
\n", @@ -709,7 +709,7 @@ "
\n", "\n", - "TensorFlow has many [optimization algorithms](https://www.tensorflow.org/api_guides/python/train) available for training. This model uses the [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer) that implements the *[stochastic gradient descent](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* (SGD) algorithm. The `learning_rate` sets the step size to take for each iteration down the hill. This is a *hyperparameter* that you'll commonly adjust to achieve better results." + "텐서플로우는 학습을 위해 이용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 그래디언트 하강(stochastic gradient descent)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현하는 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. 매개변수 `learning_rate`은 경사하강 과정의 크기를 나타내는 척도이며, 더 나은 결과를 위해 공동적으로 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " ] }, { @@ -719,7 +719,7 @@ "id": "XkUd6UiZa_dF" }, "source": [ - "Let's setup the optimizer and the `global_step` counter:" + "옵티마이저(optimizer)와 `global_step`을 설정합니다." ] }, { @@ -738,13 +738,13 @@ ] }, { - "cell_type": "markdown", + "cell_type": "raw", "metadata": { "colab_type": "text", "id": "pJVRZ0hP52ZB" }, "source": [ - "We'll use this to calculate a single optimization step:" + "이 값들을 단일 최적화 단계를 계산하기위해 사용합니다. " ] }, { @@ -775,18 +775,18 @@ "id": "7Y2VSELvwAvW" }, "source": [ - "### Training loop\n", + "### 훈련 루프\n", "\n", - "With all the pieces in place, the model is ready for training! A training loop feeds the dataset examples into the model to help it make better predictions. The following code block sets up these training steps:\n", + "모든 조각을 가지고, 모델은 학습할 준비가 되었습니다! 훈련 루프는 더 나은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 다음의 훈련 단계를 작성한 것입니다. \n", "\n", - "1. Iterate each *epoch*. An epoch is one pass through the dataset.\n", - "2. Within an epoch, iterate over each example in the training `Dataset` grabbing its *features* (`x`) and *label* (`y`).\n", - "3. Using the example's features, make a prediction and compare it with the label. Measure the inaccuracy of the prediction and use that to calculate the model's loss and gradients.\n", - "4. Use an `optimizer` to update the model's variables.\n", - "5. Keep track of some stats for visualization.\n", - "6. Repeat for each epoch.\n", + "1. 각 *에포크(epoch)* 반복. 에포크(epoch)는 데이터셋을 통과시키는 횟수입니다. \n", + "2. epoch내에서, `Dataset`의 *features* (`x`)와 *label* (`y`)를 가져오는 예제를 반복합니다.\n", + "3. 예제의 특성을 사용하여 결과를 예측을 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기위해 사용합니다. \n", + "4. 모델의 변수를 업데이트하기위해 `옵티마이저(optimizer)`를 사용합니다. \n", + "5. 시각화를 위해 몇가지 값을 추적합니다.\n", + "6. 각 epoch를 반복합니다.\n", "\n", - "The `num_epochs` variable is the number of times to loop over the dataset collection. Counter-intuitively, training a model longer does not guarantee a better model. `num_epochs` is a *[hyperparameter](https://developers.google.com/machine-learning/glossary/#hyperparameter)* that you can tune. Choosing the right number usually requires both experience and experimentation." + "`num_epochs` 변수는 데이터셋 반복 회수입니다. 반직관적으로, 모델을 길게 학습하는것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 여러분들이 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 회수를 선택하는것은 경험과 직관을 필요로 합니다. " ] }, { @@ -799,12 +799,12 @@ }, "outputs": [], "source": [ - "## Note: Rerunning this cell uses the same model variables\n", + "## Note: 이 셀을 다시 실행하면 동일한 모델의 변수가 사용됩니다.\n", "\n", "from tensorflow import contrib\n", "tfe = contrib.eager\n", "\n", - "# keep results for plotting\n", + "# 도식화를 위해 결과 저장\n", "train_loss_results = []\n", "train_accuracy_results = []\n", "\n", @@ -814,19 +814,19 @@ " epoch_loss_avg = tfe.metrics.Mean()\n", " epoch_accuracy = tfe.metrics.Accuracy()\n", "\n", - " # Training loop - using batches of 32\n", + " # 훈련 루프 - 32번의 배치 실행\n", " for x, y in train_dataset:\n", " # Optimize the model\n", " loss_value, grads = grad(model, x, y)\n", " optimizer.apply_gradients(zip(grads, model.trainable_variables),\n", " global_step)\n", "\n", - " # Track progress\n", - " epoch_loss_avg(loss_value) # add current batch loss\n", - " # compare predicted label to actual label\n", + " # 진행 상황 추적\n", + " epoch_loss_avg(loss_value) # 현재 배치의 손실 추가\n", + " # 예측된 레이블과 실제 레이블 비교\n", " epoch_accuracy(tf.argmax(model(x), axis=1, output_type=tf.int32), y)\n", "\n", - " # end epoch\n", + " # epoch 종료\n", " train_loss_results.append(epoch_loss_avg.result())\n", " train_accuracy_results.append(epoch_accuracy.result())\n", " \n", @@ -843,7 +843,7 @@ "id": "2FQHVUnm_rjw" }, "source": [ - "### Visualize the loss function over time" + "### 시간에 따른 손실함수 시각화" ] }, { @@ -853,9 +853,9 @@ "id": "j3wdbmtLVTyr" }, "source": [ - "While it's helpful to print out the model's training progress, it's often *more* helpful to see this progress. [TensorBoard](https://www.tensorflow.org/guide/summaries_and_tensorboard) is a nice visualization tool that is packaged with TensorFlow, but we can create basic charts using the `matplotlib` module.\n", + "모델의 훈련 과정을 출력하는 것은 도움이 되지만, 훈련 과정을 직접 보는 것이 더 도움이 되곤합니다. [TensorBoard](https://www.tensorflow.org/guide/summaries_and_tensorboard)는 텐서플로우에 패키지되어있는 굉장히 유용한 시각화 툴입니다. 하지만 우리는 `matplotlib` 모듈을 사용하여 일반적인 차트를 출력할 수 있습니다.\n", "\n", - "Interpreting these charts takes some experience, but you really want to see the *loss* go down and the *accuracy* go up." + "이 차트를 해석하는것은 여러 경험이 필요하지만, 우리는 *손실*이 내려가고 *정확도*가 올라가는 것을 보고싶습니다." ] }, { @@ -886,11 +886,11 @@ "id": "Zg8GoMZhLpGH" }, "source": [ - "## Evaluate the model's effectiveness\n", + "## 모델 유효성 검증\n", "\n", - "Now that the model is trained, we can get some statistics on its performance.\n", + "이제 모델은 학습되었습니다. 우리는 모델의 성능을 검증하기위해 몇가지 통계를 얻을 수 있습니다. \n", "\n", - "*Evaluating* means determining how effectively the model makes predictions. To determine the model's effectiveness at Iris classification, pass some sepal and petal measurements to the model and ask the model to predict what Iris species they represent. Then compare the model's prediction against the actual label. For example, a model that picked the correct species on half the input examples has an *[accuracy](https://developers.google.com/machine-learning/glossary/#accuracy)* of `0.5`. Figure 4 shows a slightly more effective model, getting 4 out of 5 predictions correct at 80% accuracy:\n", + "*평가(Evaluating)*는 모델이 예측을 얼마나 효과적으로 수행하는지 결정하는것을 의미합니다. 붓꽃 분류 모델의 유효성을 결정하기 위해서, 몇가지 꽃잎과 꽃받침 데이터를 통과시키고 어떠한 품종을 예측하는지 확인합니다. 그 후 실제 품종과 비교합니다. 예를 들어, 절반의 데이터를 올바르게 예측한 모델의 *[정확도](https://developers.google.com/machine-learning/glossary/#accuracy)* 는 `0.5`입니다. 그림 4는 조금 더 효과적인 보여줍니다. 5개의 예측 중 4개를 올바르게 예측한 80% 정확도의 모델입니다.\n", "\n", "\n", " \n", @@ -919,7 +919,7 @@ " \n", " \n", " \n", "
5.52.54.01.311
\n", - " Figure 4. An Iris classifier that is 80% accurate.
 \n", + " 그림 4. An Iris classifier that is 80% accurate.
 \n", "
" ] @@ -931,11 +931,11 @@ "id": "z-EvK7hGL0d8" }, "source": [ - "### Setup the test dataset\n", + "### 테스트 데이터셋 설정\n", "\n", - "Evaluating the model is similar to training the model. The biggest difference is the examples come from a separate *[test set](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* rather than the training set. To fairly assess a model's effectiveness, the examples used to evaluate a model must be different from the examples used to train the model.\n", + "모델을 평가하는것은 모델을 학습하는것과 유사합니다. 가장 큰 차이는 훈련 데이터가 아닌 *[테스트 데이터셋](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* 을 사용했다는 것입니다. 공정하게 모델의 유효성을 평가하기위해, 모델을 평가하기위한 예제는 반드시 훈련 데이터와 달라야합니다. \n", "\n", - "The setup for the test `Dataset` is similar to the setup for training `Dataset`. Download the CSV text file and parse that values, then give it a little shuffle:" + "테스트 데이터셋을 설정하는것은 훈련 데이터셋을 설정하는 것과 유사합니다. CSV 파일을 다운로드하고 값을 구분합니다. 그 후 약간의 셔플을 적용합니다." ] }, { @@ -982,9 +982,9 @@ "id": "HFuOKXJdMAdm" }, "source": [ - "### Evaluate the model on the test dataset\n", + "### 테스트 데이터셋을 사용한 모델 평가\n", "\n", - "Unlike the training stage, the model only evaluates a single [epoch](https://developers.google.com/machine-learning/glossary/#epoch) of the test data. In the following code cell, we iterate over each example in the test set and compare the model's prediction against the actual label. This is used to measure the model's accuracy across the entire test set." + "훈련 단계와는 다르게 모델은 테스트 데이터에 대해서 오직 한번의 [epoch](https://developers.google.com/machine-learning/glossary/#epoch)을 진행합니다. 다음의 코드셀은 테스트 셋을 반복하여 실행하고 실제 레이블과 비교합니다. 이는 전체 테스트 데이터셋에 대한 정확도를 측정하는데 사용됩니다." ] }, { @@ -1014,7 +1014,7 @@ "id": "HcKEZMtCOeK-" }, "source": [ - "We can see on the last batch, for example, the model is usually correct:" + "예를들어, 마지막 배치에서 모델이 일반적으로 정확하다는 것을 확인할 수 있습니다. " ] }, { @@ -1037,12 +1037,11 @@ "id": "7Li2r1tYvW7S" }, "source": [ - "## Use the trained model to make predictions\n", - "\n", - "We've trained a model and \"proven\" that it's good—but not perfect—at classifying Iris species. Now let's use the trained model to make some predictions on [unlabeled examples](https://developers.google.com/machine-learning/glossary/#unlabeled_example); that is, on examples that contain features but not a label.\n", + "## 예측을 위해 훈련 된 모델 사용하기\n", "\n", - "In real-life, the unlabeled examples could come from lots of different sources including apps, CSV files, and data feeds. For now, we're going to manually provide three unlabeled examples to predict their labels. Recall, the label numbers are mapped to a named representation as:\n", + "우리는 이제 붓꽃을 분류하기위해 완벽하지는 않지만 어느정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)들을 예측해봅시다.\n", "\n", + "실제로는 레이블되지 않은 예제들은 여러 소스(앱, CSV 파일, 직접제공 등)로 부터 제공될 수 있습니다. 지금은 레이블을 예측하기위해 수동으로 3개의 레이블되지 않은 예제를 제공하겠습니다. 레이블은 다음과 붓꽃이름으로 맵핑되어있습니다.\n", "* `0`: Iris setosa\n", "* `1`: Iris versicolor\n", "* `2`: Iris virginica" diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 89f6487d193..707b4f180c8 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -88,7 +88,7 @@ "source": [ "## 텐서플로우 임포트\n", "\n", - "시작하기 위해서 텐서플로우 모듈을 임포트하고 즉시실행을 활성화합니다. 즉시실행으로 텐서플로우에 대한 대화형 프론트엔드(frontend)가 가능합니다. 세부사항은 나중에 이야기할 것입니다." + "시작하기 위해서 텐서플로우 모듈을 임포트하고 즉시실행(eager execution)을 활성화합니다. 즉시실행 활성화로 텐서플로우에 대한 대화형 프론트엔드(frontend)가 가능합니다. 세부사항은 나중에 이야기할 것입니다." ] }, { @@ -108,7 +108,7 @@ ] }, { - "cell_type": "raw", + "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "H9UySOPLXdaw" @@ -116,7 +116,7 @@ "source": [ "## 텐서\n", "\n", - "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 형태를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로우는 텐서를 생성하고 계산하는 풍부한 연산자 라이브러리를 제공합니다. ([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.). 이러한 연산자들은 자동적으로 파이썬 타입을 전환합니다. 예를 들어:\n" + "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 형태를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로우는 텐서를 생성하고 계산하는 풍부한 연산 라이브러리를 제공합니다. ([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.). 이러한 연산자들은 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" ] }, { @@ -166,7 +166,7 @@ ] }, { - "cell_type": "raw", + "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "eBPw8e8vrsom" @@ -174,26 +174,26 @@ "source": [ "넘파이 배열과 텐서의 가장 확실한 차이는 다음과 같습니다:\n", "\n", - "1. 가속기 메모리(GPU, TPU와 같은)로 텐서를 뒷받침할 수 있습니다. \n", + "1. 텐서는 가속기 메모리(GPU, TPU와 같은)의 사용이 가능합니다.\n", "2. 텐서는 불변성(immutable)을 가집니다." ] }, { - "cell_type": "markdown", + "cell_type": "raw", "metadata": { "colab_type": "text", "id": "Dwi1tdW3JBw6" }, "source": [ - "### NumPy 적합성\n", + "### 넘파이 적합성\n", "\n", "Tensor와 ndarray사이의 전환은 다소 간단합니다.\n", "\n", - "* 텐서플로우 연산자는 자동적으로 Numpy ndarray를 Tensor로 전환합니다.\n", - "* 넘파이 연산자는 자동적으로 텐서플로우 텐서를 넘이파 ndarray로 전환합니다.\n", + "* 텐서플로우 연산는 자동적으로 넘파이 ndarray를 Tensor로 전환합니다.\n", + "* 넘파이 연산는 자동적으로 텐서플로우 Tensor를 넘파이 ndarray로 전환합니다.\n", "\n", - "텐서는 `.numpy()` 메소드(method)를 호출하여 Numpy ndarray로 전환할 수 있습니다.\n", - "가능한 경우, 텐서와 배열은 메모리 표현을 공유하기 때문에 이러한 전환은 일반적으로 간단(저렴)합니다. 그러나 텐서는 GPU 메모리에 저장될 수 있고, 넘파이 배열은 항상 호스트 메모리에 백업이 되므로, 이러한 전환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 포함됩니다." + "Tensor는 `.numpy()` 메소드(method)를 호출하여 넘파이 ndarray로 전환할 수 있습니다.\n", + "가능한 경우, Tensor와 ndarray은 메모리 표현을 공유하기 때문에 이러한 전환은 일반적으로 간단(저렴)합니다. 그러나 Tensor는 GPU 메모리에 저장될 수 있고, 넘파이 ndarray은 항상 호스트 메모리에 백업이 되므로, 이러한 전환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 포함됩니다." ] }, { @@ -223,15 +223,15 @@ ] }, { - "cell_type": "markdown", + "cell_type": "raw", "metadata": { "colab_type": "text", "id": "PBNP8yTRfu_X" }, "source": [ - "## GPU acceleration\n", + "## GPU 가속기\n", "\n", - "Many TensorFlow operations can be accelerated by using the GPU for computation. Without any annotations, TensorFlow automatically decides whether to use the GPU or CPU for an operation (and copies the tensor between CPU and GPU memory if necessary). Tensors produced by an operation are typically backed by the memory of the device on which the operation executed. For example:" + "많은 텐서플로우 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로우는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 CPU 와 GPU에 Tensor를 복사합니다.) 명령에 의해 생성된 Tensor는 전형적으로 명령이 실행된 장치의 메모리에 의해 실행됩니다. 예를들어:" ] }, { @@ -261,9 +261,9 @@ "id": "vpgYzgVXW2Ud" }, "source": [ - "### Device Names\n", + "### 장치 이름\n", "\n", - "The `Tensor.device` property provides a fully qualified string name of the device hosting the contents of the tensor. This name encodes many details, such as an identifier of the network address of the host on which this program is executing and the device within that host. This is required for distributed execution of a TensorFlow program. The string ends with `GPU:` if the tensor is placed on the `N`-th GPU on the host." + "`Tensor.device`는 Tensor를 구성하고 있는 호스트 장치의 풀네임을 제공합니다. 이러한 이름은 프로그램이 실행중인 호스트의 네트워크 주소 및 해당 호스트 내의 장치와 같은 많은 세부 정보를 인코딩하며, 이것은 텐서플로우 프로그램의 분산 실행에 필요합니다. Tensor가 호스트의 `N`번째 GPU에 놓여지면 문자열은 `GPU:` 끝납니다." ] }, { @@ -275,9 +275,9 @@ "source": [ "\n", "\n", - "### Explicit Device Placement\n", + "### 명시적 장치 배치\n", "\n", - "The term \"placement\" in TensorFlow refers to how individual operations are assigned (placed on) a device for execution. As mentioned above, when there is no explicit guidance provided, TensorFlow automatically decides which device to execute an operation, and copies Tensors to that device if needed. However, TensorFlow operations can be explicitly placed on specific devices using the `tf.device` context manager. For example:" + "텐서플로우에서 \"배치\"라는 용어는 개별 명령이 실행을 위해 장치를 할당(배치)하는 방법을 나타냅니다. 앞서 언급되었듯이, 명시적 지침이 없을경우 텐서플로우는 명령을 실행하기위한 장치를 자동으로 결정하고, 필요시 Tensor를 장치에 복사합니다. 그러나 텐서플로우 명령은 `tf.device`을 사용하여 명시적으로 배치할 수 있습니다. 예를 들어:" ] }, { @@ -324,18 +324,18 @@ "id": "o1K4dlhhHtQj" }, "source": [ - "## Datasets\n", + "## 데이터셋\n", "\n", - "This section demonstrates the use of the [`tf.data.Dataset` API](https://www.tensorflow.org/guide/datasets) to build pipelines to feed data to your model. It covers:\n", + "이번 섹션에서는 모델에 데이터를 제공하기위한 파이프라인을 구축하기 위해 [`tf.data.Dataset` API](https://www.tensorflow.org/guide/datasets)를 시연해볼 것입니다. 이는 다음을 포함합니다.\n", "\n", - "* Creating a `Dataset`.\n", - "* Iteration over a `Dataset` with eager execution enabled.\n", + "* `Dataset` 생성.\n", + "* 즉시실행(eager execution) 활성화와 `Dataset`을 통한 반복\n", "\n", - "We recommend using the `Dataset`s API for building performant, complex input pipelines from simple, re-usable pieces that will feed your model's training or evaluation loops.\n", + "모델을 학습시키고, 평가 루프를 제공할 간단하고 재사용 가능한 조각으로부터 복잡한 입력 파이프라인을 구축하기위해 `Dataset`s API를 사용하기를 권장합니다. \n", "\n", - "If you're familiar with TensorFlow graphs, the API for constructing the `Dataset` object remains exactly the same when eager execution is enabled, but the process of iterating over elements of the dataset is slightly simpler.\n", - "You can use Python iteration over the `tf.data.Dataset` object and do not need to explicitly create an `tf.data.Iterator` object.\n", - "As a result, the discussion on iterators in the [TensorFlow Guide](https://www.tensorflow.org/guide/datasets) is not relevant when eager execution is enabled." + "만약 텐서플로우 그래프에 익숙하다면, `Dataset` 객체를 생성하기 위한 API는 즉시실행이 활성화 되어도 동일하게 유지됩니다. 하지만 그러나 데이터셋의 요소를 반복하는 프로세스는 약간 더 간단합니다.\n", + "또한 `tf.data.Dataset` 객체를 통하여 파이썬 반복문을 사용할 수 있으며, 명시적으로 `tf.data.Iterator` 객체를 생성할 필요가 없습니다.\n", + "그 결과, [TensorFlow Guide](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시실행이 활성화될 때에는 관계없습니다. " ] }, { @@ -345,9 +345,9 @@ "id": "zI0fmOynH-Ne" }, "source": [ - "### Create a source `Dataset`\n", + "### `Dataset`소스 생성\n", "\n", - "Create a _source_ dataset using one of the factory functions like [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices) or using objects that read from files like [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) or [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset). See the [TensorFlow Guide](https://www.tensorflow.org/guide/datasets#reading_input_data) for more information." + "굉장히 유용한 함수중 하나인 [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices)를 사용하여 데이터셋 소스를 생성하거나 or 파일로부터 읽어들이는 객체인 [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) 또는 [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset)를 사용하여 데이터셋 소스를 생성하십시오. 더 많은 정보는 [TensorFlow Guide](https://www.tensorflow.org/guide/datasets#reading_input_data) 를 참조하세요." ] }, { @@ -382,9 +382,9 @@ "id": "vbxIhC-5IPdf" }, "source": [ - "### Apply transformations\n", + "### 변환 적용\n", "\n", - "Use the transformations functions like [`map`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`batch`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`shuffle`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle) etc. to apply transformations to the records of the dataset. See the [API documentation for `tf.data.Dataset`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset) for details." + "[`map`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`batch`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`shuffle`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle)와 같은 변환 함수를 사용하세요. 또한 데이터셋의 레코드에 변환을 적용하세요. 세부사항은 [API documentation for `tf.data.Dataset`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)을 참조하세요." ] }, { @@ -409,10 +409,9 @@ "id": "A8X1GNfoIZKJ" }, "source": [ - "### Iterate\n", + "### 반복\n", "\n", - "When eager execution is enabled `Dataset` objects support iteration.\n", - "If you're familiar with the use of `Dataset`s in TensorFlow graphs, note that there is no need for calls to `Dataset.make_one_shot_iterator()` or `get_next()` calls." + "즉시실행이 활성화되면 `Dataset` 객체는 반복을 지원합니다. 만약 텐서플로우 그래프에서 `Dataset`을 사용하는게 익숙하다면, `Dataset.make_one_shot_iterator()` 또는 `get_next()`와 같은 객체를 호출할 필요가 없는다는 것에 주목하세요." ] }, { diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md index 9c28180b352..d78212b1af4 100644 --- a/site/ko/tutorials/eager/index.md +++ b/site/ko/tutorials/eager/index.md @@ -1,13 +1,21 @@ -# Research and experimentation +# 연구 및 실험 -Eager execution provides an imperative, define-by-run interface for advanced -operations. Write custom layers, forward passes, and training loops with -auto differentiation. Start with these notebooks, then read the +이 문서들은 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도 +불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다. +이 번역에 개선할 부분이 있다면 +[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다. +문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을 +작성하거나 +[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로 +메일을 보내주시기 바랍니다. + +즉시실행(Eager execution)은 더 나은 연산을 위한 실행에 의해 정의되는 명령형 인터페이스를 제공합니다. +사용자 정의 레이어, 정방향 전파, 자동미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 시작한 다음 순서대로 진행하세요. [eager execution guide](../../guide/eager). -1. [Eager execution](eager_basics.ipynb) +1. [즉시실행(Eager execution)](eager_basics.ipynb) 2. [Automatic differentiation and gradient tape](automatic_differentiation.ipynb) -3. [Custom training: basics](custom_training.ipynb) -4. [Custom layers](custom_layers.ipynb) -5. [Custom training: walkthrough](custom_training_walkthrough.ipynb) +3. [사용자 정의 학습 : 기본(Custom training: basics)](custom_training.ipynb) +4. [사용자 정의 레이어(Custom layers)](custom_layers.ipynb) +5. [사용자 정의 학습 : walkthrough(Custom training: walkthrough)](custom_training_walkthrough.ipynb) From 36b87943cde0a01140da25ce208d22daf6bf93c1 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Mon, 1 Apr 2019 14:16:24 +0900 Subject: [PATCH 04/19] Update from 9cdb7f90 --- .../eager/automatic_differentiation.ipynb | 13 ++-- site/ko/tutorials/eager/custom_layers.ipynb | 20 +++--- site/ko/tutorials/eager/custom_training.ipynb | 12 ++-- .../eager/custom_training_walkthrough.ipynb | 61 +++++++++---------- site/ko/tutorials/eager/eager_basics.ipynb | 32 +++++----- 5 files changed, 67 insertions(+), 71 deletions(-) diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index de7ea83a46b..857cbc3d65d 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -41,7 +41,7 @@ "id": "xh8WkEwWpnm7" }, "source": [ - "# 자동미분(Automatic differentiation) 과 그래디언트 테이프" + "# 자동미분(Automatic Differentiation)과 그래디언트 테이프(Gradient Tape)" ] }, { @@ -71,7 +71,7 @@ "id": "vDJ4XzMqodTy" }, "source": [ - "이전 튜토리얼에서 우리는 Tensor와 Tensor의 연산들에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술인 [자동미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." + "이전 튜토리얼에서 우리는 Tensor와 Tensor의 연산들에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술 중 하나인 [자동미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." ] }, { @@ -108,7 +108,7 @@ "source": [ "## 그래디언트 테이프(Gradient Tape)\n", "\n", - "텐서플로우는 자동미분(주어진 입력 변수에 따른 기울기 연산)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape`는 안에서 실행된 모든 연산을 tape에 \"기록\"합니다. 그리고 [역방향 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 기록된 연산의 그래디언트를 계산하기 위해 각각의 기록된 연산들과 관련된 테이프와 그래디언트들을 사용합니다. \n", + "텐서플로우는 자동미분(주어진 입력 변수에 따른 그래디언트 연산)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape`는 안에서 실행된 모든 연산을 tape에 \"기록\"합니다. 그리고 [역방향 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 각각의 기록된 연산들과 관련된 테이프와 그래디언트들을 사용하여 기록된 연산의 그래디언트를 계산합니다. \n", "\n", "예를 들면:" ] @@ -165,7 +165,6 @@ " z = tf.multiply(y, y)\n", "\n", "# 중간값 y에 관한 z의 도함수 계산을 위한 테이프 사용\n", - "# intermediate value y.\n", "dz_dy = t.gradient(z, y)\n", "assert dz_dy.numpy() == 8.0" ] @@ -209,7 +208,7 @@ "source": [ "### 제어흐름(Control Flow) 기록\n", "\n", - "테이프가 실행되는데로 연산을 기록하기 때문에, 파이썬 제어흐름(예를 들어 `if` `while`, `for`문 같은)은 자연스럽게 처리됩니다. " + "테이프를 실행하는 순간부터 연산을 기록하기 때문에, 파이썬 제어흐름(예를 들어 `if` `while`, `for`문 같은)은 자연스럽게 처리됩니다. " ] }, { @@ -287,7 +286,7 @@ "source": [ "## 다음 단계\n", "\n", - "이번 튜토리얼에서는 텐서플로우에서 그래디언트 계산법을 배웠습니다. 이를 통해 우리는 신경망을 구축하고 훈련시키는 데 필요한 기본 요소를 충분히 확보 할 수 있습니다." + "이번 튜토리얼에서는 텐서플로우에서 그래디언트 계산법을 배웠습니다. 이를 통해 우리는 신경망을 구축하고 훈련시키는 데 필요한 기본 요소를 충분히 확보할 수 있습니다." ] } ], @@ -315,7 +314,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index 97091da1efb..e57583018b7 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -102,7 +102,7 @@ "\n", "많은 머신러닝 모델은 비교적 단순한 레이어의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로우는 여러 표준 레이어 세트를 제공하므로 사용자 고유의 응용 프로그램에 관련된 레이어를 처음부터 작성하거나, 기존 레이어의 구성으로 쉽게 작성할 수 있습니다.\n", "\n", - "텐서플로우는 [Keras](https://keras.io) API 의 풀페키지를 tf.keras package에 포함하고 있습니다. Keras 레이어는 모델을 구축하는데 매우 유용합니다." + "텐서플로우는 [Keras](https://keras.io) API 의 풀패키지를 tf.keras package에 포함하고 있습니다. Keras 레이어는 모델을 구축하는데 매우 유용합니다." ] }, { @@ -186,11 +186,11 @@ "source": [ "## 사용자 정의 레이어 구현\n", "사용자 정의 레이어를 구현하는 가장 좋은 방법은 tf.keras.Layer 클래스를 상속하고 다음과 같이 구현하는 것입니다.\n", - " * `__init__` , 여기서 모든 입력 독립적인 초기화를 할 수 있습니다.\n", - " * `build`, 입력 텐서의 형태를 알고 나머지를 초기화 할 수 있습니다.\n", + " * `__init__` , 모든 독립적인 입력값을 초기화를 할 수 있습니다.\n", + " * `build`, 입력 Tensor의 형태를 알고 나머지를 초기화 할 수 있습니다.\n", " * `call`, 정방향 계산을 진행 할 수 있습니다.\n", "\n", - "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 레이어가 작동할 입력의 형태를 기준으로 나중에 변수를 만들 수 있습니다. 반면에, `__init__`에 변수를 생성하는것은 변수 생성에 필요한 형태가 명시적으로 지정되어야 함을 의미합니다.변수를 생성하는 데 필요한 모양이 명시적으로 지정되어야 함을 의미합니다." + "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 레이어가 작동할 입력의 형태를 기준으로 나중에 변수를 만들 수 있습니다. 반면에, `__init__`에 변수를 생성하는것은 변수 생성에 필요한 형태가 명시적으로 지정되어야 함을 의미합니다." ] }, { @@ -230,7 +230,7 @@ "source": [ "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. \n", "\n", - "다른 독자가 표준 레이어의 동작을 잘 알고 있기 때문에, 가능한 경우 표준 레이어를 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers, tf.keras.layers 또는 tf.contrib.layers에 없는 레이어를 사용하기 원하면 [github issue](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀리퀘스트를 요청하세요." + "다른 독자가 표준 레이어의 동작을 잘 알고 있기 때문에, 가능한 경우 표준 레이어를 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers 또는 tf.contrib.layers에 없는 레이어를 사용하기 원하면 [github issue](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀리퀘스트를 요청하세요." ] }, { @@ -242,9 +242,9 @@ "source": [ "## 모델: 레이어 구성\n", "\n", - "머신러닝 모델에서 많은 흥미로운 유사 레이어(layer-likely)는 레이어들의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 residual block은 합성곱(convolution), 배치정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", + "머신러닝 모델에서 대부분의 흥미로운 유사 레이어(layer-likely)는 레이어들의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 잔여블록(residual block)은 합성곱(convolution), 배치정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", "\n", - "레이어 집합을 포함한 유사 레이어를 생성하기위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(Inheritance)하여 구현합니다." + "레이어 집합을 포함한 유사 레이어를 생성하기위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현합니다." ] }, { @@ -313,7 +313,7 @@ ] }, { - "cell_type": "raw", + "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "c5YwYcnuK-wc" @@ -321,7 +321,7 @@ "source": [ "# 다음 단계\n", "\n", - "이제 여러분들은 이전 노트북으로 돌아가서 선형 회귀 예제에 레이어와 모델을 적용하여 좀 더 나은 구조를 만들 수 있습니다." + "이제 여러분들은 이전 노트북으로 돌아가서 선형 회귀 예제에 좀 더 나은 구조를 만들기 위해 레이어와 모델을 적용할 수 있습니다." ] } ], @@ -349,7 +349,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/custom_training.ipynb b/site/ko/tutorials/eager/custom_training.ipynb index 56c0ab00fa9..05b1c35e536 100644 --- a/site/ko/tutorials/eager/custom_training.ipynb +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -41,7 +41,7 @@ "id": "hrXv0rU9sIma" }, "source": [ - "# 사용자 지정 학습: 기초" + "# 사용자 정의 학습: 기초" ] }, { @@ -200,7 +200,7 @@ "3. 훈련 데이터 가져오기\n", "4. 훈련 데이터를 통한 실행, 데이터에 최적화하기 위한 \"옵티마이저(optimizer)\" 사용한 변수 조정\n", "\n", - "이번 튜토리얼에서는 선형모델의 간단한 예제를 살펴보겠습니다. `f(x) = x * W + b`, `W` and `b` 두 변수를 가지고 있는 선형모델입니다. 더욱이 잘 학습된 모델이 `W = 3.0` and `b = 2.0`의 값을 갖도록 데이터를 합성할 것입니다." + "이번 튜토리얼에서는 선형모델의 간단한 예제를 살펴보겠습니다. `f(x) = x * W + b`, 위 모델은 `W` 와 `b` 두 변수를 가지고 있는 선형모델이며, 잘 학습된 모델이 `W = 3.0` and `b = 2.0`의 값을 갖도록 데이터를 합성할 것입니다." ] }, { @@ -249,7 +249,7 @@ "source": [ "### 손실 함수 정의\n", "\n", - "손실 함수는 주어진 입력에 대한 모델의 출력이 원하는 출력과 얼마나 잘 일치하는지 측정합니다. L2 규제항(regularization)을 적용한 손실 함수를 사용하겠습니다." + "손실 함수는 주어진 입력에 대한 모델의 출력이 원하는 출력과 얼마나 잘 일치하는지를 측정합니다. L2 규제항(regularization)을 적용한 손실 함수를 사용하겠습니다." ] }, { @@ -354,7 +354,7 @@ "source": [ "### 훈련 루프 정의\n", "\n", - "현재 우리는 네트워크와 훈련 데이터를 가지고 있습니다. 모델의 변수(`W` 와 `b`)를 업데이트하기 위해 훈련 데이터를 사용하여 훈련시킵니다. 그리고 [gradient descent](https://en.wikipedia.org/wiki/Gradient_descent)를 사용하여 손실을 감소시킵니다. 경사하강에는 여러가지 방법이 있으며, `tf.train.Optimizer` 에 구현되어있습니다. 이러한 구현을 사용하는것을 강력히 추천드립니다. 그러나 이번 튜토리얼에서는 기본적인 방법을 사용하겠습니다." + "현재 우리는 네트워크와 훈련 데이터를 가지고 있습니다. 모델의 변수(`W` 와 `b`)를 업데이트하기 위해 훈련 데이터를 사용하여 훈련시킵니다. 그리고 [경사하강(gradient descent)](https://en.wikipedia.org/wiki/Gradient_descent)를 사용하여 손실을 감소시킵니다. 경사하강에는 여러가지 방법이 있으며, `tf.train.Optimizer` 에 구현되어있습니다. 이러한 구현을 사용하는것을 강력히 추천드립니다. 그러나 이번 튜토리얼에서는 기본적인 방법을 사용하겠습니다." ] }, { @@ -397,7 +397,7 @@ "source": [ "model = Model()\n", "\n", - "# Collect the history of W-values and b-values to plot later\n", + "# 도식화를 위해 W값과 b값들의 변화를 저장합니다.\n", "Ws, bs = [], []\n", "epochs = range(10)\n", "for epoch in epochs:\n", @@ -458,7 +458,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index cc5f9e4f43a..7f2e6e9ae25 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -80,7 +80,7 @@ "\n", "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로우의 개념들을 사용합니다.\n", "\n", - "* 즉시실행([eager execution])(https://www.tensorflow.org/guide/eager) 개발환경,\n", + "* [즉시실행(eager execution)](https://www.tensorflow.org/guide/eager) 개발환경,\n", "* [Datasets API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 불러오기,\n", "* [Keras API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 레이어(layer) 구축 .\n", "\n", @@ -112,7 +112,7 @@ "source": [ "### 임포트 및 즉시실행 구성\n", "\n", - "텐서플로우를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시실행을 활성화할 것입니다. 즉시실행은 텐서플로우가 나중에 실행되는 [computational graph](https://www.tensorflow.org/guide/graphs)를 만드는데신, 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", + "텐서플로우를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시실행을 활성화할 것입니다. 즉시실행은 텐서플로우가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는데신, 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", "\n", "즉시실행이 활성화 될때, 동일한 프로그램내에서는 비활성화를 할 수 없습니다. 더 많은 세부사항은 [eager execution guide](https://www.tensorflow.org/guide/eager)을 참조하세요." ] @@ -149,7 +149,7 @@ "source": [ "## 붓꽃 분류 문제\n", "\n", - "당신이 식물학자라고 상상하고, 주어진 붓꽃을 자동적으로 분류하는 방법을 찾고있다고 가정합시다. 머신러닝은 통계적으로 꽃을 분류할 수 있는 다양한 알고리즘을 제공합니다. 예를 들어, 정교한 머신러닝 프로그램은 사진을 통해 꽃을 분류할 수 있습니다. 우리의 목적은 좀 더 겸손하게 측정된 [꽃받침](https://en.wikipedia.org/wiki/Sepal)과 [꽃잎](https://en.wikipedia.org/wiki/Petal)의 길이와 폭을 토대로 붓꽃을 분류하는것입니다.\n", + "당신이 식물학자라고 상상하고, 주어진 붓꽃을 자동적으로 분류하는 방법을 찾고있다고 가정합시다. 머신러닝은 통계적으로 꽃을 분류할 수 있는 다양한 알고리즘을 제공합니다. 예를 들어, 정교한 머신러닝 프로그램은 사진을 통해 꽃을 분류할 수 있습니다. 우리의 목적은 좀 더 겸손하게, 측정된 [꽃받침](https://en.wikipedia.org/wiki/Sepal)과 [꽃잎](https://en.wikipedia.org/wiki/Petal)의 길이와 폭을 토대로 붓꽃을 분류하는것입니다.\n", "\n", "이 붓꽃은 약 300종 입니다. 하지만 이번 튜토리얼에서는 오직 3가지 품종을 기준으로 분류할 것입니다. \n", "\n", @@ -163,11 +163,11 @@ " alt=\"Petal geometry compared for three iris species: Iris setosa, Iris virginica, and Iris versicolor\">\n", " \n", " \n", - " Figure 1. Iris setosa (by Radomil, CC BY-SA 3.0), Iris versicolor, (by Dlanglois, CC BY-SA 3.0), and Iris virginica (by Frank Mayfield, CC BY-SA 2.0).
 \n", + " 그림 1. Iris setosa (by Radomil, CC BY-SA 3.0), Iris versicolor, (by Dlanglois, CC BY-SA 3.0), and Iris virginica (by Frank Mayfield, CC BY-SA 2.0).
 \n", " \n", "\n", "\n", - "다행이도 다른사람들이 먼저 꽃받침과 꽃임이 측정된 [120개의 붓꽃 데이터](https://en.wikipedia.org/wiki/Iris_flower_data_set)를 만들어 놓았습니다. 이것은 머신러닝 분류문제에 있어 초보자에게 유명한 고전 데이터셋입니다. " + "다행히도 다른사람들이 먼저 꽃받침과 꽃잎의 길이와 폭이 측정된 [120개의 붓꽃 데이터](https://en.wikipedia.org/wiki/Iris_flower_data_set)를 만들어 놓았습니다. 이것은 머신러닝 분류문제에 있어 초보자들에게 유명한 고전 데이터셋입니다. " ] }, { @@ -239,9 +239,9 @@ "처음 5개의 데이터로부터 다음을 주목하세요.\n", "\n", "1. 첫번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", - " * 총 120개의 예가 있다. 각 예들은 4가지의 특성(feature)을 가지며 3가지 가능한 레이블(label)을 가지고 있습니다.\n", + " * 총 120개의 예가 있으며, 각 예들은 4가지의 특성(feature), 3가지 가능한 레이블(label)을 가지고 있다.\n", "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[예](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", - " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 예제의 특징을 나타냅니다. 이 필드는 붓꽃의 측정값을 나타내는 부동소수점을 나타냅니다.\n", + " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 예제의 특징을 나타냅니다. 이 필드들는 붓꽃의 측정값을 부동소수점으로 나타냅니다.\n", " * 마지막 컬럼(column)은 *[레이블(label)](https://developers.google.com/machine-learning/glossary/#label)*입니다.: 레이블은 우리가 에측하고자 하는 값을 나타냅니다. 이 데이터셋에서는 꽃의 이름과 관련된 정수값 0, 1, 2를 나타냅니다.\n", "\n", "코드로 표현하면 다음과 같습니다.:" @@ -257,7 +257,7 @@ }, "outputs": [], "source": [ - "# column order in CSV file\n", + "# CSV파일내에서 컬럼의 순서\n", "column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']\n", "\n", "feature_names = column_names[:-1]\n", @@ -280,7 +280,7 @@ "* `1`: Iris versicolor\n", "* `2`: Iris virginica\n", "\n", - "특성과 레이블에 관한 더 많은 정보를 위해서 다음을 참조하세요. [ML Terminology section of the Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/framing/ml-terminology)." + "특성과 레이블에 관한 더 많은 정보를 위해서는 다음을 참조하세요. [ML Terminology section of the Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/framing/ml-terminology)." ] }, { @@ -308,7 +308,7 @@ "텐서플로우의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위한 많은 케이스를 다룹니다. 이는 훈련을 위한 형태로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 다음을 참조하세요. [Datasets Quick Start guide](https://www.tensorflow.org/get_started/datasets_quickstart) \n", "\n", "\n", - "데이터셋이 CSV 형태의 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 배치 사이즈[batch_size](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." + "데이터셋이 CSV 형태의 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 [배치 사이즈(batch_size)](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." ] }, { @@ -338,9 +338,8 @@ "id": "gB_RSn62c-3G" }, "source": [ - "`make_csv_dataset` 함수는 `tf.data.Dataset` 의 `(features, label)` 쌍을 반환합니다., where \n", - "`features` 가 사전형 객체인: `{'feature_name': value}`로 주어집니다.\n", - "즉시실행 활성화로 이 `Dataset`은 반복가능합니다. 특성(feature)을 살펴봅시다." + "`make_csv_dataset` 함수는 `tf.data.Dataset` 의 `(features, label)` 쌍을 반환합니다. `features`는 사전형 객체인: `{'feature_name': value}`로 주어집니다.\n", + "또한 즉시실행 활성화로 이 `Dataset`은 반복가능합니다. 다음은 특성(feature)들을 살펴봅시다." ] }, { @@ -396,7 +395,7 @@ "id": "YlxpSyHlhT6M" }, "source": [ - "모델 구축단계를 단순화하기 위해서, 특성 사전 객체를 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", + "모델 구축단계를 단순화하기 위해서, 특성(사전형 객체)을 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", "\n", "이 함수는 `Tensor`의 list로부터 값을 취하고 특정한 차원으로 결합된 `Tensor`를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메소드(method)를 사용합니다." ] @@ -478,11 +477,11 @@ "\n", " *[모델](https://developers.google.com/machine-learning/crash-course/glossary#model)*은 특성(feature)들과 레이블(label)과의 관계입니다. 붓꽃 분류 문제에서 모델은 측정된 꽃받침과 꽃잎 사이의 관계를 정의하고 붓꽃의 품종을 예측합니다. 몇가지 간단한 모델은 몇 줄의 대수학으로 표현할 수 있으나, 복잡한 머신러닝 모델은 요약하기 힘든 굉장히 많은 수의 매개변수를 가지고 있습니다.\n", "\n", - "머신러닝을 사용하지 않고 4가지의 특성사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 아마 여러분들이 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문들)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 여러분들을 위한 모델을 결정합니다. 만약 여러분들이 충분한 예제를 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 여러분들을 위한 특성들간의 관계를 이해합니다. \n", + "머신러닝을 사용하지 않고 4가지의 특성 사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 여러분들이 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문들)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 여러분들을 위한 모델을 결정합니다. 만약 여러분들이 충분한 예제를 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 여러분들을 위한 특성들 사이의 관계를 이해하고 제공합니다. \n", "\n", "### 모델 선정\n", "\n", - "우리는 학습을 위한 모델의 종류를 선정해야합니다. 여러정류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡환 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*들로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[dense(또는 fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전연결 신경망(fully-connected neural network)는 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전연결 신경망입니다. \n", + "우리는 학습을 위한 모델의 종류를 선정해야합니다. 여러정류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*들로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[dense(또는 fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전연결 신경망입니다. \n", "\n", "\n", " \n", "
\n", @@ -494,7 +493,7 @@ "
\n", "\n", - "그림 2의 모델이 훈련되고 레이블 되어있지 않은 데이터를 제공했을때, 모델은 주어진 데이터의 3가지 예측을 출력(주어진 레이블의 개수)합니다. 이러한 예측은 *[추론(inference)](https://developers.google.com/machine-learning/crash-course/glossary#inference)*이라고 정의합니다. 이 예제에서 출력의 합은 1.0입니다. 그림 2에서 예측은 `0.02` for *Iris setosa*, `0.95` for *Iris versicolor*, `0.03` for *Iris virginica*로 주어집니다. 이는 모델이 95%의 확률로 주어진 데이터를 *Iris versicolor*로 예측한다는 것을 의미합니다. " + "그림 2의 모델이 훈련되고 레이블 되어있지 않은 데이터를 제공했을때, 모델은 주어진 데이터의 3가지 예측을 출력(주어진 레이블의 개수)합니다. 이러한 예측은 *[추론(inference)](https://developers.google.com/machine-learning/crash-course/glossary#inference)*이라고 정의합니다. 이 예제에서 출력의 합은 1.0입니다. 그림 2에서 예측은 *Iris setosa* `0.02`, *Iris versicolor* `0.95`, *Iris virginica*에 `0.03`로 주어집니다. 이는 모델이 95%의 확률로 주어진 데이터를 *Iris versicolor*로 예측한다는 것을 의미합니다. " ] }, { @@ -506,7 +505,7 @@ "source": [ "### Keras를 사용한 모델 생성\n", "\n", - "텐서플로우의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 레이어를 생성하기위한 풍부한 라이브러리를 가지고있습니다. 이는 연결되있는 모든것들을 케라스가 처리하여 모델의 구축하기 쉽게 만듭니다.\n", + "텐서플로우의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 레이어를 생성하기위한 풍부한 라이브러리를 제공합니다. 이는 연결되있는 모든것들을 케라스가 처리하여 모델을 구축하기 쉽게 만듭니다.\n", "\n", "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 레이어의 선형 적층 모델입니다. 이 구조는 레이어의 인스턴스를 취하며, 아래의 케이스의 경우 각 레이어당 10개의 노드(node)를 가지는 2개의 [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense) 레이어와 3개의 예측(레이블의 개수)노드를 가지는 출력 레이어로 구성되어있습니다. 첫번째 레이어의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." ] @@ -624,9 +623,9 @@ "source": [ "## 모델 훈련하기\n", "\n", - "*[훈련 단계](https://developers.google.com/machine-learning/crash-course/glossary#training)*는 모델이 점진적으로 최적화되거나 데이터셋을 학습하는 머신러닝의 과정입니다. 훈련의 목적은 미지의 데이터를 예측하기위해, 훈련 데이터셋의 구조에 대해서 충분히 학습하는것 입니다. 만약 모델이 훈련 데이터셋에 대해서 과하게 학습된다면, 오직 훈련 데이터셋에 대해서 작동할 것이며, 일반화되기 힘들것입니다. 이러한 문제를 *[overfitting](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)* 이라고 합니다. 이는 마치 문제를 이해하고 해결한다기 보다는 답을 기억하는 것이라고 생각할 수 있습니다. \n", + "*[훈련 단계](https://developers.google.com/machine-learning/crash-course/glossary#training)*는 모델이 점진적으로 최적화되거나 데이터셋을 학습하는 머신러닝의 과정입니다. 훈련의 목적은 미지의 데이터를 예측하기 위해, 훈련 데이터셋의 구조에 대해서 충분히 학습하는 것입니다. 만약 모델이 훈련 데이터셋에 대해서 과하게 학습된다면, 오직 훈련 데이터셋에 대해서 작동할 것이며, 일반화되기 힘들 것입니다. 이러한 문제를 *[과대적합(overfitting)](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)* 이라고 합니다. 이는 마치 문제를 이해하고 해결한다기보다는 답을 기억하는 것이라고 생각할 수 있습니다. \n", "\n", - "붓꽃 분류 문제는 지도학습 *[지도학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도 학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고있지않습니다. 대신에 모델은 특성들의 패턴을 찾습니다. " + "붓꽃 분류 문제는 지도학습 *[지도학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시 중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고 있지않습니다. 대신에 모델은 특성들의 패턴을 찾습니다. " ] }, { @@ -640,7 +639,7 @@ "\n", "훈련과 평가단계는 모델의 *[손실(loss)](https://developers.google.com/machine-learning/crash-course/glossary#loss)* 계산할 필요가 있습니다. 손실은 모델의 예측이 원하는 레이블과 얼마나 일치하는지, 또한 모델이 잘 작동하는지에 대한 척도로 사용됩니다. 우리는 이 값은 최소화하고, 최적화하기를 원합니다. \n", "\n", - "모델의 손실은 [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) 함수를 사용하여 계산할 것입니다. 이 함수는 모델의 클래스(레이블)과 예측된 값(logit)을 입력받아 예제를 통한 평균 손실을 반환합니다." + "모델의 손실은 [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) 함수를 사용하여 계산할 것입니다. 이 함수는 모델의 클래스(레이블)과 예측된 값(로짓)을 입력받아 예제를 통한 평균 손실을 반환합니다." ] }, { @@ -695,9 +694,9 @@ "id": "lOxFimtlKruu" }, "source": [ - "### Optimizer 생성 \n", + "### 옵티마이저(Optimizer) 생성 \n", "\n", - "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 `손실`함수를 최소화하기위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 우리는 이 함수의 최저점을 찾고자합니다. The gradients point in the direction of steepest ascent—so we'll travel the opposite way and move down the hill. By iteratively calculating the loss and gradient for each batch, we'll adjust the model during training. Gradually, the model will find the best combination of weights and bias to minimize loss. And the lower the loss, the better the model's predictions.\n", + "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 `손실`함수를 최소화하기위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 우리는 이 함수의 최저점을 찾고자합니다. 그래디언트는 가장 가파른 상승방향을 가르키며 따라서 우리는 반대방향으로 이동하는 여행을 합니다.각 배치마다의 손실과 기울기를 반복적으로 계산하여 훈련 중에 모델을 조정합니다. 점진적으로, 모델은 손실을 최소화하기위해 가중치(weight)와 편향(bias)의 최적의 조합을 찾아냅니다. 더 적은 손실을 통해 더 좋은 모델의 예측을 기대할 수 있습니다. \n", "\n", "\n", " \n", " \n", "
\n", @@ -705,7 +704,7 @@ " alt=\"Optimization algorithms visualized over time in 3D space.\">\n", "
\n", - " Figure 3. Optimization algorithms visualized over time in 3D space.
(Source: Stanford class CS231n, MIT License, Image credit: Alec Radford)\n", + " 그림 3. Optimization algorithms visualized over time in 3D space.
(Source: Stanford class CS231n, MIT License, Image credit: Alec Radford)\n", "
\n", "\n", @@ -777,16 +776,16 @@ "source": [ "### 훈련 루프\n", "\n", - "모든 조각을 가지고, 모델은 학습할 준비가 되었습니다! 훈련 루프는 더 나은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 다음의 훈련 단계를 작성한 것입니다. \n", + "모든 조각을 가지고, 모델은 학습할 준비가 되었습니다! 훈련 루프는 더 나은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 아래의 훈련 단계를 작성한 것입니다. \n", "\n", - "1. 각 *에포크(epoch)* 반복. 에포크(epoch)는 데이터셋을 통과시키는 횟수입니다. \n", - "2. epoch내에서, `Dataset`의 *features* (`x`)와 *label* (`y`)를 가져오는 예제를 반복합니다.\n", + "1. 각 *에포크(epoch)* 반복. 에포크는 데이터셋을 통과시키는 횟수입니다. \n", + "2. 에포크내에서, `Dataset`의 *features* (`x`)와 *label* (`y`)를 가져오는 예제를 반복합니다.\n", "3. 예제의 특성을 사용하여 결과를 예측을 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기위해 사용합니다. \n", "4. 모델의 변수를 업데이트하기위해 `옵티마이저(optimizer)`를 사용합니다. \n", "5. 시각화를 위해 몇가지 값을 추적합니다.\n", - "6. 각 epoch를 반복합니다.\n", + "6. 각 에포크를 반복합니다.\n", "\n", - "`num_epochs` 변수는 데이터셋 반복 회수입니다. 반직관적으로, 모델을 길게 학습하는것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 여러분들이 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 회수를 선택하는것은 경험과 직관을 필요로 합니다. " + "`num_epochs` 변수는 데이터셋 반복 횟수입니다. 반직관적으로, 모델을 길게 학습하는것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 여러분들이 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는것은 경험과 직관을 필요로 합니다. " ] }, { @@ -1037,7 +1036,7 @@ "id": "7Li2r1tYvW7S" }, "source": [ - "## 예측을 위해 훈련 된 모델 사용하기\n", + "## 예측을 위해 훈련된 모델 사용하기\n", "\n", "우리는 이제 붓꽃을 분류하기위해 완벽하지는 않지만 어느정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)들을 예측해봅시다.\n", "\n", @@ -1097,7 +1096,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 707b4f180c8..5ad8297237a 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -71,7 +71,7 @@ "id": "6sILUVbHoSgH" }, "source": [ - "이것은 텐서플로우를 사용하기위한 입문 튜토리얼입니다. 다음 내용을 다룹니다 : \n", + "이 노트북은 텐서플로우를 사용하기 위한 입문 튜토리얼입니다. 다음 내용을 다룹니다 : \n", "\n", "* 필요한 패키지 임포트\n", "* 텐서(Tensor) 생성 및 사용\n", @@ -172,14 +172,14 @@ "id": "eBPw8e8vrsom" }, "source": [ - "넘파이 배열과 텐서의 가장 확실한 차이는 다음과 같습니다:\n", + "넘파이 `ndarray`와 `Tensor`의 가장 확실한 차이는 다음과 같습니다:\n", "\n", - "1. 텐서는 가속기 메모리(GPU, TPU와 같은)의 사용이 가능합니다.\n", - "2. 텐서는 불변성(immutable)을 가집니다." + "1. `Tensor`는 가속기 메모리(GPU, TPU와 같은)의 사용이 가능합니다.\n", + "2. `Tensor`는 불변성(immutable)을 가집니다." ] }, { - "cell_type": "raw", + "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Dwi1tdW3JBw6" @@ -187,7 +187,7 @@ "source": [ "### 넘파이 적합성\n", "\n", - "Tensor와 ndarray사이의 전환은 다소 간단합니다.\n", + "`Tensor`와 `ndarray`사이의 전환은 다소 간단합니다.\n", "\n", "* 텐서플로우 연산는 자동적으로 넘파이 ndarray를 Tensor로 전환합니다.\n", "* 넘파이 연산는 자동적으로 텐서플로우 Tensor를 넘파이 ndarray로 전환합니다.\n", @@ -223,7 +223,7 @@ ] }, { - "cell_type": "raw", + "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "PBNP8yTRfu_X" @@ -231,7 +231,7 @@ "source": [ "## GPU 가속기\n", "\n", - "많은 텐서플로우 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로우는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 CPU 와 GPU에 Tensor를 복사합니다.) 명령에 의해 생성된 Tensor는 전형적으로 명령이 실행된 장치의 메모리에 의해 실행됩니다. 예를들어:" + "대부분의 텐서플로우 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로우는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 CPU 와 GPU에 Tensor를 복사합니다.) 명령에 의해 생성된 Tensor는 전형적으로 명령이 실행된 장치의 메모리에 의해 실행됩니다. 예를들어:" ] }, { @@ -273,11 +273,9 @@ "id": "ZWZQCimzuqyP" }, "source": [ - "\n", - "\n", "### 명시적 장치 배치\n", "\n", - "텐서플로우에서 \"배치\"라는 용어는 개별 명령이 실행을 위해 장치를 할당(배치)하는 방법을 나타냅니다. 앞서 언급되었듯이, 명시적 지침이 없을경우 텐서플로우는 명령을 실행하기위한 장치를 자동으로 결정하고, 필요시 Tensor를 장치에 복사합니다. 그러나 텐서플로우 명령은 `tf.device`을 사용하여 명시적으로 배치할 수 있습니다. 예를 들어:" + "텐서플로우에서 \"배치\"라는 용어는 개별 명령이 실행을 위해 장치를 할당(배치)하는 방법을 나타냅니다. 앞서 언급되었듯이, 명시적 지침이 없을경우 텐서플로우는 명령을 실행하기위한 장치를 자동으로 결정하고, 필요시 Tensor를 장치에 복사합니다. 그러나 텐서플로우 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. 예를 들어:" ] }, { @@ -302,16 +300,16 @@ " print(\"10 loops: {:0.2f}ms\".format(1000*result))\n", "\n", "\n", - "# Force execution on CPU\n", + "# CPU에 강제실행\n", "print(\"On CPU:\")\n", "with tf.device(\"CPU:0\"):\n", " x = tf.random_uniform([1000, 1000])\n", " assert x.device.endswith(\"CPU:0\")\n", " time_matmul(x)\n", "\n", - "# Force execution on GPU #0 if available\n", + "# 이용가능시 GPU #0에 강제실행\n", "if tf.test.is_gpu_available():\n", - " with tf.device(\"GPU:0\"): # Or GPU:1 for the 2nd GPU, GPU:2 for the 3rd etc.\n", + " with tf.device(\"GPU:0\"): # 또는 GPU:1, GPU:2\n", " x = tf.random_uniform([1000, 1000])\n", " assert x.device.endswith(\"GPU:0\")\n", " time_matmul(x)" @@ -326,7 +324,7 @@ "source": [ "## 데이터셋\n", "\n", - "이번 섹션에서는 모델에 데이터를 제공하기위한 파이프라인을 구축하기 위해 [`tf.data.Dataset` API](https://www.tensorflow.org/guide/datasets)를 시연해볼 것입니다. 이는 다음을 포함합니다.\n", + "이번 섹션에서는 모델에 데이터를 제공하기 위한 파이프라인을 구축하기 위해 [`tf.data.Dataset` API](https://www.tensorflow.org/guide/datasets)를 시연해볼 것입니다. 이는 다음을 포함합니다.\n", "\n", "* `Dataset` 생성.\n", "* 즉시실행(eager execution) 활성화와 `Dataset`을 통한 반복\n", @@ -347,7 +345,7 @@ "source": [ "### `Dataset`소스 생성\n", "\n", - "굉장히 유용한 함수중 하나인 [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices)를 사용하여 데이터셋 소스를 생성하거나 or 파일로부터 읽어들이는 객체인 [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) 또는 [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset)를 사용하여 데이터셋 소스를 생성하십시오. 더 많은 정보는 [TensorFlow Guide](https://www.tensorflow.org/guide/datasets#reading_input_data) 를 참조하세요." + "굉장히 유용한 함수중 하나인 [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices)를 사용하여 데이터셋 소스를 생성하거나 or 파일로부터 읽어들이는 객체인 [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) 또는 [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset)를 사용하여 데이터셋 소스를 생성하세요. 더 많은 정보는 [TensorFlow Guide](https://www.tensorflow.org/guide/datasets#reading_input_data) 를 참조하세요." ] }, { @@ -458,7 +456,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.7.1" } }, "nbformat": 4, From bdfcfeb1c1cec491ce016b71f3043ceda0718343 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Tue, 2 Apr 2019 00:48:26 +0900 Subject: [PATCH 05/19] Update from 09ecc41b --- .../eager/automatic_differentiation.ipynb | 8 ++--- site/ko/tutorials/eager/custom_layers.ipynb | 36 +++++++++---------- site/ko/tutorials/eager/custom_training.ipynb | 16 ++++----- .../eager/custom_training_walkthrough.ipynb | 28 +++++++-------- site/ko/tutorials/eager/eager_basics.ipynb | 24 ++++++------- site/ko/tutorials/eager/index.md | 4 +-- 6 files changed, 58 insertions(+), 58 deletions(-) diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index 857cbc3d65d..6a089c90f27 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -108,7 +108,7 @@ "source": [ "## 그래디언트 테이프(Gradient Tape)\n", "\n", - "텐서플로우는 자동미분(주어진 입력 변수에 따른 그래디언트 연산)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape`는 안에서 실행된 모든 연산을 tape에 \"기록\"합니다. 그리고 [역방향 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 각각의 기록된 연산들과 관련된 테이프와 그래디언트들을 사용하여 기록된 연산의 그래디언트를 계산합니다. \n", + "텐서플로는 자동미분(주어진 입력 변수에 따른 그래디언트 연산)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape`는 안에서 실행된 모든 연산을 tape에 \"기록\"합니다. 그리고 [역방향 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 각각의 기록된 연산들과 관련된 테이프와 그래디언트들을 사용하여 기록된 연산의 그래디언트를 계산합니다. \n", "\n", "예를 들면:" ] @@ -176,7 +176,7 @@ "id": "ISkXuY7YzIcS" }, "source": [ - "초기값으로 GradientTape.gradient() 메소드가 호출되면 GradientTape에 포함된 리소스가 해체되게 설정돼있습니다. 동일한 연산을 통해서 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. `persistent`는 `gradient()` 메소드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다." + "초기값으로 GradientTape.gradient() 메서드가 호출되면 GradientTape에 포함된 리소스가 해체되게 설정돼있습니다. 동일한 연산을 통해서 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. `persistent`는 `gradient()` 메서드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다." ] }, { @@ -263,7 +263,7 @@ }, "outputs": [], "source": [ - "x = tf.Variable(1.0) # 1.0으로 초기화된 텐서플로우 변수 생성\n", + "x = tf.Variable(1.0) # 1.0으로 초기화된 텐서플로 변수 생성\n", "\n", "with tf.GradientTape() as t:\n", " with tf.GradientTape() as t2:\n", @@ -286,7 +286,7 @@ "source": [ "## 다음 단계\n", "\n", - "이번 튜토리얼에서는 텐서플로우에서 그래디언트 계산법을 배웠습니다. 이를 통해 우리는 신경망을 구축하고 훈련시키는 데 필요한 기본 요소를 충분히 확보할 수 있습니다." + "이번 튜토리얼에서는 텐서플로에서 그래디언트 계산법을 배웠습니다. 이를 통해 우리는 신경망을 구축하고 훈련시키는 데 필요한 기본 요소를 충분히 확보할 수 있습니다." ] } ], diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index e57583018b7..ed568418a66 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -41,7 +41,7 @@ "id": "60RdWsg1tETW" }, "source": [ - "# 사용자 정의 레이어" + "# 사용자 정의 layer" ] }, { @@ -71,7 +71,7 @@ "id": "UEu3q4jmpKVT" }, "source": [ - "신경망을 구축하기 위해서 고수준 API인 `tf.keras`를 사용하길 권합니다. 대부분의 텐서플로우 API는 즉시실행(eager execution)을 활성화할 수 있습니다." + "신경망을 구축하기 위해서 고수준 API인 `tf.keras`를 사용하길 권합니다. 대부분의 텐서플로 API는 즉시실행(eager execution)을 활성화할 수 있습니다." ] }, { @@ -96,13 +96,13 @@ "id": "zSFfVVjkrrsI" }, "source": [ - "## 레이어(layer): 유용한 연산자 집합\n", + "## layer: 유용한 연산자 집합\n", "\n", "머신러닝을 위한 코드를 작성하는 대부분의 시간에 우리는, 개별적인 연산과 변수를 조작하는 것보다는 고수준의 추상화 수준에서 작업하기를 원합니다.\n", "\n", - "많은 머신러닝 모델은 비교적 단순한 레이어의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로우는 여러 표준 레이어 세트를 제공하므로 사용자 고유의 응용 프로그램에 관련된 레이어를 처음부터 작성하거나, 기존 레이어의 구성으로 쉽게 작성할 수 있습니다.\n", + "많은 머신러닝 모델은 비교적 단순한 layer의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로는 여러 표준 레이어 세트를 제공하므로 사용자 고유의 응용 프로그램에 관련된 레이어를 처음부터 작성하거나, 기존 레이어의 구성으로 쉽게 작성할 수 있습니다.\n", "\n", - "텐서플로우는 [Keras](https://keras.io) API 의 풀패키지를 tf.keras package에 포함하고 있습니다. Keras 레이어는 모델을 구축하는데 매우 유용합니다." + "텐서플로는 [Keras](https://keras.io) API 의 풀패키지를 tf.keras package에 포함하고 있습니다. Keras layer는 모델을 구축하는데 매우 유용합니다." ] }, { @@ -115,8 +115,8 @@ }, "outputs": [], "source": [ - "# tf.keras.layers 패키지에서 레이어는 객체입니다. 레이어를 구성하려면 간단히 객체를 생성하십시오.\n", - "# 대부분의 레이어는 첫번째 인수로 출력 차원(크기) 또는 채널을 취합니다.\n", + "# tf.keras.layers 패키지에서 layer는 객체입니다. layer를 구성하려면 간단히 객체를 생성하십시오.\n", + "# 대부분의 layer는 첫번째 인수로 출력 차원(크기) 또는 채널을 취합니다.\n", "layer = tf.keras.layers.Dense(100)\n", "# 입력 차원의 수는 유추될 수 있기 때문에 종종 불필요합니다. \n", "# 일부 복잡한 모델에서는 수동으로 입력 차원의 수를 제공하는것이 유용할 수 있습니다.\n", @@ -130,7 +130,7 @@ "id": "Fn69xxPO5Psr" }, "source": [ - "미리 구성되어있는 레이어는 다음 [문서](https://www.tensorflow.org/api_docs/python/tf/keras/layers)에서 확인할 수 있습니다. Dense, Conv2D, LSTM, BatchNormalization, Dropout, 등을 포함하고 있습니다." + "미리 구성되어있는 layer는 다음 [문서](https://www.tensorflow.org/api_docs/python/tf/keras/layers)에서 확인할 수 있습니다. Dense, Conv2D, LSTM, BatchNormalization, Dropout, 등을 포함하고 있습니다." ] }, { @@ -143,7 +143,7 @@ }, "outputs": [], "source": [ - "# 레이어를 사용하기 위해서 간단하게 호출합니다.\n", + "# layer를 사용하기 위해서 간단하게 호출합니다.\n", "layer(tf.zeros([10, 5]))" ] }, @@ -157,7 +157,7 @@ }, "outputs": [], "source": [ - "# 레이어는 유용한 메소드들을 내재하고있습니다. 예를 들어, `layer.variables`를 사용하여 레이어안에 있는 모든 변수들을 확인할 수 있으며, \n", + "# layer는 유용한 메서드들을 내재하고있습니다. 예를 들어, `layer.variables`를 사용하여 layer안에 있는 모든 변수들을 확인할 수 있으며, \n", "# `layer.trainable_variables`를 사용하여 학습가능한 변수들을 확인할 수 있습니다. \n", "# 이번 케이스에서 완전 연결(fully-connected) 레이어는 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", "layer.variables" @@ -184,13 +184,13 @@ "id": "O0kDbE54-5VS" }, "source": [ - "## 사용자 정의 레이어 구현\n", - "사용자 정의 레이어를 구현하는 가장 좋은 방법은 tf.keras.Layer 클래스를 상속하고 다음과 같이 구현하는 것입니다.\n", + "## 사용자 정의 layer 구현\n", + "사용자 정의 layer를 구현하는 가장 좋은 방법은 tf.keras.Layer 클래스를 상속하고 다음과 같이 구현하는 것입니다.\n", " * `__init__` , 모든 독립적인 입력값을 초기화를 할 수 있습니다.\n", " * `build`, 입력 Tensor의 형태를 알고 나머지를 초기화 할 수 있습니다.\n", " * `call`, 정방향 계산을 진행 할 수 있습니다.\n", "\n", - "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 레이어가 작동할 입력의 형태를 기준으로 나중에 변수를 만들 수 있습니다. 반면에, `__init__`에 변수를 생성하는것은 변수 생성에 필요한 형태가 명시적으로 지정되어야 함을 의미합니다." + "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 layer가 작동할 입력의 형태를 기준으로 나중에 변수를 만들 수 있습니다. 반면에, `__init__`에 변수를 생성하는것은 변수 생성에 필요한 형태가 명시적으로 지정되어야 함을 의미합니다." ] }, { @@ -230,7 +230,7 @@ "source": [ "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. \n", "\n", - "다른 독자가 표준 레이어의 동작을 잘 알고 있기 때문에, 가능한 경우 표준 레이어를 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers 또는 tf.contrib.layers에 없는 레이어를 사용하기 원하면 [github issue](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀리퀘스트를 요청하세요." + "다른 독자가 표준 layer의 동작을 잘 알고 있기 때문에, 가능한 경우 표준 layer를 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers 또는 tf.contrib.layers에 없는 layer를 사용하기 원하면 [github issue](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀리퀘스트를 요청하세요." ] }, { @@ -240,11 +240,11 @@ "id": "Qhg4KlbKrs3G" }, "source": [ - "## 모델: 레이어 구성\n", + "## 모델: layer 구성\n", "\n", - "머신러닝 모델에서 대부분의 흥미로운 유사 레이어(layer-likely)는 레이어들의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 잔여블록(residual block)은 합성곱(convolution), 배치정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", + "머신러닝 모델에서 대부분의 흥미로운 유사 layer(layer-likely)는 layer들의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 잔여블록(residual block)은 합성곱(convolution), 배치정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", "\n", - "레이어 집합을 포함한 유사 레이어를 생성하기위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현합니다." + "layer 집합을 포함한 유사 layer를 생성하기위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현합니다." ] }, { @@ -321,7 +321,7 @@ "source": [ "# 다음 단계\n", "\n", - "이제 여러분들은 이전 노트북으로 돌아가서 선형 회귀 예제에 좀 더 나은 구조를 만들기 위해 레이어와 모델을 적용할 수 있습니다." + "이제 여러분들은 이전 노트북으로 돌아가서 선형 회귀 예제에 좀 더 나은 구조를 만들기 위해 layer와 모델을 적용할 수 있습니다." ] } ], diff --git a/site/ko/tutorials/eager/custom_training.ipynb b/site/ko/tutorials/eager/custom_training.ipynb index 05b1c35e536..bdd634433a4 100644 --- a/site/ko/tutorials/eager/custom_training.ipynb +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -71,9 +71,9 @@ "id": "k2o3TTG4TFpt" }, "source": [ - "이전 튜토리얼에서 우리는 머신러닝을 위한 기초 빌딩 블록인 자동미분(automatic differentiation)을 위한 텐서플로우 API들을 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 초기 타입의 텐서플로우를 사용하여 간단한 머신러닝을 구축해보겠습니다. \n", + "이전 튜토리얼에서 우리는 머신러닝을 위한 기초 빌딩 블록인 자동미분(automatic differentiation)을 위한 텐서플로 API들을 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 초기 타입의 텐서플로를 사용하여 간단한 머신러닝을 구축해보겠습니다. \n", "\n", - "텐서플로우는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망 API인 (`tf.keras`)를 포함하고 있습니다. 신경망에 관련하여 일을 하고 있는 사람들에게는 이러한 고수준의 API들을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " + "텐서플로는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망 API인 (`tf.keras`)를 포함하고 있습니다. 신경망에 관련하여 일을 하고 있는 사람들에게는 이러한 고수준의 API들을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " ] }, { @@ -119,7 +119,7 @@ "source": [ "## 변수\n", "\n", - "텐서플로우 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝은 상태가 변경될 필요가 있습니다(stateful). 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로, 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 계산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어에 의존한 선택이 가능합니다. " + "텐서플로 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝은 상태가 변경될 필요가 있습니다(stateful). 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로, 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 계산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어에 의존한 선택이 가능합니다. " ] }, { @@ -145,9 +145,9 @@ "id": "wfneTXy7JcUz" }, "source": [ - "그러나 텐서플로우는 상태가 변경 가능한 연산자들이 내장되어 있으며, 이 연산자들은 상태를 표현하기 위한 저수준 파이썬 표현보다 사용하기가 더 좋습니다. 예를 들어, 모델에서 가중치를 나타내기 위해서 텐서플로우 변수를 사용하는것이 편하고 효율적입니다. \n", + "그러나 텐서플로는 상태가 변경 가능한 연산자들이 내장되어 있으며, 이 연산자들은 상태를 표현하기 위한 저수준 파이썬 표현보다 사용하기가 더 좋습니다. 예를 들어, 모델에서 가중치를 나타내기 위해서 텐서플로 변수를 사용하는것이 편하고 효율적입니다. \n", "\n", - "텐서플로우 변수는 값을 저장하고 텐서플로우 계산에 사용될 때 묵시적으로 저장된 값을 읽어오는 객체입니다. `tf.assign_sub`, `tf.scatter_update` 등은 텐서플로우 변수에 저장되있는 값을 조작하는 연산자들입니다." + "텐서플로 변수는 값을 저장하고 텐서플로 계산에 사용될 때 묵시적으로 저장된 값을 읽어오는 객체입니다. `tf.assign_sub`, `tf.scatter_update` 등은 텐서플로 변수에 저장되있는 값을 조작하는 연산자들입니다." ] }, { @@ -167,7 +167,7 @@ "v.assign(3.0)\n", "assert v.numpy() == 3.0\n", "\n", - "# 텐서플로우 연산자 내에서 `v` 사용 \n", + "# 텐서플로 연산자 내에서 `v` 사용 \n", "v.assign(tf.square(v))\n", "assert v.numpy() == 9.0" ] @@ -428,9 +428,9 @@ "source": [ "## 다음 단계\n", "\n", - "이번 튜토리얼에서는 `Variable`를 다루었으며, 지금까지 논의된 초기 타입의 텐서플로우를 사용하여 간단한 선형모델을 구축하고 훈련시켰습니다.\n", + "이번 튜토리얼에서는 `Variable`를 다루었으며, 지금까지 논의된 초기 타입의 텐서플로를 사용하여 간단한 선형모델을 구축하고 훈련시켰습니다.\n", "\n", - "이론적으로, 이것은 머신러닝 연구에 텐서플로우를 사용하는데 필요한 대부분입니다. 실제로, 신경망에 있어 `tf.keras`와 고수준 API들은 고수준 빌딩 블록(\"layer\"로 불리는)을 제공하고, 저장 및 복원을 위한 유틸리티, 손실함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " + "이론적으로, 이것은 머신러닝 연구에 텐서플로를 사용하는데 필요한 대부분입니다. 실제로, 신경망에 있어 `tf.keras`와 고수준 API들은 고수준 빌딩 블록(\"layer\"로 불리는)을 제공하고, 저장 및 복원을 위한 유틸리티, 손실함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " ] } ], diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index 7f2e6e9ae25..ebfde665b95 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -76,15 +76,15 @@ "2. 모델 훈련\n", "3. 예측을 위한 모델 사용\n", "\n", - "## 텐서플로우 프로그래밍\n", + "## 텐서플로 프로그래밍\n", "\n", - "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로우의 개념들을 사용합니다.\n", + "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로의 개념들을 사용합니다.\n", "\n", "* [즉시실행(eager execution)](https://www.tensorflow.org/guide/eager) 개발환경,\n", "* [Datasets API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 불러오기,\n", - "* [Keras API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 레이어(layer) 구축 .\n", + "* [Keras API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 layer 구축 .\n", "\n", - "이번 튜토리얼은 다른 텐서플로우 프로그램과 유사하게 구성되어있습니다.\n", + "이번 튜토리얼은 다른 텐서플로 프로그램과 유사하게 구성되어있습니다.\n", "\n", "1. 데이터 불러오기 및 분석.\n", "2. 모델 타입 선정.\n", @@ -112,7 +112,7 @@ "source": [ "### 임포트 및 즉시실행 구성\n", "\n", - "텐서플로우를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시실행을 활성화할 것입니다. 즉시실행은 텐서플로우가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는데신, 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", + "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시실행을 활성화할 것입니다. 즉시실행은 텐서플로가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는데신, 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", "\n", "즉시실행이 활성화 될때, 동일한 프로그램내에서는 비활성화를 할 수 없습니다. 더 많은 세부사항은 [eager execution guide](https://www.tensorflow.org/guide/eager)을 참조하세요." ] @@ -305,7 +305,7 @@ "source": [ "### `tf.data.Dataset` 생성\n", "\n", - "텐서플로우의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위한 많은 케이스를 다룹니다. 이는 훈련을 위한 형태로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 다음을 참조하세요. [Datasets Quick Start guide](https://www.tensorflow.org/get_started/datasets_quickstart) \n", + "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위한 많은 케이스를 다룹니다. 이는 훈련을 위한 형태로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 다음을 참조하세요. [Datasets Quick Start guide](https://www.tensorflow.org/get_started/datasets_quickstart) \n", "\n", "\n", "데이터셋이 CSV 형태의 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 [배치 사이즈(batch_size)](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." @@ -397,7 +397,7 @@ "source": [ "모델 구축단계를 단순화하기 위해서, 특성(사전형 객체)을 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", "\n", - "이 함수는 `Tensor`의 list로부터 값을 취하고 특정한 차원으로 결합된 `Tensor`를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메소드(method)를 사용합니다." + "이 함수는 `Tensor`의 list로부터 값을 취하고 특정한 차원으로 결합된 `Tensor`를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메서드(method)를 사용합니다." ] }, { @@ -423,7 +423,7 @@ "id": "V1Vuph_eDl8x" }, "source": [ - "그 후 각 `(features,label)`쌍의 `features`을 훈련 데이터셋에 적재하기위해 [tf.data.Dataset.map](https://www.tensorflow.org/api_docs/python/tf/data/dataset/map) 메소드를 사용합니다. " + "그 후 각 `(features,label)`쌍의 `features`을 훈련 데이터셋에 적재하기위해 [tf.data.Dataset.map](https://www.tensorflow.org/api_docs/python/tf/data/dataset/map) 메서드를 사용합니다. " ] }, { @@ -505,9 +505,9 @@ "source": [ "### Keras를 사용한 모델 생성\n", "\n", - "텐서플로우의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 레이어를 생성하기위한 풍부한 라이브러리를 제공합니다. 이는 연결되있는 모든것들을 케라스가 처리하여 모델을 구축하기 쉽게 만듭니다.\n", + "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 layer를 생성하기위한 풍부한 라이브러리를 제공합니다. 이는 연결되있는 모든것들을 케라스가 처리하여 모델을 구축하기 쉽게 만듭니다.\n", "\n", - "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 레이어의 선형 적층 모델입니다. 이 구조는 레이어의 인스턴스를 취하며, 아래의 케이스의 경우 각 레이어당 10개의 노드(node)를 가지는 2개의 [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense) 레이어와 3개의 예측(레이블의 개수)노드를 가지는 출력 레이어로 구성되어있습니다. 첫번째 레이어의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." + "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 layer의 선형 적층 모델입니다. 이 구조는 layer의 인스턴스를 취하며, 아래의 케이스의 경우 각 layer당 10개의 노드(node)를 가지는 2개의 [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)층과 3개의 예측(레이블의 개수)노드를 가지는 출력 층으로 구성되어있습니다. 첫번째 layer의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." ] }, { @@ -534,7 +534,7 @@ "id": "FHcbEzMpxbHL" }, "source": [ - "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 레이어의 출력의 형태를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 단일 레이어와 동일하다고 생각할 수 있습니다. 사용가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", + "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 층들의 출력의 형태를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 단일층과 동일하다고 생각할 수 있습니다. 사용가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", "\n", "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 좌우됩니다. 머신러닝의 여러측면과 마찬가지로, 신경망의 최적의 형태를 결정하는것은 많은 경험과 지식이 필요합니다. 경험을 토대로, 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." ] @@ -708,7 +708,7 @@ " \n", "\n", "\n", - "텐서플로우는 학습을 위해 이용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 그래디언트 하강(stochastic gradient descent)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현하는 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. 매개변수 `learning_rate`은 경사하강 과정의 크기를 나타내는 척도이며, 더 나은 결과를 위해 공동적으로 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " + "텐서플로는 학습을 위해 이용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 그래디언트 하강(stochastic gradient descent)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현하는 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. 매개변수 `learning_rate`은 경사하강 과정의 크기를 나타내는 척도이며, 더 나은 결과를 위해 공동적으로 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " ] }, { @@ -737,7 +737,7 @@ ] }, { - "cell_type": "raw", + "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "pJVRZ0hP52ZB" @@ -852,7 +852,7 @@ "id": "j3wdbmtLVTyr" }, "source": [ - "모델의 훈련 과정을 출력하는 것은 도움이 되지만, 훈련 과정을 직접 보는 것이 더 도움이 되곤합니다. [TensorBoard](https://www.tensorflow.org/guide/summaries_and_tensorboard)는 텐서플로우에 패키지되어있는 굉장히 유용한 시각화 툴입니다. 하지만 우리는 `matplotlib` 모듈을 사용하여 일반적인 차트를 출력할 수 있습니다.\n", + "모델의 훈련 과정을 출력하는 것은 도움이 되지만, 훈련 과정을 직접 보는 것이 더 도움이 되곤합니다. [TensorBoard](https://www.tensorflow.org/guide/summaries_and_tensorboard)는 텐서플로에 패키지되어있는 굉장히 유용한 시각화 툴입니다. 하지만 우리는 `matplotlib` 모듈을 사용하여 일반적인 차트를 출력할 수 있습니다.\n", "\n", "이 차트를 해석하는것은 여러 경험이 필요하지만, 우리는 *손실*이 내려가고 *정확도*가 올라가는 것을 보고싶습니다." ] diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 5ad8297237a..87c95fe4d1c 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -71,7 +71,7 @@ "id": "6sILUVbHoSgH" }, "source": [ - "이 노트북은 텐서플로우를 사용하기 위한 입문 튜토리얼입니다. 다음 내용을 다룹니다 : \n", + "이 노트북은 텐서플로를 사용하기 위한 입문 튜토리얼입니다. 다음 내용을 다룹니다 : \n", "\n", "* 필요한 패키지 임포트\n", "* 텐서(Tensor) 생성 및 사용\n", @@ -86,9 +86,9 @@ "id": "z1JcS5iBXMRO" }, "source": [ - "## 텐서플로우 임포트\n", + "## 텐서플로 임포트\n", "\n", - "시작하기 위해서 텐서플로우 모듈을 임포트하고 즉시실행(eager execution)을 활성화합니다. 즉시실행 활성화로 텐서플로우에 대한 대화형 프론트엔드(frontend)가 가능합니다. 세부사항은 나중에 이야기할 것입니다." + "시작하기 위해서 텐서플로 모듈을 임포트하고 즉시실행(eager execution)을 활성화합니다. 즉시실행 활성화로 텐서플로에 대한 대화형 프론트엔드(frontend)가 가능합니다. 세부사항은 나중에 이야기할 것입니다." ] }, { @@ -116,7 +116,7 @@ "source": [ "## 텐서\n", "\n", - "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 형태를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로우는 텐서를 생성하고 계산하는 풍부한 연산 라이브러리를 제공합니다. ([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.). 이러한 연산자들은 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" + "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 형태를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 계산하는 풍부한 연산 라이브러리를 제공합니다. ([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.). 이러한 연산자들은 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" ] }, { @@ -189,10 +189,10 @@ "\n", "`Tensor`와 `ndarray`사이의 전환은 다소 간단합니다.\n", "\n", - "* 텐서플로우 연산는 자동적으로 넘파이 ndarray를 Tensor로 전환합니다.\n", - "* 넘파이 연산는 자동적으로 텐서플로우 Tensor를 넘파이 ndarray로 전환합니다.\n", + "* 텐서플로 연산는 자동적으로 넘파이 ndarray를 Tensor로 전환합니다.\n", + "* 넘파이 연산는 자동적으로 텐서플로 Tensor를 넘파이 ndarray로 전환합니다.\n", "\n", - "Tensor는 `.numpy()` 메소드(method)를 호출하여 넘파이 ndarray로 전환할 수 있습니다.\n", + "Tensor는 `.numpy()` 메서드(method)를 호출하여 넘파이 ndarray로 전환할 수 있습니다.\n", "가능한 경우, Tensor와 ndarray은 메모리 표현을 공유하기 때문에 이러한 전환은 일반적으로 간단(저렴)합니다. 그러나 Tensor는 GPU 메모리에 저장될 수 있고, 넘파이 ndarray은 항상 호스트 메모리에 백업이 되므로, 이러한 전환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 포함됩니다." ] }, @@ -231,7 +231,7 @@ "source": [ "## GPU 가속기\n", "\n", - "대부분의 텐서플로우 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로우는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 CPU 와 GPU에 Tensor를 복사합니다.) 명령에 의해 생성된 Tensor는 전형적으로 명령이 실행된 장치의 메모리에 의해 실행됩니다. 예를들어:" + "대부분의 텐서플로 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 CPU 와 GPU에 Tensor를 복사합니다.) 명령에 의해 생성된 Tensor는 전형적으로 명령이 실행된 장치의 메모리에 의해 실행됩니다. 예를들어:" ] }, { @@ -263,7 +263,7 @@ "source": [ "### 장치 이름\n", "\n", - "`Tensor.device`는 Tensor를 구성하고 있는 호스트 장치의 풀네임을 제공합니다. 이러한 이름은 프로그램이 실행중인 호스트의 네트워크 주소 및 해당 호스트 내의 장치와 같은 많은 세부 정보를 인코딩하며, 이것은 텐서플로우 프로그램의 분산 실행에 필요합니다. Tensor가 호스트의 `N`번째 GPU에 놓여지면 문자열은 `GPU:` 끝납니다." + "`Tensor.device`는 Tensor를 구성하고 있는 호스트 장치의 풀네임을 제공합니다. 이러한 이름은 프로그램이 실행중인 호스트의 네트워크 주소 및 해당 호스트 내의 장치와 같은 많은 세부 정보를 인코딩하며, 이것은 텐서플로 프로그램의 분산 실행에 필요합니다. Tensor가 호스트의 `N`번째 GPU에 놓여지면 문자열은 `GPU:` 끝납니다." ] }, { @@ -275,7 +275,7 @@ "source": [ "### 명시적 장치 배치\n", "\n", - "텐서플로우에서 \"배치\"라는 용어는 개별 명령이 실행을 위해 장치를 할당(배치)하는 방법을 나타냅니다. 앞서 언급되었듯이, 명시적 지침이 없을경우 텐서플로우는 명령을 실행하기위한 장치를 자동으로 결정하고, 필요시 Tensor를 장치에 복사합니다. 그러나 텐서플로우 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. 예를 들어:" + "텐서플로에서 \"배치\"라는 용어는 개별 명령이 실행을 위해 장치를 할당(배치)하는 방법을 나타냅니다. 앞서 언급되었듯이, 명시적 지침이 없을경우 텐서플로는 명령을 실행하기위한 장치를 자동으로 결정하고, 필요시 Tensor를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. 예를 들어:" ] }, { @@ -331,7 +331,7 @@ "\n", "모델을 학습시키고, 평가 루프를 제공할 간단하고 재사용 가능한 조각으로부터 복잡한 입력 파이프라인을 구축하기위해 `Dataset`s API를 사용하기를 권장합니다. \n", "\n", - "만약 텐서플로우 그래프에 익숙하다면, `Dataset` 객체를 생성하기 위한 API는 즉시실행이 활성화 되어도 동일하게 유지됩니다. 하지만 그러나 데이터셋의 요소를 반복하는 프로세스는 약간 더 간단합니다.\n", + "만약 텐서플로 그래프에 익숙하다면, `Dataset` 객체를 생성하기 위한 API는 즉시실행이 활성화 되어도 동일하게 유지됩니다. 하지만 그러나 데이터셋의 요소를 반복하는 프로세스는 약간 더 간단합니다.\n", "또한 `tf.data.Dataset` 객체를 통하여 파이썬 반복문을 사용할 수 있으며, 명시적으로 `tf.data.Iterator` 객체를 생성할 필요가 없습니다.\n", "그 결과, [TensorFlow Guide](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시실행이 활성화될 때에는 관계없습니다. " ] @@ -409,7 +409,7 @@ "source": [ "### 반복\n", "\n", - "즉시실행이 활성화되면 `Dataset` 객체는 반복을 지원합니다. 만약 텐서플로우 그래프에서 `Dataset`을 사용하는게 익숙하다면, `Dataset.make_one_shot_iterator()` 또는 `get_next()`와 같은 객체를 호출할 필요가 없는다는 것에 주목하세요." + "즉시실행이 활성화되면 `Dataset` 객체는 반복을 지원합니다. 만약 텐서플로 그래프에서 `Dataset`을 사용하는게 익숙하다면, `Dataset.make_one_shot_iterator()` 또는 `get_next()`와 같은 객체를 호출할 필요가 없는다는 것에 주목하세요." ] }, { diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md index d78212b1af4..3f275517e37 100644 --- a/site/ko/tutorials/eager/index.md +++ b/site/ko/tutorials/eager/index.md @@ -10,12 +10,12 @@ 메일을 보내주시기 바랍니다. 즉시실행(Eager execution)은 더 나은 연산을 위한 실행에 의해 정의되는 명령형 인터페이스를 제공합니다. -사용자 정의 레이어, 정방향 전파, 자동미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 시작한 다음 순서대로 진행하세요. +사용자 정의 layer, 정방향 전파, 자동미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 시작한 다음 순서대로 진행하세요. [eager execution guide](../../guide/eager). 1. [즉시실행(Eager execution)](eager_basics.ipynb) 2. [Automatic differentiation and gradient tape](automatic_differentiation.ipynb) 3. [사용자 정의 학습 : 기본(Custom training: basics)](custom_training.ipynb) -4. [사용자 정의 레이어(Custom layers)](custom_layers.ipynb) +4. [사용자 정의 layer(Custom layers)](custom_layers.ipynb) 5. [사용자 정의 학습 : walkthrough(Custom training: walkthrough)](custom_training_walkthrough.ipynb) From 5f2c72a95ad8b480734a7db7915f5474c78c8a56 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Tue, 2 Apr 2019 13:41:36 +0900 Subject: [PATCH 06/19] Update from 4e28c14a Edit a typing error --- .../eager/automatic_differentiation.ipynb | 6 +- site/ko/tutorials/eager/custom_layers.ipynb | 4 +- site/ko/tutorials/eager/custom_training.ipynb | 14 +- .../eager/custom_training_walkthrough.ipynb | 285 ++++++++++++++---- site/ko/tutorials/eager/eager_basics.ipynb | 55 ++-- site/ko/tutorials/eager/index.md | 4 +- 6 files changed, 273 insertions(+), 95 deletions(-) diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index 6a089c90f27..59dcf5dc7ed 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -71,7 +71,7 @@ "id": "vDJ4XzMqodTy" }, "source": [ - "이전 튜토리얼에서 우리는 Tensor와 Tensor의 연산들에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술 중 하나인 [자동미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." + "이전 튜토리얼에서 우리는 텐서(tensor)와 텐서의 연산들에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술 중 하나인 [자동미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." ] }, { @@ -286,7 +286,7 @@ "source": [ "## 다음 단계\n", "\n", - "이번 튜토리얼에서는 텐서플로에서 그래디언트 계산법을 배웠습니다. 이를 통해 우리는 신경망을 구축하고 훈련시키는 데 필요한 기본 요소를 충분히 확보할 수 있습니다." + "이번 튜토리얼에서는 텐서플로에서 그래디언트 계산법을 배웠습니다. 이를 통해 우리는 신경망(neural network)을 구축하고 훈련시키는 데 필요한 기본 요소를 충분히 확보할 수 있습니다." ] } ], @@ -314,7 +314,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.1" + "version": "3.6.7" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index ed568418a66..29fc33e0c31 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -100,7 +100,7 @@ "\n", "머신러닝을 위한 코드를 작성하는 대부분의 시간에 우리는, 개별적인 연산과 변수를 조작하는 것보다는 고수준의 추상화 수준에서 작업하기를 원합니다.\n", "\n", - "많은 머신러닝 모델은 비교적 단순한 layer의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로는 여러 표준 레이어 세트를 제공하므로 사용자 고유의 응용 프로그램에 관련된 레이어를 처음부터 작성하거나, 기존 레이어의 구성으로 쉽게 작성할 수 있습니다.\n", + "많은 머신러닝 모델은 비교적 단순한 layer의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로는 여러 표준 layer 세트를 제공하므로 사용자 고유의 응용 프로그램에 관련된 layer를 처음부터 작성하거나, 기존 layer의 구성으로 쉽게 작성할 수 있습니다.\n", "\n", "텐서플로는 [Keras](https://keras.io) API 의 풀패키지를 tf.keras package에 포함하고 있습니다. Keras layer는 모델을 구축하는데 매우 유용합니다." ] @@ -349,7 +349,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.1" + "version": "3.6.7" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/custom_training.ipynb b/site/ko/tutorials/eager/custom_training.ipynb index bdd634433a4..58c48d95445 100644 --- a/site/ko/tutorials/eager/custom_training.ipynb +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -73,7 +73,7 @@ "source": [ "이전 튜토리얼에서 우리는 머신러닝을 위한 기초 빌딩 블록인 자동미분(automatic differentiation)을 위한 텐서플로 API들을 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 초기 타입의 텐서플로를 사용하여 간단한 머신러닝을 구축해보겠습니다. \n", "\n", - "텐서플로는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망 API인 (`tf.keras`)를 포함하고 있습니다. 신경망에 관련하여 일을 하고 있는 사람들에게는 이러한 고수준의 API들을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " + "텐서플로는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 `tf.keras`를 포함하고 있습니다. 신경망에 관련하여 일을 하고 있는 사람들에게는 이러한 고수준의 API들을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " ] }, { @@ -119,7 +119,7 @@ "source": [ "## 변수\n", "\n", - "텐서플로 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝은 상태가 변경될 필요가 있습니다(stateful). 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로, 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 계산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어에 의존한 선택이 가능합니다. " + "텐서플로 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로, 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 계산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어에 의존한 선택이 가능합니다. " ] }, { @@ -167,7 +167,7 @@ "v.assign(3.0)\n", "assert v.numpy() == 3.0\n", "\n", - "# 텐서플로 연산자 내에서 `v` 사용 \n", + "# 텐서플로 연산내에서 `v` 사용 \n", "v.assign(tf.square(v))\n", "assert v.numpy() == 9.0" ] @@ -181,7 +181,7 @@ "source": [ "변수들을 사용한 계산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 초기값으로부터 드물게 업데이트됩니다. 이는 계산과 메모리에 있어 더욱 효율적입니다. \n", "\n", - "또한 변수를 사용하는 것은 코드를 읽는 과정에서 변경 가능한 상태(state mutable)의 조각을 빠르게 인식하는 방법입니다." + "또한 변수를 사용하는 것은 코드를 읽는 과정에서 상태가 변경 가능한 상태(state mutable)의 조각을 빠르게 인식하는 방법입니다." ] }, { @@ -341,7 +341,7 @@ "plt.scatter(inputs, model(inputs), c='r')\n", "plt.show()\n", "\n", - "print('Current loss: '),\n", + "print('현재 손실: '),\n", "print(loss(model(inputs), outputs).numpy())" ] }, @@ -406,7 +406,7 @@ " current_loss = loss(model(inputs), outputs)\n", "\n", " train(model, inputs, outputs, learning_rate=0.1)\n", - " print('Epoch %2d: W=%1.2f b=%1.2f, loss=%2.5f' %\n", + " print('에포크 %2d: W=%1.2f b=%1.2f, 손실=%2.5f' %\n", " (epoch, Ws[-1], bs[-1], current_loss))\n", "\n", "# Let's plot it all\n", @@ -458,7 +458,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.1" + "version": "3.6.7" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index ebfde665b95..bcd0765d937 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -112,20 +112,29 @@ "source": [ "### 임포트 및 즉시실행 구성\n", "\n", - "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시실행을 활성화할 것입니다. 즉시실행은 텐서플로가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는데신, 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", + "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시실행을 활성화할 것입니다. 즉시실행은 텐서플로가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", "\n", - "즉시실행이 활성화 될때, 동일한 프로그램내에서는 비활성화를 할 수 없습니다. 더 많은 세부사항은 [eager execution guide](https://www.tensorflow.org/guide/eager)을 참조하세요." + "즉시실행이 활성화 될때, 동일한 프로그램내에서는 비활성화를 할 수 없습니다. 더 많은 세부사항은 [즉시실행 가이드](https://www.tensorflow.org/guide/eager)을 참조하세요." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "colab": {}, "colab_type": "code", "id": "g4Wzg69bnwK2" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "텐서플로 버전: 1.10.0\n", + "즉시실행: True\n" + ] + } + ], "source": [ "from __future__ import absolute_import, division, print_function\n", "\n", @@ -136,8 +145,8 @@ "\n", "tf.enable_eager_execution()\n", "\n", - "print(\"TensorFlow version: {}\".format(tf.__version__))\n", - "print(\"Eager execution: {}\".format(tf.executing_eagerly()))" + "print(\"텐서플로 버전: {}\".format(tf.__version__))\n", + "print(\"즉시실행: {}\".format(tf.executing_eagerly()))" ] }, { @@ -188,13 +197,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "colab": {}, "colab_type": "code", "id": "J6c7uEU9rjRM" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv\n", + "8192/2194 [================================================================================================================] - 0s 0us/step\n", + "Local copy of the dataset file: C:\\Users\\82108\\.keras\\datasets\\iris_training.csv\n" + ] + } + ], "source": [ "train_dataset_url = \"https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv\"\n", "\n", @@ -239,7 +258,7 @@ "처음 5개의 데이터로부터 다음을 주목하세요.\n", "\n", "1. 첫번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", - " * 총 120개의 예가 있으며, 각 예들은 4가지의 특성(feature), 3가지 가능한 레이블(label)을 가지고 있다.\n", + " * 총 120개의 예가 있으며, 각 예들은 4가지의 특성(feature), 3가지 가능한 레이블(label)을 가지고 있습니다.\n", "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[예](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 예제의 특징을 나타냅니다. 이 필드들는 붓꽃의 측정값을 부동소수점으로 나타냅니다.\n", " * 마지막 컬럼(column)은 *[레이블(label)](https://developers.google.com/machine-learning/glossary/#label)*입니다.: 레이블은 우리가 에측하고자 하는 값을 나타냅니다. 이 데이터셋에서는 꽃의 이름과 관련된 정수값 0, 1, 2를 나타냅니다.\n", @@ -249,22 +268,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "colab": {}, "colab_type": "code", "id": "9Edhevw7exl6" }, - "outputs": [], - "source": [ - "# CSV파일내에서 컬럼의 순서\n", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "특성: ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']\n", + "레이블: species\n" + ] + } + ], + "source": [ + "# CSV 파일내에서 컬럼의 순서\n", "column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']\n", "\n", "feature_names = column_names[:-1]\n", "label_name = column_names[-1]\n", "\n", - "print(\"Features: {}\".format(feature_names))\n", - "print(\"Label: {}\".format(label_name))" + "print(\"특성: {}\".format(feature_names))\n", + "print(\"레이블: {}\".format(label_name))" ] }, { @@ -285,7 +313,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "colab": {}, "colab_type": "code", @@ -313,7 +341,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "colab": {}, "colab_type": "code", @@ -344,13 +372,43 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "colab": {}, "colab_type": "code", "id": "iDuG94H-C122" }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "OrderedDict([('sepal_length',\n", + " ),\n", + " ('sepal_width',\n", + " ),\n", + " ('petal_length',\n", + " ),\n", + " ('petal_width',\n", + " )])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "features, labels = next(iter(train_dataset))\n", "\n", @@ -371,21 +429,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": { "colab": {}, "colab_type": "code", "id": "me5Wn-9FcyyO" }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "plt.scatter(features['petal_length'].numpy(),\n", " features['sepal_length'].numpy(),\n", " c=labels.numpy(),\n", " cmap='viridis')\n", "\n", - "plt.xlabel(\"Petal length\")\n", - "plt.ylabel(\"Sepal length\");" + "plt.xlabel(\"petal length\")\n", + "plt.ylabel(\"sepal length\");" ] }, { @@ -402,7 +473,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": { "colab": {}, "colab_type": "code", @@ -428,7 +499,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": { "colab": {}, "colab_type": "code", @@ -451,13 +522,26 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "colab": {}, "colab_type": "code", "id": "kex9ibEek6Tr" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tf.Tensor(\n", + "[[4.9 3. 1.4 0.2]\n", + " [6.6 2.9 4.6 1.3]\n", + " [6.8 3.2 5.9 2.3]\n", + " [5. 3.5 1.3 0.3]\n", + " [7.7 2.8 6.7 2. ]], shape=(5, 4), dtype=float32)\n" + ] + } + ], "source": [ "features, labels = next(iter(train_dataset))\n", "\n", @@ -512,7 +596,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": { "colab": {}, "colab_type": "code", @@ -553,13 +637,29 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "colab": {}, "colab_type": "code", "id": "xe6SQ5NrpB-I" }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "predictions = model(features)\n", "predictions[:5]" @@ -579,13 +679,29 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": { "colab": {}, "colab_type": "code", "id": "_tRwHZmTNTX2" }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "tf.nn.softmax(predictions[:5])" ] @@ -602,16 +718,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": { "colab": {}, "colab_type": "code", "id": "-Jzm_GoErz8B" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "예측: [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]\n", + " 레이블: [0 1 2 0 2 1 0 0 2 1 1 2 2 2 0 2 0 2 0 2 0 0 1 0 0 1 2 2 2 1 0 2]\n" + ] + } + ], "source": [ - "print(\"Prediction: {}\".format(tf.argmax(predictions, axis=1)))\n", - "print(\" Labels: {}\".format(labels))" + "print(\"예측: {}\".format(tf.argmax(predictions, axis=1)))\n", + "print(\" 레이블: {}\".format(labels))" ] }, { @@ -623,7 +748,7 @@ "source": [ "## 모델 훈련하기\n", "\n", - "*[훈련 단계](https://developers.google.com/machine-learning/crash-course/glossary#training)*는 모델이 점진적으로 최적화되거나 데이터셋을 학습하는 머신러닝의 과정입니다. 훈련의 목적은 미지의 데이터를 예측하기 위해, 훈련 데이터셋의 구조에 대해서 충분히 학습하는 것입니다. 만약 모델이 훈련 데이터셋에 대해서 과하게 학습된다면, 오직 훈련 데이터셋에 대해서 작동할 것이며, 일반화되기 힘들 것입니다. 이러한 문제를 *[과대적합(overfitting)](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)* 이라고 합니다. 이는 마치 문제를 이해하고 해결한다기보다는 답을 기억하는 것이라고 생각할 수 있습니다. \n", + "*[훈련 단계](https://developers.google.com/machine-learning/crash-course/glossary#training)*는 모델이 점진적으로 최적화되거나 데이터셋을 학습하는 머신러닝의 과정입니다. 훈련의 목적은 미지의 데이터를 예측하기 위해, 훈련 데이터셋의 구조에 대해서 충분히 학습하는 것입니다. 만약 모델이 훈련 데이터셋에 대해서 과하게 학습된다면 오직 훈련 데이터셋에 대해서 작동할 것이며, 일반화되기 힘들 것입니다. 이러한 문제를 *[과대적합(overfitting)](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)* 이라고 합니다. 이는 마치 문제를 이해하고 해결한다기보다는 답을 기억하는 것이라고 생각할 수 있습니다. \n", "\n", "붓꽃 분류 문제는 지도학습 *[지도학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시 중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고 있지않습니다. 대신에 모델은 특성들의 패턴을 찾습니다. " ] @@ -644,13 +769,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": { "colab": {}, "colab_type": "code", "id": "tMAT4DcMPwI-" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "손실 테스트: 1.5565308332443237\n" + ] + } + ], "source": [ "def loss(model, x, y):\n", " y_ = model(x)\n", @@ -658,7 +791,7 @@ "\n", "\n", "l = loss(model, features, labels)\n", - "print(\"Loss test: {}\".format(l))" + "print(\"손실 테스트: {}\".format(l))" ] }, { @@ -668,12 +801,12 @@ "id": "3IcPqA24QM6B" }, "source": [ - "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)* 계산하기위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 다음을 확인하세요. [eager execution guide](https://www.tensorflow.org/guide/eager)." + "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)* 계산하기위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 [즉시실행 가이드](https://www.tensorflow.org/guide/eager)를 확인하세요. " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": { "colab": {}, "colab_type": "code", @@ -708,7 +841,7 @@ " \n", "\n", "\n", - "텐서플로는 학습을 위해 이용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 그래디언트 하강(stochastic gradient descent)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현하는 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. 매개변수 `learning_rate`은 경사하강 과정의 크기를 나타내는 척도이며, 더 나은 결과를 위해 공동적으로 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " + "텐서플로는 학습을 위해 이용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 그래디언트 하강(stochastic gradient descent, SGD)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현하는 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. 매개변수 `learning_rate`은 경사하강 과정의 크기를 나타내는 척도이며, 더 나은 결과를 위해 공동적으로 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " ] }, { @@ -723,7 +856,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": { "colab": {}, "colab_type": "code", @@ -733,7 +866,7 @@ "source": [ "optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)\n", "\n", - "global_step = tf.Variable(0)" + "global_step = tf.contrib.eager.Variable(0)" ] }, { @@ -748,22 +881,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "metadata": { "colab": {}, "colab_type": "code", "id": "rxRNTFVe56RG" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "단계: 0, 초기 손실: 1.5565308332443237\n", + "단계: 1, 손실: 1.4113397598266602\n" + ] + } + ], "source": [ "loss_value, grads = grad(model, features, labels)\n", "\n", - "print(\"Step: {}, Initial Loss: {}\".format(global_step.numpy(),\n", + "print(\"단계: {}, 초기 손실: {}\".format(global_step.numpy(),\n", " loss_value.numpy()))\n", "\n", "optimizer.apply_gradients(zip(grads, model.trainable_variables), global_step)\n", "\n", - "print(\"Step: {}, Loss: {}\".format(global_step.numpy(),\n", + "print(\"단계: {}, 손실: {}\".format(global_step.numpy(),\n", " loss(model, features, labels).numpy()))" ] }, @@ -790,13 +932,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": { "colab": {}, "colab_type": "code", "id": "AIgulGRUhpto" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "에포크 000: 손실: 1.364, 정확도: 35.000%\n", + "에포크 050: 손실: 0.732, 정확도: 70.833%\n", + "에포크 100: 손실: 0.434, 정확도: 95.000%\n", + "에포크 150: 손실: 0.273, 정확도: 98.333%\n", + "에포크 200: 손실: 0.231, 정확도: 99.167%\n" + ] + } + ], "source": [ "## Note: 이 셀을 다시 실행하면 동일한 모델의 변수가 사용됩니다.\n", "\n", @@ -830,7 +984,7 @@ " train_accuracy_results.append(epoch_accuracy.result())\n", " \n", " if epoch % 50 == 0:\n", - " print(\"Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}\".format(epoch,\n", + " print(\"에포크 {:03d}: 손실: {:.3f}, 정확도: {:.3%}\".format(epoch,\n", " epoch_loss_avg.result(),\n", " epoch_accuracy.result()))" ] @@ -859,22 +1013,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "metadata": { "colab": {}, "colab_type": "code", "id": "agjvNd2iUGFn" }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAtgAAAIdCAYAAAAH9goCAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzs3Xd8XNWd///X0WjUe++WLbl34wLYGINxsE1NQkKAhMCGOCGBzS9tU78hu2lks8kCIQlLWCAkYEhC6KE3U9zk3mVbtrrVex3NnN8fM3jlLskjjSS/n4+HHnjuPXP1mWswbx997jnGWouIiIiIiPhHUKALEBEREREZTRSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RkkBhjHMaYVmNMjj/HDmfGmHHGmNZA1yEiEkgK2CIiPr6A+9GXxxjT0ev1Tf29nrXWba2NstaW+HNsfxljfmqMscaYrxx3/Fu+4z/s43XKjDFLTjfGWltkrY06i3JFREY8BWwRER9fwI3yBcQS4Kpexx4/frwxJnjoqxywQuDzxx37nO+4X4yw+yEiMmgUsEVE+sg3E/yUMWa1MaYF+Kwx5gJjzDpjTKMxptIYc58xxukbH+ybIc71vf6L7/zLxpgWY8xaY8zY/o71nV9hjCk0xjQZY35rjPnAGHPLacpfCyQYYyb63j8L7/8Dthz3Ga82xmzzfZ73jTHTfMdXAxnAy74Z/W8YY/J9Nd9qjCkBXvvoWK/rJRpjHvXdmwZjzNO+4ynGmH/6vk+9MWbNgH9jRESGGQVsEZH++TjwBBALPAX0AF8DkoCFwHLgS6d5/43A/wMS8M6S/6S/Y40xKcBfgW/7vu8hYH4fav8zcLPv1zcDj/U+aYyZB/wRuA1IBB4GnjPGhFhrbwAqgBW+Gf3f9HrrYmAScMVJvucTQAgwBUgF7vUd/zZQBCQDab7PKSIyKihgi4j0z/vW2hestR5rbYe1dqO1dr21tsdaWwQ8CFx8mvf/3VpbYK11AY8DswYw9kpgq7X2Od+5/wZq+1D7n4GbfDPsn/Zds7dVwO99n8ltrX3Yd3zeGa57l7W23Vrb0fugMSYbWArcbq1tsNZ2W2s/mql24Z0Rz/Edf7cP9YuIjAgK2CIi/VPa+4UxZpIx5iVjzBFjTDPwH3hnlU/lSK9ftwOneyDwVGMzetdhrbVA2ZkKt9YewjsT/nNgl7W24rghY4Dv+No2Go0xjUA6kHmGS5ee4ng2UGutbTrJubuBYuBNY8xBY8y3z1S/iMhIoYAtItI/9rjX/wPsBPKttTHAjwAzyDVUAlkfvTDGGM4cgj/yGPBNjmsP8SkF/t1aG9frK8Ja+1ff+eM/u/egN+CfTCmQZIyJOcl7mq21X7fW5gLX4g32p5v5FxEZMRSwRUTOTjTQBLQZYyZz+v5rf3kRmGOMucq3csfX8PYy98UTwMeAp09y7kHgq8aYecYryvc9In3nq4BxfS3SWlsKvAH8zhgTZ4xxGmMWA/ium+f7y0ET4PZ9iYiMeArYIiJn55t4l79rwTub/dRgf0NrbRVwPfAboA7Iw7saSFcf3tturX3DWtt5knPrgduBPwANeJfw+2yvIT8H/t3XPvL/9bHcj95fiDeg3+l7PRF4C2gFPgDutda+38driogMa+bUP9kTEZGRwBjjwLvCx3XW2vcCXY+IyLlOM9giIiOQMWa5MSbWGBOKd4m7HmBDgMsSEREUsEVERqpFeNeRrsW79va11toztoiIiMjgU4uIiIiIiIgfaQZbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPgofqGxljHgauBKqttdNOM24esA643lr79zNdNykpyebm5vqtThERERGRk9m0aVOttTb5TOOGLGADjwL3A4+daoAxxgH8Eni1rxfNzc2loKDgrIsTERERETkdY0xxX8YNWYuItXYNUH+GYXcCTwPVg1+RiIiIiIj/DZsebGNMJvBx4IE+jF1ljCkwxhTU1NQMfnEiIiIiIn00bAI2cA/wHWut+0wDrbUPWmvnWmvnJiefsQ1GRERERGTIDGUP9pnMBZ40xgAkASuNMT3W2mcDW5aIiIiISN8Nm4BtrR370a+NMY8CLypci4iIiMhIM5TL9K0GlgBJxpgy4C7ACWCtPWPftYiIiIjISDBkAdtae0M/xt4yiKWctYrGDm5+eAPfXDaBFdPTA12OiIiIiAwjw+khxxEjMiSYA9WtlDd2BLoUERERERlmFLAHICY8mOAgQ11bd6BLEREREZFhRgF7AIwxJEaFUNfaFehSRERERGSYUcAeoMTIUOpaNYMtIiIiIsdSwB6gxKgQatUiIiIiIiLHUcAeoKSoULWIiIiIiMgJFLAHKDEyRC0iIiIiInICBewBSooOpcPlpr27J9CliIiIiMgwooA9QImRIQDUtmgWW0RERET+jwL2ACVFhQJQ26Y+bBERERH5PwrYA5QY5Z3BVh+2iIiIiPSmgD1Aib4ZbK0kIiIiIiK9KWAP0Ec92NouXURERER6U8AeoDCng6jQYGo1gy0iIiIivShgn4XEKK2FLSIiIiLHUsA+C0lRodRpFRERERER6UUB+yxoN0cREREROZ4C9llIjApVD7aIiIiIHEMB+ywkRYVQ39aN22MDXYqIiIiIDBMK2GchMTIEj4XGdrWJiIiIiIiXAvZZOLrZjNbCFhEREREfBeyz8NF26erDFhEREZGPDFnANsY8bIypNsbsPMX5m4wx231fHxpjZg5VbQOVfHS7dM1gi4iIiIjXUM5gPwosP835Q8DF1toZwE+AB4eiqLNxtEVEM9giIiIi4hM8VN/IWrvGGJN7mvMf9nq5Dsga7JrOVly4kyCjHmwRERER+T/DtQf7C8DLpzppjFlljCkwxhTU1NQMYVnHCgoyJESGUqsWERERERHxGXYB2xhzCd6A/Z1TjbHWPmitnWutnZucnDx0xZ1EUlSIHnIUERERkaOGrEWkL4wxM4CHgBXW2rpA19MXiVEh6sEWERERkaOGzQy2MSYH+AfwOWttYaDr6avEyFD1YIuIiIjIUUM2g22MWQ0sAZKMMWXAXYATwFr7APAjIBH4vTEGoMdaO3eo6hso7wy2AraIiIiIeA3lKiI3nOH8bcBtQ1SO3yRFhdLa1UOny02Y0xHockREREQkwIZNi8hIleTbzVFtIiIiIiICCthnLTFSm82IiIiIyP9RwD5LiR/NYKsPW0RERERQwD5rSb7t0ms0gy0iIiIiKGCftZSYUKJDg1l3cEQs2y0iIiIig0wB+yyFBju4dnYmL+6opLFdbSIiIiIi5zoFbD+4YX4O3T0entlSHuhSRERERCTAFLD9YEpGDDOz43hifQnW2kCXIyIiIiIBpIDtJzfOz2Z/dSubihsCXYqIiIiIBJACtp9cOSODqNBgnthQEuhSRERERCSAFLD9JDI0mGtnZ/DS9kqa2l2BLkdEREREAkQB249umJ9DV4+HX766F49HvdgiIiIi5yIFbD+amhHLbYvG8sT6Eu58cgudLnegSxIRERGRIRYc6AJGmx9cMZnUmDB+9s891LR08bNrpzEuOQpHkAl0aSIiIiIyBBSw/cwYwxcXjyMlJpRv/W0by/57DeFOB5PTo7lyRgY3LsghzOkIdJkiIiIiMkjMSF+3ee7cubagoCDQZZxUaX07Gw7Vs7Oiic3FDWwrayItJow7l+YzOzuemtYu6lq7mJEVS35KdKDLFREREZHTMMZsstbOPeM4Beyh8+GBWn712j62lDQeczw4yPCVS/L56iV5hAZrdltERERkOOprwFaLyBC6MD+Jf+QlsraojqZ2F8nRoUSHOXng3YPc9+Z+XtlZybc+NpGF+UlEhuq3RkRERGQk0gz2MPHW3ip+8MxOKps6cToM542J59JJKaycnk5WfESgyxMRERE556lFZATq6nFTcLiBNYU1vFtYw94jLQDMzonjY1PSWJifyNSMWK1IIiIiIhIACtijQHFdGy/tqOTFbZXsrmwGIDosmEX5SayYns7SSSlqJREREREZIsMuYBtjHgauBKqttdNOct4A9wIrgXbgFmvt5jNddzQH7N6qWzpZe7CODw/U8da+ampauggNDmL5tDS+ftkEcpMiA12iiIiIyKg2HAP2YqAVeOwUAXslcCfegL0AuNdau+BM1z1XAnZvbo9lU3EDL22v4G+byuju8XDTghxuX5JPakwo3r+riIiIiIg/DbtVRKy1a4wxuacZcg3e8G2BdcaYOGNMurW2ckgKHEEcQYb5YxOYPzaBr16az71v7Ocv60v409pi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MyuDF7ZV8FRBGXsqm7lscgr/ed1MEvrQM/6TF3fzpw8Ps+bfLjnhLyZDaTgG7E8Blx8XsOdba+88ydhLgN8Di6y1dSc5vwpYBZCTk3NecXHxoNYuIiIiMhq1dLrYUtLIpuIGqlu6aO500dTuorKpg7KGDrp6PMzKjuPBz513wjrgHd1u/rmjkic3lrC5pBG358RMOS0zht98ehYTUqOPHrPW8sgHh7n75b3ERzr59uWTCA0OotPlxmMtYU4H4U4HESHBhIc4cAQZbvrjOi6bksq9n5k96PfkdIZjwO5Ti4gxZgbwDLDCWlt4putqBltERETE/6y11Ld1Ex8RctK1v3vr6Hazq6KJbWVNuD0eJqXFMCk9mpToUz9oubO8iX9dvYWi2rY+1fPinYuYlhnbr8/gb8MxYAfjfchxKVCO9yHHG621u3qNyQHeAm621n7Yl+sqYIuIiIiMTJ0uNweqWwkNDiI02EFQEHS6PHR0u+lwuWnv7qHT5SYmzMmF+UmBLnf4rYNtre0xxtwBvIp3mb6HrbW7jDFf9p1/APgRkAj83tdT1NOXDyEiIiIiI0+Y0xHwWenBoJ0cRURERET6oK8z2IHZyF1EREREZJRSwBYRERER8SMFbBERERERP1LAFhERERHxIwVsERERERE/UsAWEREREfGjEb9MnzGmBgjUXulJQG2AvvdIpPvVP7pf/aP71T+6X/2j+9U/ul/9o/vVP4G8X2OstclnGjTiA3YgGWMKtBFO3+l+9Y/uV//ofvWP7lf/6H71j+5X/+h+9c9IuF9qERERERER8SMFbBERERERP1LAPjsPBrqAEUb3q390v/pH96t/dL/6R/erf3S/+kf3q3+G/f1SD7aIiIiIiB9pBltERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFb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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))\n", "fig.suptitle('Training Metrics')\n", "\n", - "axes[0].set_ylabel(\"Loss\", fontsize=14)\n", + "axes[0].set_ylabel(\"loss\", fontsize=14)\n", "axes[0].plot(train_loss_results)\n", "\n", "axes[1].set_ylabel(\"Accuracy\", fontsize=14)\n", - "axes[1].set_xlabel(\"Epoch\", fontsize=14)\n", + "axes[1].set_xlabel(\"epoch\", fontsize=14)\n", "axes[1].plot(train_accuracy_results);" ] }, @@ -1003,7 +1170,7 @@ " prediction = tf.argmax(logits, axis=1, output_type=tf.int32)\n", " test_accuracy(prediction, y)\n", "\n", - "print(\"Test set accuracy: {:.3%}\".format(test_accuracy.result()))" + "print(\"테스트셋 정확도: {:.3%}\".format(test_accuracy.result()))" ] }, { @@ -1068,7 +1235,7 @@ " class_idx = tf.argmax(logits).numpy()\n", " p = tf.nn.softmax(logits)[class_idx]\n", " name = class_names[class_idx]\n", - " print(\"Example {} prediction: {} ({:4.1f}%)\".format(i, name, 100*p))" + " print(\"예 {} 예측: {} ({:4.1f}%)\".format(i, name, 100*p))" ] } ], @@ -1096,7 +1263,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.1" + "version": "3.6.7" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 87c95fe4d1c..680d7fc1558 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -93,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "cellView": "code", "colab": {}, @@ -116,7 +116,7 @@ "source": [ "## 텐서\n", "\n", - "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 형태를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 계산하는 풍부한 연산 라이브러리를 제공합니다. ([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.). 이러한 연산자들은 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" + "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 형태를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 계산하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자들은 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" ] }, { @@ -136,7 +136,7 @@ "print(tf.reduce_sum([1, 2, 3]))\n", "print(tf.encode_base64(\"hello world\"))\n", "\n", - "# Operator overloading is also supported\n", + "# 연산자의 오버로딩 또한 지원합니다.\n", "print(tf.square(2) + tf.square(3))" ] }, @@ -172,7 +172,7 @@ "id": "eBPw8e8vrsom" }, "source": [ - "넘파이 `ndarray`와 `Tensor`의 가장 확실한 차이는 다음과 같습니다:\n", + "넘파이 `ndarray`와 텐서플로 `Tensor`의 가장 확연한 차이는 다음과 같습니다:\n", "\n", "1. `Tensor`는 가속기 메모리(GPU, TPU와 같은)의 사용이 가능합니다.\n", "2. `Tensor`는 불변성(immutable)을 가집니다." @@ -189,8 +189,8 @@ "\n", "`Tensor`와 `ndarray`사이의 전환은 다소 간단합니다.\n", "\n", - "* 텐서플로 연산는 자동적으로 넘파이 ndarray를 Tensor로 전환합니다.\n", - "* 넘파이 연산는 자동적으로 텐서플로 Tensor를 넘파이 ndarray로 전환합니다.\n", + "* 텐서플로 연산은 자동적으로 넘파이 ndarray를 Tensor로 전환합니다.\n", + "* 넘파이 연산은 자동적으로 텐서플로 Tensor를 넘파이 ndarray로 전환합니다.\n", "\n", "Tensor는 `.numpy()` 메서드(method)를 호출하여 넘파이 ndarray로 전환할 수 있습니다.\n", "가능한 경우, Tensor와 ndarray은 메모리 표현을 공유하기 때문에 이러한 전환은 일반적으로 간단(저렴)합니다. 그러나 Tensor는 GPU 메모리에 저장될 수 있고, 넘파이 ndarray은 항상 호스트 메모리에 백업이 되므로, 이러한 전환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 포함됩니다." @@ -210,15 +210,15 @@ "\n", "ndarray = np.ones([3, 3])\n", "\n", - "print(\"TensorFlow operations convert numpy arrays to Tensors automatically\")\n", + "print(\"텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 전환합니다.\")\n", "tensor = tf.multiply(ndarray, 42)\n", "print(tensor)\n", "\n", "\n", - "print(\"And NumPy operations convert Tensors to numpy arrays automatically\")\n", + "print(\"그리고 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 전환합니다.\")\n", "print(np.add(tensor, 1))\n", "\n", - "print(\"The .numpy() method explicitly converts a Tensor to a numpy array\")\n", + "print(\".numpy() 메서드는 텐서를 넘파이 배열로 전환시킵니다.\")\n", "print(tensor.numpy())" ] }, @@ -236,21 +236,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "cellView": "code", "colab": {}, "colab_type": "code", "id": "3Twf_Rw-gQFM" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GPU를 사용가능한가 : \n", + "False\n", + "텐서가 GPU #0에 있는가 : \n", + "False\n" + ] + } + ], "source": [ "x = tf.random_uniform([3, 3])\n", "\n", - "print(\"Is there a GPU available: \"),\n", + "print(\"GPU 사용이 가능한가 : \"),\n", "print(tf.test.is_gpu_available())\n", "\n", - "print(\"Is the Tensor on GPU #0: \"),\n", + "print(\"텐서가 GPU #0에 있는가 : \"),\n", "print(x.device.endswith('GPU:0'))" ] }, @@ -263,7 +274,7 @@ "source": [ "### 장치 이름\n", "\n", - "`Tensor.device`는 Tensor를 구성하고 있는 호스트 장치의 풀네임을 제공합니다. 이러한 이름은 프로그램이 실행중인 호스트의 네트워크 주소 및 해당 호스트 내의 장치와 같은 많은 세부 정보를 인코딩하며, 이것은 텐서플로 프로그램의 분산 실행에 필요합니다. Tensor가 호스트의 `N`번째 GPU에 놓여지면 문자열은 `GPU:` 끝납니다." + "`Tensor.device`는 Tensor를 구성하고 있는 호스트 장치의 풀네임을 제공합니다. 이러한 이름은 프로그램이 실행중인 호스트의 네트워크 주소 및 해당 호스트 내의 장치와 같은 많은 세부 정보를 인코딩하며, 이것은 텐서플로 프로그램의 분산 실행에 필요합니다. Tensor가 호스트의 `N`번째 GPU에 놓여지면 문자열은 `GPU:`으로 끝납니다." ] }, { @@ -333,7 +344,7 @@ "\n", "만약 텐서플로 그래프에 익숙하다면, `Dataset` 객체를 생성하기 위한 API는 즉시실행이 활성화 되어도 동일하게 유지됩니다. 하지만 그러나 데이터셋의 요소를 반복하는 프로세스는 약간 더 간단합니다.\n", "또한 `tf.data.Dataset` 객체를 통하여 파이썬 반복문을 사용할 수 있으며, 명시적으로 `tf.data.Iterator` 객체를 생성할 필요가 없습니다.\n", - "그 결과, [TensorFlow Guide](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시실행이 활성화될 때에는 관계없습니다. " + "그 결과, [텐서플로 가이드](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시실행이 활성화될 때에는 관계없습니다. " ] }, { @@ -343,9 +354,9 @@ "id": "zI0fmOynH-Ne" }, "source": [ - "### `Dataset`소스 생성\n", + "### `Dataset` 소스 생성\n", "\n", - "굉장히 유용한 함수중 하나인 [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices)를 사용하여 데이터셋 소스를 생성하거나 or 파일로부터 읽어들이는 객체인 [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) 또는 [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset)를 사용하여 데이터셋 소스를 생성하세요. 더 많은 정보는 [TensorFlow Guide](https://www.tensorflow.org/guide/datasets#reading_input_data) 를 참조하세요." + "굉장히 유용한 함수중 하나인 [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices)를 사용하여 데이터셋 소스를 생성하거나 파일로부터 읽어들이는 객체인 [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) 또는 [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset)를 사용하여 데이터셋 소스를 생성하세요. 더 많은 정보를 위해서 [텐서플로 가이드](https://www.tensorflow.org/guide/datasets#reading_input_data)를 참조하세요." ] }, { @@ -360,7 +371,7 @@ "source": [ "ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6])\n", "\n", - "# Create a CSV file\n", + "# CSV 파일 생성\n", "import tempfile\n", "_, filename = tempfile.mkstemp()\n", "\n", @@ -382,7 +393,7 @@ "source": [ "### 변환 적용\n", "\n", - "[`map`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`batch`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`shuffle`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle)와 같은 변환 함수를 사용하세요. 또한 데이터셋의 레코드에 변환을 적용하세요. 세부사항은 [API documentation for `tf.data.Dataset`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)을 참조하세요." + "[`map`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`batch`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`shuffle`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle)과 같은 변환 함수를 사용하세요. 또한 데이터셋의 레코드에 변환을 적용하세요. 세부사항은 [`tf.data.Dataset`을 위한 API 문서](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)을 참조하세요." ] }, { @@ -422,11 +433,11 @@ }, "outputs": [], "source": [ - "print('Elements of ds_tensors:')\n", + "print('ds_tensors 요소:')\n", "for x in ds_tensors:\n", " print(x)\n", "\n", - "print('\\nElements in ds_file:')\n", + "print('\\nds_file 요소:')\n", "for x in ds_file:\n", " print(x)" ] @@ -456,7 +467,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.1" + "version": "3.6.7" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md index 3f275517e37..e75df364cb0 100644 --- a/site/ko/tutorials/eager/index.md +++ b/site/ko/tutorials/eager/index.md @@ -14,8 +14,8 @@ [eager execution guide](../../guide/eager). 1. [즉시실행(Eager execution)](eager_basics.ipynb) -2. [Automatic differentiation and gradient tape](automatic_differentiation.ipynb) -3. [사용자 정의 학습 : 기본(Custom training: basics)](custom_training.ipynb) +2. [자동미분과 그래디언트 테이프(Automatic differentiation and gradient tape)](automatic_differentiation.ipynb) +3. [사용자 정의 학습 : 기초(Custom training: basics)](custom_training.ipynb) 4. [사용자 정의 layer(Custom layers)](custom_layers.ipynb) 5. [사용자 정의 학습 : walkthrough(Custom training: walkthrough)](custom_training_walkthrough.ipynb) From c2ef77e7384b083b74af784849e19c202d003f0d Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Tue, 2 Apr 2019 17:48:34 +0900 Subject: [PATCH 07/19] Update from 61caa152 edit common mistakes --- .../eager/automatic_differentiation.ipynb | 39 ++++++++-------- site/ko/tutorials/eager/custom_layers.ipynb | 16 +++---- site/ko/tutorials/eager/custom_training.ipynb | 8 ++-- .../eager/custom_training_walkthrough.ipynb | 44 +++++++++---------- site/ko/tutorials/eager/eager_basics.ipynb | 30 ++++++------- 5 files changed, 69 insertions(+), 68 deletions(-) diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index 59dcf5dc7ed..6d927d99ecc 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -41,7 +41,7 @@ "id": "xh8WkEwWpnm7" }, "source": [ - "# 자동미분(Automatic Differentiation)과 그래디언트 테이프(Gradient Tape)" + "# 자동 미분과 그래디언트 테이프" ] }, { @@ -56,10 +56,10 @@ " View on TensorFlow.org\n", " \n", " \n", - " Run in Google Colab\n", + " Run in Google Colab\n", " \n", " \n", - " View source on GitHub\n", + " View source on GitHub\n", " \n", "" ] @@ -71,7 +71,7 @@ "id": "vDJ4XzMqodTy" }, "source": [ - "이전 튜토리얼에서 우리는 텐서(tensor)와 텐서의 연산들에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술 중 하나인 [자동미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." + "이전 튜토리얼에서는 텐서(tensor)와 텐서의 연산들에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술 중 하나인 [자동 미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." ] }, { @@ -106,9 +106,9 @@ "id": "1CLWJl0QliB0" }, "source": [ - "## 그래디언트 테이프(Gradient Tape)\n", + "## 그래디언트 테이프\n", "\n", - "텐서플로는 자동미분(주어진 입력 변수에 따른 그래디언트 연산)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape`는 안에서 실행된 모든 연산을 tape에 \"기록\"합니다. 그리고 [역방향 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 각각의 기록된 연산들과 관련된 테이프와 그래디언트들을 사용하여 기록된 연산의 그래디언트를 계산합니다. \n", + "텐서플로는 자동 미분(주어진 입력 변수에 대한 연산의 그래디언트(gradient)를 계산하는 것)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape`는 안에서 실행된 모든 연산을 테이프(tape)에 \"기록\"합니다. 그리고 [후진 방식 자동 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 각각의 기록된 연산과 관련된 그래디언트와 테이프를 사용하여 기록된 연산의 그래디언트를 계산합니다. \n", "\n", "예를 들면:" ] @@ -130,7 +130,7 @@ " y = tf.reduce_sum(x)\n", " z = tf.multiply(y, y)\n", "\n", - "# 입력 tensor x에 관한 z의 도함수\n", + "# 입력 텐서 x에 대한 z의 도함수\n", "dz_dx = t.gradient(z, x)\n", "for i in [0, 1]:\n", " for j in [0, 1]:\n", @@ -144,7 +144,7 @@ "id": "N4VlqKFzzGaC" }, "source": [ - "또한 `tf.GradientTape` 컨텍스트에 기록되는 동안 계산된 중간 출력값의 그래디언트를 계산할 수 있습니다." + "또한 `tf.GradientTape` 컨텍스트 안에서 기록되는 동안 계산된 중간 값에 대한 그래디언트도 구할 수 있습니다." ] }, { @@ -164,7 +164,7 @@ " y = tf.reduce_sum(x)\n", " z = tf.multiply(y, y)\n", "\n", - "# 중간값 y에 관한 z의 도함수 계산을 위한 테이프 사용\n", + "# 테이프 사용하여 중간 값 y에 대한 도함수를 계산합니다. \n", "dz_dy = t.gradient(z, y)\n", "assert dz_dy.numpy() == 8.0" ] @@ -176,7 +176,8 @@ "id": "ISkXuY7YzIcS" }, "source": [ - "초기값으로 GradientTape.gradient() 메서드가 호출되면 GradientTape에 포함된 리소스가 해체되게 설정돼있습니다. 동일한 연산을 통해서 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. `persistent`는 `gradient()` 메서드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다." + "기본적으로 GradientTape.gradient() 메서드가 호출되면 GradientTape에 포함된 리소스가 해제됩니다. 동일한 연산을 대해 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. 이 그래디언트 테이프는 `gradient()` 메서드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다.\n", + "예를 들면 다음과 같습니다:" ] }, { @@ -196,7 +197,7 @@ " z = y * y\n", "dz_dx = t.gradient(z, x) # 108.0 (4*x^3 at x = 3)\n", "dy_dx = t.gradient(y, x) # 6.0\n", - "del t # 리소스가 해체됩니다." + "del t # 테이프에 대한 참조를 삭제합니다." ] }, { @@ -206,9 +207,9 @@ "id": "6kADybtQzYj4" }, "source": [ - "### 제어흐름(Control Flow) 기록\n", + "### 제어 흐름 기록\n", "\n", - "테이프를 실행하는 순간부터 연산을 기록하기 때문에, 파이썬 제어흐름(예를 들어 `if` `while`, `for`문 같은)은 자연스럽게 처리됩니다. " + "연산이 실행되는 순서대로 테이프에 기록되기 때문에, 파이썬 제어 흐름(예를 들어 `if` `while`, `for`문 같은)이 자연스럽게 처리됩니다. " ] }, { @@ -248,9 +249,9 @@ "id": "DK05KXrAAld3" }, "source": [ - "### 고차원(Higher-order) 그래디언트\n", + "### 고계도(Higher-order) 그래디언트\n", "\n", - "`GradientTape` 컨텍스트 매니저안에 있는 연산들은 자동미분을 위해 기록됩니다. 만약 그래디언트가 컨텍스트 안에서 연산되면 그래디언트 연산 또한 기록되어집니다. 그 결과 똑같은 API가 고차원 그래디언트에서도 잘 작동합니다. 예를 들면:" + "`GradientTape` 컨텍스트 매니저안에 있는 연산들은 자동미분을 위해 기록됩니다. 만약 그래디언트가 컨텍스트 안에서 계산되면 그 그래디언트 연산 또한 기록되어집니다. 그 결과 똑같은 API가 고계도 그래디언트에서도 잘 작동합니다. 예를 들면:" ] }, { @@ -263,13 +264,13 @@ }, "outputs": [], "source": [ - "x = tf.Variable(1.0) # 1.0으로 초기화된 텐서플로 변수 생성\n", + "x = tf.Variable(1.0) # 1.0으로 초기화된 텐서플로 변수를 생성합니다.\n", "\n", "with tf.GradientTape() as t:\n", " with tf.GradientTape() as t2:\n", " y = x * x * x\n", - " # t 컨텍스트 매니저 안의 그래디언트 연산\n", - " # 이것은 또한 그래디언트 계산이 미분가능하다는것을 의미합니다. \n", + " # t 컨텍스트 매니저 안의 그래디언트를 계산합니다.\n", + " # 이것은 또한 그래디언트 연산 자체도 미분가능하다는것을 의미합니다. \n", " dy_dx = t2.gradient(y, x)\n", "d2y_dx2 = t.gradient(dy_dx, x)\n", "\n", @@ -286,7 +287,7 @@ "source": [ "## 다음 단계\n", "\n", - "이번 튜토리얼에서는 텐서플로에서 그래디언트 계산법을 배웠습니다. 이를 통해 우리는 신경망(neural network)을 구축하고 훈련시키는 데 필요한 기본 요소를 충분히 확보할 수 있습니다." + "이번 튜토리얼에서는 텐서플로에서 그래디언트 계산법을 다루었습니다. 이를 통해 신경망(neural network)을 구축하고 훈련시키는데 필요한 많은 기본 요소를 배웠습니다." ] } ], diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index 29fc33e0c31..f85d0e46f34 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -56,10 +56,10 @@ " View on TensorFlow.org\n", " \n", " \n", - " Run in Google Colab\n", + " Run in Google Colab\n", " \n", " \n", - " View source on GitHub\n", + " View source on GitHub\n", " \n", "" ] @@ -71,7 +71,7 @@ "id": "UEu3q4jmpKVT" }, "source": [ - "신경망을 구축하기 위해서 고수준 API인 `tf.keras`를 사용하길 권합니다. 대부분의 텐서플로 API는 즉시실행(eager execution)을 활성화할 수 있습니다." + "신경망을 구축하기 위해서 고수준 API인 `tf.keras`를 사용하길 권합니다. 대부분의 텐서플로 API는 즉시 실행(eager execution)을 활성화할 수 있습니다." ] }, { @@ -98,7 +98,7 @@ "source": [ "## layer: 유용한 연산자 집합\n", "\n", - "머신러닝을 위한 코드를 작성하는 대부분의 시간에 우리는, 개별적인 연산과 변수를 조작하는 것보다는 고수준의 추상화 수준에서 작업하기를 원합니다.\n", + "머신러닝을 위한 코드를 작성하는 대부분의 시간동안 개별적인 연산과 변수를 조작하는 것보다는 고수준의 추상화 수준에서 작업하기를 원합니다.\n", "\n", "많은 머신러닝 모델은 비교적 단순한 layer의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로는 여러 표준 layer 세트를 제공하므로 사용자 고유의 응용 프로그램에 관련된 layer를 처음부터 작성하거나, 기존 layer의 구성으로 쉽게 작성할 수 있습니다.\n", "\n", @@ -118,7 +118,7 @@ "# tf.keras.layers 패키지에서 layer는 객체입니다. layer를 구성하려면 간단히 객체를 생성하십시오.\n", "# 대부분의 layer는 첫번째 인수로 출력 차원(크기) 또는 채널을 취합니다.\n", "layer = tf.keras.layers.Dense(100)\n", - "# 입력 차원의 수는 유추될 수 있기 때문에 종종 불필요합니다. \n", + "# 입력 차원의 수는 유추할 수 있기 때문에 종종 불필요합니다. \n", "# 일부 복잡한 모델에서는 수동으로 입력 차원의 수를 제공하는것이 유용할 수 있습니다.\n", "layer = tf.keras.layers.Dense(10, input_shape=(None, 5))" ] @@ -159,7 +159,7 @@ "source": [ "# layer는 유용한 메서드들을 내재하고있습니다. 예를 들어, `layer.variables`를 사용하여 layer안에 있는 모든 변수들을 확인할 수 있으며, \n", "# `layer.trainable_variables`를 사용하여 학습가능한 변수들을 확인할 수 있습니다. \n", - "# 이번 케이스에서 완전 연결(fully-connected) 레이어는 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", + "# 이번 케이스에서 완전연결(fully-connected) 레이어는 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", "layer.variables" ] }, @@ -242,7 +242,7 @@ "source": [ "## 모델: layer 구성\n", "\n", - "머신러닝 모델에서 대부분의 흥미로운 유사 layer(layer-likely)는 layer들의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 잔여블록(residual block)은 합성곱(convolution), 배치정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", + "머신러닝 모델에서 대부분의 흥미로운 유사 layer(layer-likely)는 layer들의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 잔여 블록(residual block)은 합성곱(convolution), 배치 정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", "\n", "layer 집합을 포함한 유사 layer를 생성하기위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현합니다." ] @@ -321,7 +321,7 @@ "source": [ "# 다음 단계\n", "\n", - "이제 여러분들은 이전 노트북으로 돌아가서 선형 회귀 예제에 좀 더 나은 구조를 만들기 위해 layer와 모델을 적용할 수 있습니다." + "이제 이전 노트북으로 돌아가서 선형 회귀 예제에 좀 더 나은 구조를 만들기 위해 layer와 모델을 적용할 수 있습니다." ] } ], diff --git a/site/ko/tutorials/eager/custom_training.ipynb b/site/ko/tutorials/eager/custom_training.ipynb index 58c48d95445..1385cb3736a 100644 --- a/site/ko/tutorials/eager/custom_training.ipynb +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -56,10 +56,10 @@ " View on TensorFlow.org\n", " \n", " \n", - " Run in Google Colab\n", + " Run in Google Colab\n", " \n", " \n", - " View source on GitHub\n", + " View source on GitHub\n", " \n", "" ] @@ -71,7 +71,7 @@ "id": "k2o3TTG4TFpt" }, "source": [ - "이전 튜토리얼에서 우리는 머신러닝을 위한 기초 빌딩 블록인 자동미분(automatic differentiation)을 위한 텐서플로 API들을 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 초기 타입의 텐서플로를 사용하여 간단한 머신러닝을 구축해보겠습니다. \n", + "이전 튜토리얼에서는 머신러닝을 위한 기초 빌딩 블록인 자동 미분(automatic differentiation)을 위한 텐서플로 API들을 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 초기 타입의 텐서플로를 사용하여 간단한 머신러닝을 구축해보겠습니다. \n", "\n", "텐서플로는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 `tf.keras`를 포함하고 있습니다. 신경망에 관련하여 일을 하고 있는 사람들에게는 이러한 고수준의 API들을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " ] @@ -134,7 +134,7 @@ "source": [ "# 파이썬 state 사용\n", "x = tf.zeros([10, 10])\n", - "x += 2 # 이것은 x = x + 2 같으며, 초기값 x를 변경하지 않습니다.\n", + "x += 2 # 이것은 x = x + 2와 같으며, 초기값 x를 변경하지 않습니다.\n", "print(x)" ] }, diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index bcd0765d937..99b8486f785 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -56,10 +56,10 @@ " View on TensorFlow.org\n", " \n", " \n", - " Run in Google Colab\n", + " Run in Google Colab\n", " \n", " \n", - " View source on GitHub\n", + " View source on GitHub\n", " \n", "" ] @@ -71,7 +71,7 @@ "id": "LDrzLFXE8T1l" }, "source": [ - "이번 튜토리얼은 붓꽃의 품종을 분류하기 위한 머신러닝 모델을 구축할 것입니다. 다음을 위해 즉시실행[(eager execution)](https://www.tensorflow.org/guide/eager)을 사용합니다.\n", + "이번 튜토리얼은 붓꽃의 품종을 분류하기 위한 머신러닝 모델을 구축할 것입니다. 다음을 위해 즉시 실행[(eager execution)](https://www.tensorflow.org/guide/eager)을 사용합니다.\n", "1. 모델 구축\n", "2. 모델 훈련\n", "3. 예측을 위한 모델 사용\n", @@ -80,9 +80,9 @@ "\n", "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로의 개념들을 사용합니다.\n", "\n", - "* [즉시실행(eager execution)](https://www.tensorflow.org/guide/eager) 개발환경,\n", - "* [Datasets API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 불러오기,\n", - "* [Keras API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 layer 구축 .\n", + "* [즉시 실행(eager execution)](https://www.tensorflow.org/guide/eager) 개발환경,\n", + "* [데이터셋 API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 불러오기,\n", + "* [케라스 API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 layer 구축 .\n", "\n", "이번 튜토리얼은 다른 텐서플로 프로그램과 유사하게 구성되어있습니다.\n", "\n", @@ -110,11 +110,11 @@ "id": "1J3AuPBT9gyR" }, "source": [ - "### 임포트 및 즉시실행 구성\n", + "### 임포트 및 즉시 실행 구성\n", "\n", - "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시실행을 활성화할 것입니다. 즉시실행은 텐서플로가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", + "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화할 것입니다. 즉시 실행은 텐서플로가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", "\n", - "즉시실행이 활성화 될때, 동일한 프로그램내에서는 비활성화를 할 수 없습니다. 더 많은 세부사항은 [즉시실행 가이드](https://www.tensorflow.org/guide/eager)을 참조하세요." + "즉시 실행이 활성화 될때, 동일한 프로그램내에서는 비활성화를 할 수 없습니다. 더 많은 세부사항은 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)을 참조하세요." ] }, { @@ -146,7 +146,7 @@ "tf.enable_eager_execution()\n", "\n", "print(\"텐서플로 버전: {}\".format(tf.__version__))\n", - "print(\"즉시실행: {}\".format(tf.executing_eagerly()))" + "print(\"즉시 실행: {}\".format(tf.executing_eagerly()))" ] }, { @@ -158,7 +158,7 @@ "source": [ "## 붓꽃 분류 문제\n", "\n", - "당신이 식물학자라고 상상하고, 주어진 붓꽃을 자동적으로 분류하는 방법을 찾고있다고 가정합시다. 머신러닝은 통계적으로 꽃을 분류할 수 있는 다양한 알고리즘을 제공합니다. 예를 들어, 정교한 머신러닝 프로그램은 사진을 통해 꽃을 분류할 수 있습니다. 우리의 목적은 좀 더 겸손하게, 측정된 [꽃받침](https://en.wikipedia.org/wiki/Sepal)과 [꽃잎](https://en.wikipedia.org/wiki/Petal)의 길이와 폭을 토대로 붓꽃을 분류하는것입니다.\n", + "당신이 식물학자라고 상상하고, 주어진 붓꽃을 자동적으로 분류하는 방법을 찾고있다고 가정합시다. 머신러닝은 통계적으로 꽃을 분류할 수 있는 다양한 알고리즘을 제공합니다. 예를 들어, 정교한 머신러닝 프로그램은 사진을 통해 꽃을 분류할 수 있습니다. 이번 튜토리얼의 목적은 좀 더 겸손하게, 측정된 [꽃받침](https://en.wikipedia.org/wiki/Sepal)과 [꽃잎](https://en.wikipedia.org/wiki/Petal)의 길이와 폭을 토대로 붓꽃을 분류하는것입니다.\n", "\n", "이 붓꽃은 약 300종 입니다. 하지만 이번 튜토리얼에서는 오직 3가지 품종을 기준으로 분류할 것입니다. \n", "\n", @@ -261,7 +261,7 @@ " * 총 120개의 예가 있으며, 각 예들은 4가지의 특성(feature), 3가지 가능한 레이블(label)을 가지고 있습니다.\n", "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[예](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 예제의 특징을 나타냅니다. 이 필드들는 붓꽃의 측정값을 부동소수점으로 나타냅니다.\n", - " * 마지막 컬럼(column)은 *[레이블(label)](https://developers.google.com/machine-learning/glossary/#label)*입니다.: 레이블은 우리가 에측하고자 하는 값을 나타냅니다. 이 데이터셋에서는 꽃의 이름과 관련된 정수값 0, 1, 2를 나타냅니다.\n", + " * 마지막 컬럼(column)은 *[레이블(label)](https://developers.google.com/machine-learning/glossary/#label)*입니다.: 레이블은 예측하고자 하는 값을 나타냅니다. 이 데이터셋에서는 꽃의 이름과 관련된 정수값 0, 1, 2를 나타냅니다.\n", "\n", "코드로 표현하면 다음과 같습니다.:" ] @@ -367,7 +367,7 @@ }, "source": [ "`make_csv_dataset` 함수는 `tf.data.Dataset` 의 `(features, label)` 쌍을 반환합니다. `features`는 사전형 객체인: `{'feature_name': value}`로 주어집니다.\n", - "또한 즉시실행 활성화로 이 `Dataset`은 반복가능합니다. 다음은 특성(feature)들을 살펴봅시다." + "또한 즉시 실행 활성화로 이 `Dataset`은 반복가능합니다. 다음은 특성(feature)들을 살펴봅시다." ] }, { @@ -565,7 +565,7 @@ "\n", "### 모델 선정\n", "\n", - "우리는 학습을 위한 모델의 종류를 선정해야합니다. 여러정류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*들로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[dense(또는 fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전연결 신경망입니다. \n", + "이제 학습을 위한 모델의 종류를 선정해야합니다. 여러 종류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*들로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[dense(또는 fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전연결 신경망입니다. \n", "\n", "\n", " \n", "
\n", @@ -713,7 +713,7 @@ "id": "uRZmchElo481" }, "source": [ - "`tf.argmax`는 예측된 값들 중 가장 큰 확률(우리가 원하는 클래스)을 반환합니다. 하지만 모델이 아직 훈련되지 않았으므로 이는 좋은 예측이 아닙니다." + "`tf.argmax`는 예측된 값들 중 가장 큰 확률(원하는 클래스)을 반환합니다. 하지만 모델이 아직 훈련되지 않았으므로 이는 좋은 예측이 아닙니다." ] }, { @@ -762,7 +762,7 @@ "source": [ "### 손실 함수와 그래디언트 함수 정의하기\n", "\n", - "훈련과 평가단계는 모델의 *[손실(loss)](https://developers.google.com/machine-learning/crash-course/glossary#loss)* 계산할 필요가 있습니다. 손실은 모델의 예측이 원하는 레이블과 얼마나 일치하는지, 또한 모델이 잘 작동하는지에 대한 척도로 사용됩니다. 우리는 이 값은 최소화하고, 최적화하기를 원합니다. \n", + "훈련과 평가단계는 모델의 *[손실(loss)](https://developers.google.com/machine-learning/crash-course/glossary#loss)* 계산할 필요가 있습니다. 손실은 모델의 예측이 원하는 레이블과 얼마나 일치하는지, 또한 모델이 잘 작동하는지에 대한 척도로 사용됩니다. 이 값은 최소화하고, 최적화하기를 원합니다. \n", "\n", "모델의 손실은 [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) 함수를 사용하여 계산할 것입니다. 이 함수는 모델의 클래스(레이블)과 예측된 값(로짓)을 입력받아 예제를 통한 평균 손실을 반환합니다." ] @@ -801,7 +801,7 @@ "id": "3IcPqA24QM6B" }, "source": [ - "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)* 계산하기위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 [즉시실행 가이드](https://www.tensorflow.org/guide/eager)를 확인하세요. " + "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)* 계산하기위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 확인하세요. " ] }, { @@ -829,7 +829,7 @@ "source": [ "### 옵티마이저(Optimizer) 생성 \n", "\n", - "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 `손실`함수를 최소화하기위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 우리는 이 함수의 최저점을 찾고자합니다. 그래디언트는 가장 가파른 상승방향을 가르키며 따라서 우리는 반대방향으로 이동하는 여행을 합니다.각 배치마다의 손실과 기울기를 반복적으로 계산하여 훈련 중에 모델을 조정합니다. 점진적으로, 모델은 손실을 최소화하기위해 가중치(weight)와 편향(bias)의 최적의 조합을 찾아냅니다. 더 적은 손실을 통해 더 좋은 모델의 예측을 기대할 수 있습니다. \n", + "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 `손실`함수를 최소화하기위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 이 함수의 최저점을 찾고자합니다. 그래디언트는 가장 가파른 상승방향을 가르키며 따라서 반대방향으로 이동하는 여행을 합니다.각 배치마다의 손실과 기울기를 반복적으로 계산하여 훈련 중에 모델을 조정합니다. 점진적으로, 모델은 손실을 최소화하기위해 가중치(weight)와 편향(bias)의 최적의 조합을 찾아냅니다. 더 적은 손실을 통해 더 좋은 모델의 예측을 기대할 수 있습니다. \n", "\n", "\n", " \n", " \n", " \n", "
\n", @@ -1006,9 +1006,9 @@ "id": "j3wdbmtLVTyr" }, "source": [ - "모델의 훈련 과정을 출력하는 것은 도움이 되지만, 훈련 과정을 직접 보는 것이 더 도움이 되곤합니다. [TensorBoard](https://www.tensorflow.org/guide/summaries_and_tensorboard)는 텐서플로에 패키지되어있는 굉장히 유용한 시각화 툴입니다. 하지만 우리는 `matplotlib` 모듈을 사용하여 일반적인 차트를 출력할 수 있습니다.\n", + "모델의 훈련 과정을 출력하는 것은 도움이 되지만, 훈련 과정을 직접 보는 것이 더 도움이 되곤합니다. [TensorBoard](https://www.tensorflow.org/guide/summaries_and_tensorboard)는 텐서플로에 패키지되어있는 굉장히 유용한 시각화 툴입니다. 하지만 `matplotlib` 모듈을 사용하여 일반적인 차트를 출력할 수 있습니다.\n", "\n", - "이 차트를 해석하는것은 여러 경험이 필요하지만, 우리는 *손실*이 내려가고 *정확도*가 올라가는 것을 보고싶습니다." + "이 차트를 해석하는것은 여러 경험이 필요하지만, 모델을 최적화하기위해 *손실*이 내려가고 *정확도*가 올라가는 것을 보고싶습니다." ] }, { @@ -1054,7 +1054,7 @@ "source": [ "## 모델 유효성 검증\n", "\n", - "이제 모델은 학습되었습니다. 우리는 모델의 성능을 검증하기위해 몇가지 통계를 얻을 수 있습니다. \n", + "이제 모델은 학습되었습니다. 모델의 성능을 검증하기위해 몇가지 통계를 얻을 수 있습니다. \n", "\n", "*평가(Evaluating)*는 모델이 예측을 얼마나 효과적으로 수행하는지 결정하는것을 의미합니다. 붓꽃 분류 모델의 유효성을 결정하기 위해서, 몇가지 꽃잎과 꽃받침 데이터를 통과시키고 어떠한 품종을 예측하는지 확인합니다. 그 후 실제 품종과 비교합니다. 예를 들어, 절반의 데이터를 올바르게 예측한 모델의 *[정확도](https://developers.google.com/machine-learning/glossary/#accuracy)* 는 `0.5`입니다. 그림 4는 조금 더 효과적인 보여줍니다. 5개의 예측 중 4개를 올바르게 예측한 80% 정확도의 모델입니다.\n", "\n", @@ -1205,7 +1205,7 @@ "source": [ "## 예측을 위해 훈련된 모델 사용하기\n", "\n", - "우리는 이제 붓꽃을 분류하기위해 완벽하지는 않지만 어느정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)들을 예측해봅시다.\n", + "이제 붓꽃을 분류하기위해 완벽하지는 않지만 어느정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)들을 예측해봅시다.\n", "\n", "실제로는 레이블되지 않은 예제들은 여러 소스(앱, CSV 파일, 직접제공 등)로 부터 제공될 수 있습니다. 지금은 레이블을 예측하기위해 수동으로 3개의 레이블되지 않은 예제를 제공하겠습니다. 레이블은 다음과 붓꽃이름으로 맵핑되어있습니다.\n", "* `0`: Iris setosa\n", diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 680d7fc1558..1d8a1522cd1 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -41,7 +41,7 @@ "id": "U9i2Dsh-ziXr" }, "source": [ - "# 즉시실행(eager execution) 기초" + "# 즉시 실행 기초" ] }, { @@ -56,10 +56,10 @@ " View on TensorFlow.org\n", " \n", - " Run in Google Colab\n", + " Run in Google Colab\n", " \n", - " View source on GitHub\n", + " View source on GitHub\n", "
" ] @@ -88,7 +88,7 @@ "source": [ "## 텐서플로 임포트\n", "\n", - "시작하기 위해서 텐서플로 모듈을 임포트하고 즉시실행(eager execution)을 활성화합니다. 즉시실행 활성화로 텐서플로에 대한 대화형 프론트엔드(frontend)가 가능합니다. 세부사항은 나중에 이야기할 것입니다." + "시작하기 위해서 텐서플로 모듈을 임포트하고 즉시 실행(eager execution)을 활성화합니다. 즉시 실행 활성화로 텐서플로에 대한 대화형 프론트엔드(frontend)가 가능합니다. 세부사항은 나중에 이야기할 것입니다." ] }, { @@ -189,11 +189,11 @@ "\n", "`Tensor`와 `ndarray`사이의 전환은 다소 간단합니다.\n", "\n", - "* 텐서플로 연산은 자동적으로 넘파이 ndarray를 Tensor로 전환합니다.\n", - "* 넘파이 연산은 자동적으로 텐서플로 Tensor를 넘파이 ndarray로 전환합니다.\n", + "* 텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 전환합니다.\n", + "* 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 전환합니다.\n", "\n", - "Tensor는 `.numpy()` 메서드(method)를 호출하여 넘파이 ndarray로 전환할 수 있습니다.\n", - "가능한 경우, Tensor와 ndarray은 메모리 표현을 공유하기 때문에 이러한 전환은 일반적으로 간단(저렴)합니다. 그러나 Tensor는 GPU 메모리에 저장될 수 있고, 넘파이 ndarray은 항상 호스트 메모리에 백업이 되므로, 이러한 전환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 포함됩니다." + "텐서는 `.numpy()` 메서드(method)를 호출하여 넘파이 배열로 전환할 수 있습니다.\n", + "가능한 경우, 텐서와 배열은 메모리 표현을 공유하기 때문에 이러한 전환은 일반적으로 간단(저렴)합니다. 그러나 텐서는 GPU 메모리에 저장될 수 있고, 넘파이 배열은 항상 호스트 메모리에 백업이 되므로, 이러한 전환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 포함됩니다." ] }, { @@ -231,7 +231,7 @@ "source": [ "## GPU 가속기\n", "\n", - "대부분의 텐서플로 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 CPU 와 GPU에 Tensor를 복사합니다.) 명령에 의해 생성된 Tensor는 전형적으로 명령이 실행된 장치의 메모리에 의해 실행됩니다. 예를들어:" + "대부분의 텐서플로 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 CPU 와 GPU에 텐서를 복사합니다.) 명령에 의해 생성된 텐서는 전형적으로 명령이 실행된 장치의 메모리에 의해 실행됩니다. 예를 들어:" ] }, { @@ -274,7 +274,7 @@ "source": [ "### 장치 이름\n", "\n", - "`Tensor.device`는 Tensor를 구성하고 있는 호스트 장치의 풀네임을 제공합니다. 이러한 이름은 프로그램이 실행중인 호스트의 네트워크 주소 및 해당 호스트 내의 장치와 같은 많은 세부 정보를 인코딩하며, 이것은 텐서플로 프로그램의 분산 실행에 필요합니다. Tensor가 호스트의 `N`번째 GPU에 놓여지면 문자열은 `GPU:`으로 끝납니다." + "`Tensor.device`는 텐서를 구성하고 있는 호스트 장치의 풀네임을 제공합니다. 이러한 이름은 프로그램이 실행중인 호스트의 네트워크 주소 및 해당 호스트 내의 장치와 같은 많은 세부 정보를 인코딩하며, 이것은 텐서플로 프로그램의 분산 실행에 필요합니다. 텐서가 호스트의 `N`번째 GPU에 놓여지면 문자열은 `GPU:`으로 끝납니다." ] }, { @@ -286,7 +286,7 @@ "source": [ "### 명시적 장치 배치\n", "\n", - "텐서플로에서 \"배치\"라는 용어는 개별 명령이 실행을 위해 장치를 할당(배치)하는 방법을 나타냅니다. 앞서 언급되었듯이, 명시적 지침이 없을경우 텐서플로는 명령을 실행하기위한 장치를 자동으로 결정하고, 필요시 Tensor를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. 예를 들어:" + "텐서플로에서 \"배치\"라는 용어는 개별 명령이 실행을 위해 장치를 할당(배치)하는 방법을 나타냅니다. 앞서 언급되었듯이, 명시적 지침이 없을경우 텐서플로는 명령을 실행하기위한 장치를 자동으로 결정하고, 필요시 텐서를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. 예를 들어:" ] }, { @@ -338,13 +338,13 @@ "이번 섹션에서는 모델에 데이터를 제공하기 위한 파이프라인을 구축하기 위해 [`tf.data.Dataset` API](https://www.tensorflow.org/guide/datasets)를 시연해볼 것입니다. 이는 다음을 포함합니다.\n", "\n", "* `Dataset` 생성.\n", - "* 즉시실행(eager execution) 활성화와 `Dataset`을 통한 반복\n", + "* 즉시 실행 활성화와 `Dataset`을 통한 반복\n", "\n", "모델을 학습시키고, 평가 루프를 제공할 간단하고 재사용 가능한 조각으로부터 복잡한 입력 파이프라인을 구축하기위해 `Dataset`s API를 사용하기를 권장합니다. \n", "\n", - "만약 텐서플로 그래프에 익숙하다면, `Dataset` 객체를 생성하기 위한 API는 즉시실행이 활성화 되어도 동일하게 유지됩니다. 하지만 그러나 데이터셋의 요소를 반복하는 프로세스는 약간 더 간단합니다.\n", + "만약 텐서플로 그래프에 익숙하다면, `Dataset` 객체를 생성하기 위한 API는 즉시 실행이 활성화 되어도 동일하게 유지됩니다. 하지만 그러나 데이터셋의 요소를 반복하는 프로세스는 약간 더 간단합니다.\n", "또한 `tf.data.Dataset` 객체를 통하여 파이썬 반복문을 사용할 수 있으며, 명시적으로 `tf.data.Iterator` 객체를 생성할 필요가 없습니다.\n", - "그 결과, [텐서플로 가이드](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시실행이 활성화될 때에는 관계없습니다. " + "그 결과, [텐서플로 가이드](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시 실행이 활성화될 때에는 관계없습니다. " ] }, { @@ -420,7 +420,7 @@ "source": [ "### 반복\n", "\n", - "즉시실행이 활성화되면 `Dataset` 객체는 반복을 지원합니다. 만약 텐서플로 그래프에서 `Dataset`을 사용하는게 익숙하다면, `Dataset.make_one_shot_iterator()` 또는 `get_next()`와 같은 객체를 호출할 필요가 없는다는 것에 주목하세요." + "즉시 실행이 활성화되면 `Dataset` 객체는 반복을 지원합니다. 만약 텐서플로 그래프에서 `Dataset`을 사용하는게 익숙하다면, `Dataset.make_one_shot_iterator()` 또는 `get_next()`와 같은 객체를 호출할 필요가 없는다는 것에 주목하세요." ] }, { From e3798d3453e7f3e0aaf0fef73aba9004a56b1ae2 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Wed, 3 Apr 2019 00:53:53 +0900 Subject: [PATCH 08/19] Update from db5446ea --- .../eager/automatic_differentiation.ipynb | 4 +- site/ko/tutorials/eager/custom_layers.ipynb | 14 ++--- site/ko/tutorials/eager/custom_training.ipynb | 22 +++---- .../eager/custom_training_walkthrough.ipynb | 60 +++++++++---------- site/ko/tutorials/eager/eager_basics.ipynb | 12 ++-- site/ko/tutorials/eager/index.md | 8 +-- 6 files changed, 60 insertions(+), 60 deletions(-) diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index 6d927d99ecc..611488b4a2d 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -71,7 +71,7 @@ "id": "vDJ4XzMqodTy" }, "source": [ - "이전 튜토리얼에서는 텐서(tensor)와 텐서의 연산들에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술 중 하나인 [자동 미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." + "이전 튜토리얼에서는 텐서(tensor)와 텐서의 연산에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술 중 하나인 [자동 미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." ] }, { @@ -315,7 +315,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index f85d0e46f34..7222bc1990f 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -157,8 +157,8 @@ }, "outputs": [], "source": [ - "# layer는 유용한 메서드들을 내재하고있습니다. 예를 들어, `layer.variables`를 사용하여 layer안에 있는 모든 변수들을 확인할 수 있으며, \n", - "# `layer.trainable_variables`를 사용하여 학습가능한 변수들을 확인할 수 있습니다. \n", + "# layer는 유용한 메서드를 내재하고있습니다. 예를 들어, `layer.variables`를 사용하여 layer안에 있는 모든 변수를 확인할 수 있으며, \n", + "# `layer.trainable_variables`를 사용하여 학습가능한 변수를 확인할 수 있습니다. \n", "# 이번 케이스에서 완전연결(fully-connected) 레이어는 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", "layer.variables" ] @@ -187,10 +187,10 @@ "## 사용자 정의 layer 구현\n", "사용자 정의 layer를 구현하는 가장 좋은 방법은 tf.keras.Layer 클래스를 상속하고 다음과 같이 구현하는 것입니다.\n", " * `__init__` , 모든 독립적인 입력값을 초기화를 할 수 있습니다.\n", - " * `build`, 입력 Tensor의 형태를 알고 나머지를 초기화 할 수 있습니다.\n", - " * `call`, 정방향 계산을 진행 할 수 있습니다.\n", + " * `build`, 입력 텐서의 크기를 알고 나머지를 초기화 할 수 있습니다.\n", + " * `call`, 정방향 연산(forward computation)을 진행 할 수 있습니다.\n", "\n", - "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 layer가 작동할 입력의 형태를 기준으로 나중에 변수를 만들 수 있습니다. 반면에, `__init__`에 변수를 생성하는것은 변수 생성에 필요한 형태가 명시적으로 지정되어야 함을 의미합니다." + "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 layer가 작동할 입력의 크기를 기준으로 나중에 변수를 만들 수 있습니다. 반면에, `__init__`에 변수를 생성하는것은 변수 생성에 필요한 크기가 명시적으로 지정되어야 함을 의미합니다." ] }, { @@ -242,7 +242,7 @@ "source": [ "## 모델: layer 구성\n", "\n", - "머신러닝 모델에서 대부분의 흥미로운 유사 layer(layer-likely)는 layer들의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 잔여 블록(residual block)은 합성곱(convolution), 배치 정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", + "머신러닝 모델에서 대부분의 흥미로운 유사 layer(layer-likely)는 layer의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 잔여 블록(residual block)은 합성곱(convolution), 배치 정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", "\n", "layer 집합을 포함한 유사 layer를 생성하기위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현합니다." ] @@ -349,7 +349,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/custom_training.ipynb b/site/ko/tutorials/eager/custom_training.ipynb index 1385cb3736a..5b1a8e93108 100644 --- a/site/ko/tutorials/eager/custom_training.ipynb +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -71,9 +71,9 @@ "id": "k2o3TTG4TFpt" }, "source": [ - "이전 튜토리얼에서는 머신러닝을 위한 기초 빌딩 블록인 자동 미분(automatic differentiation)을 위한 텐서플로 API들을 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 초기 타입의 텐서플로를 사용하여 간단한 머신러닝을 구축해보겠습니다. \n", + "이전 튜토리얼에서는 머신러닝을 위한 기초 빌딩 블록인 자동 미분(automatic differentiation)을 위한 텐서플로 API를 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 초기 타입의 텐서플로를 사용하여 간단한 머신러닝을 구축해보겠습니다. \n", "\n", - "텐서플로는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 `tf.keras`를 포함하고 있습니다. 신경망에 관련하여 일을 하고 있는 사람들에게는 이러한 고수준의 API들을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " + "텐서플로는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 `tf.keras`를 포함하고 있습니다. 신경망에 관련하여 일을 하고 있는 사람에게는 이러한 고수준의 API을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " ] }, { @@ -119,7 +119,7 @@ "source": [ "## 변수\n", "\n", - "텐서플로 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로, 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 계산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어에 의존한 선택이 가능합니다. " + "텐서플로 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로, 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 연산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어에 의존한 선택이 가능합니다. " ] }, { @@ -145,9 +145,9 @@ "id": "wfneTXy7JcUz" }, "source": [ - "그러나 텐서플로는 상태가 변경 가능한 연산자들이 내장되어 있으며, 이 연산자들은 상태를 표현하기 위한 저수준 파이썬 표현보다 사용하기가 더 좋습니다. 예를 들어, 모델에서 가중치를 나타내기 위해서 텐서플로 변수를 사용하는것이 편하고 효율적입니다. \n", + "그러나 텐서플로는 상태가 변경 가능한 연산자가 내장되어 있으며, 이러한 연산자는 상태를 표현하기 위한 저수준 파이썬 표현보다 사용하기가 더 좋습니다. 예를 들어, 모델에서 가중치를 나타내기 위해서 텐서플로 변수를 사용하는것이 편하고 효율적입니다. \n", "\n", - "텐서플로 변수는 값을 저장하고 텐서플로 계산에 사용될 때 묵시적으로 저장된 값을 읽어오는 객체입니다. `tf.assign_sub`, `tf.scatter_update` 등은 텐서플로 변수에 저장되있는 값을 조작하는 연산자들입니다." + "텐서플로 변수는 값을 저장하고 텐서플로 연산에 사용될 때 묵시적으로 저장된 값을 읽어오는 객체입니다. `tf.assign_sub`, `tf.scatter_update` 등은 텐서플로 변수에 저장되있는 값을 조작하는 연산자입니다." ] }, { @@ -179,7 +179,7 @@ "id": "-paSaeq1JzwC" }, "source": [ - "변수들을 사용한 계산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 초기값으로부터 드물게 업데이트됩니다. 이는 계산과 메모리에 있어 더욱 효율적입니다. \n", + "변수를 사용한 연산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 초기로부터 드물게 업데이트됩니다. 이는 연산과 메모리에 있어 더욱 효율적입니다. \n", "\n", "또한 변수를 사용하는 것은 코드를 읽는 과정에서 상태가 변경 가능한 상태(state mutable)의 조각을 빠르게 인식하는 방법입니다." ] @@ -193,7 +193,7 @@ "source": [ "## 예: 선형모델 피팅\n", "\n", - "몇가지 개념들을 설명해보겠습니다. 우리는 지금까지 간단한 모델을 구축하고 학습시키기 위해 ---`Tensor`, `GradientTape`, `Variable` --- 등을 사용하였습니다. 이것은 전형적으로 다음의 과정을 포함합니다.\n", + "몇가지 개념을 설명해보겠습니다. 우리는 지금까지 간단한 모델을 구축하고 학습시키기 위해 ---`Tensor`, `GradientTape`, `Variable` --- 등을 사용하였습니다. 이것은 전형적으로 다음의 과정을 포함합니다.\n", "\n", "1. 모델 정의\n", "2. 손실함수 정의\n", @@ -212,7 +212,7 @@ "source": [ "### 모델 정의\n", "\n", - "변수들과 계산을 요약하기 위한 간단한 클래스를 정의해봅시다." + "변수와 연산을 요약하기 위한 간단한 클래스를 정의해봅시다." ] }, { @@ -397,7 +397,7 @@ "source": [ "model = Model()\n", "\n", - "# 도식화를 위해 W값과 b값들의 변화를 저장합니다.\n", + "# 도식화를 위해 W값과 b값의 변화를 저장합니다.\n", "Ws, bs = [], []\n", "epochs = range(10)\n", "for epoch in epochs:\n", @@ -430,7 +430,7 @@ "\n", "이번 튜토리얼에서는 `Variable`를 다루었으며, 지금까지 논의된 초기 타입의 텐서플로를 사용하여 간단한 선형모델을 구축하고 훈련시켰습니다.\n", "\n", - "이론적으로, 이것은 머신러닝 연구에 텐서플로를 사용하는데 필요한 대부분입니다. 실제로, 신경망에 있어 `tf.keras`와 고수준 API들은 고수준 빌딩 블록(\"layer\"로 불리는)을 제공하고, 저장 및 복원을 위한 유틸리티, 손실함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " + "이론적으로, 이것은 머신러닝 연구에 텐서플로를 사용하는데 필요한 대부분입니다. 실제로, 신경망에 있어 `tf.keras`와 같은 고수준 API는 고수준 빌딩 블록(\"layer\"로 불리는)을 제공하고, 저장 및 복원을 위한 유틸리티, 손실함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " ] } ], @@ -458,7 +458,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index 99b8486f785..4f99b339195 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -41,7 +41,7 @@ "id": "JtEZ1pCPn--z" }, "source": [ - "# 사용자 정의 학습: walkthrough" + "# 사용자 정의 학습: 둘러보기" ] }, { @@ -78,7 +78,7 @@ "\n", "## 텐서플로 프로그래밍\n", "\n", - "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로의 개념들을 사용합니다.\n", + "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로의 개념을 사용합니다.\n", "\n", "* [즉시 실행(eager execution)](https://www.tensorflow.org/guide/eager) 개발환경,\n", "* [데이터셋 API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 불러오기,\n", @@ -112,7 +112,7 @@ "source": [ "### 임포트 및 즉시 실행 구성\n", "\n", - "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화할 것입니다. 즉시 실행은 텐서플로가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 여러분들이 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", + "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화할 것입니다. 즉시 실행은 텐서플로가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", "\n", "즉시 실행이 활성화 될때, 동일한 프로그램내에서는 비활성화를 할 수 없습니다. 더 많은 세부사항은 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)을 참조하세요." ] @@ -176,7 +176,7 @@ "
\n", "\n", - "다행히도 다른사람들이 먼저 꽃받침과 꽃잎의 길이와 폭이 측정된 [120개의 붓꽃 데이터](https://en.wikipedia.org/wiki/Iris_flower_data_set)를 만들어 놓았습니다. 이것은 머신러닝 분류문제에 있어 초보자들에게 유명한 고전 데이터셋입니다. " + "다행히도 다른사람들이 먼저 꽃받침과 꽃잎의 길이와 폭이 측정된 [120개의 붓꽃 데이터](https://en.wikipedia.org/wiki/Iris_flower_data_set)를 만들어 놓았습니다. 이것은 머신러닝 분류문제에 있어 초보자에게 유명한 고전 데이터셋입니다. " ] }, { @@ -333,7 +333,7 @@ "source": [ "### `tf.data.Dataset` 생성\n", "\n", - "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위한 많은 케이스를 다룹니다. 이는 훈련을 위한 형태로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 다음을 참조하세요. [Datasets Quick Start guide](https://www.tensorflow.org/get_started/datasets_quickstart) \n", + "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위한 많은 케이스를 다룹니다. 이는 훈련을 위한 형식으로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 다음을 참조하세요. [Datasets Quick Start guide](https://www.tensorflow.org/get_started/datasets_quickstart) \n", "\n", "\n", "데이터셋이 CSV 형태의 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 [배치 사이즈(batch_size)](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." @@ -367,7 +367,7 @@ }, "source": [ "`make_csv_dataset` 함수는 `tf.data.Dataset` 의 `(features, label)` 쌍을 반환합니다. `features`는 사전형 객체인: `{'feature_name': value}`로 주어집니다.\n", - "또한 즉시 실행 활성화로 이 `Dataset`은 반복가능합니다. 다음은 특성(feature)들을 살펴봅시다." + "또한 즉시 실행 활성화로 이 `Dataset`은 반복가능합니다. 다음은 특성(feature)을 살펴봅시다." ] }, { @@ -422,9 +422,9 @@ "id": "E63mArnQaAGz" }, "source": [ - "유사한 특성의 값들은 같이 그룹되어있거나, *배치* 되있다는 사실에 주목하세요. 각 예제행의 필드는 해당 특성 배열에 추가됩니다. `batch_size` 조절하여 이 특성 배열에 저장된 예제의 수를 설정하세요.\n", + "유사한 특성의 값은 같이 그룹되어있거나, *배치* 되있다는 사실에 주목하세요. 각 예제행의 필드는 해당 특성 배열에 추가됩니다. `batch_size` 조절하여 이 특성 배열에 저장된 예제의 수를 설정하세요.\n", "\n", - "또한 여러분들은 배치(batch)로부터 약간의 특성을 도식화하여 군집되있는 데이터를 확인할 수 있습니다. " + "또한 배치(batch)로부터 약간의 특성을 도식화하여 군집되있는 데이터를 확인할 수 있습니다. " ] }, { @@ -468,7 +468,7 @@ "source": [ "모델 구축단계를 단순화하기 위해서, 특성(사전형 객체)을 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", "\n", - "이 함수는 `Tensor`의 list로부터 값을 취하고 특정한 차원으로 결합된 `Tensor`를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메서드(method)를 사용합니다." + "이 함수는 `텐서`의 list로부터 값을 취하고 특정한 차원으로 결합된 `텐서`를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메서드(method)를 사용합니다." ] }, { @@ -517,7 +517,7 @@ "id": "NLy0Q1xCldVO" }, "source": [ - "데이터셋의 특성 요소들은 이제 형태가 `(batch_size, num_features)`인 배열입니다. 첫 5행의 예제를 살펴봅시다." + "데이터셋의 특성 요소는 이제 형태가 `(batch_size, num_features)`인 배열입니다. 첫 5행의 예제를 살펴봅시다." ] }, { @@ -559,13 +559,13 @@ "\n", "### 왜 모델을 사용해야하는가?\n", "\n", - " *[모델](https://developers.google.com/machine-learning/crash-course/glossary#model)*은 특성(feature)들과 레이블(label)과의 관계입니다. 붓꽃 분류 문제에서 모델은 측정된 꽃받침과 꽃잎 사이의 관계를 정의하고 붓꽃의 품종을 예측합니다. 몇가지 간단한 모델은 몇 줄의 대수학으로 표현할 수 있으나, 복잡한 머신러닝 모델은 요약하기 힘든 굉장히 많은 수의 매개변수를 가지고 있습니다.\n", + " *[모델](https://developers.google.com/machine-learning/crash-course/glossary#model)*은 특성(feature)과 레이블(label)과의 관계입니다. 붓꽃 분류 문제에서 모델은 측정된 꽃받침과 꽃잎 사이의 관계를 정의하고 붓꽃의 품종을 예측합니다. 몇가지 간단한 모델은 몇 줄의 대수학으로 표현할 수 있으나, 복잡한 머신러닝 모델은 요약하기 힘든 굉장히 많은 수의 매개변수를 가지고 있습니다.\n", "\n", - "머신러닝을 사용하지 않고 4가지의 특성 사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 여러분들이 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문들)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 여러분들을 위한 모델을 결정합니다. 만약 여러분들이 충분한 예제를 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 여러분들을 위한 특성들 사이의 관계를 이해하고 제공합니다. \n", + "머신러닝을 사용하지 않고 4가지의 특성 사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 사용자를 위한 모델을 결정합니다. 만약 충분한 예제를 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 사용자를 위한 특성간의 관계를 이해하고 제공합니다. \n", "\n", "### 모델 선정\n", "\n", - "이제 학습을 위한 모델의 종류를 선정해야합니다. 여러 종류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*들로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[dense(또는 fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전연결 신경망입니다. \n", + "이제 학습을 위한 모델의 종류를 선정해야합니다. 여러 종류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*으로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[dense(또는 fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전 연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전 연결 신경망입니다. \n", "\n", "\n", " \n", "
\n", @@ -589,7 +589,7 @@ "source": [ "### Keras를 사용한 모델 생성\n", "\n", - "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 layer를 생성하기위한 풍부한 라이브러리를 제공합니다. 이는 연결되있는 모든것들을 케라스가 처리하여 모델을 구축하기 쉽게 만듭니다.\n", + "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 layer를 생성하기위한 풍부한 라이브러리를 제공합니다. 이는 연결되있는 모든것을 케라스가 처리하여 모델을 구축하기 쉽게 만듭니다.\n", "\n", "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 layer의 선형 적층 모델입니다. 이 구조는 layer의 인스턴스를 취하며, 아래의 케이스의 경우 각 layer당 10개의 노드(node)를 가지는 2개의 [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)층과 3개의 예측(레이블의 개수)노드를 가지는 출력 층으로 구성되어있습니다. 첫번째 layer의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." ] @@ -618,9 +618,9 @@ "id": "FHcbEzMpxbHL" }, "source": [ - "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 층들의 출력의 형태를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 단일층과 동일하다고 생각할 수 있습니다. 사용가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", + "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 층의 출력의 크기를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 단일층과 동일하다고 생각할 수 있습니다. 사용가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", "\n", - "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 좌우됩니다. 머신러닝의 여러측면과 마찬가지로, 신경망의 최적의 형태를 결정하는것은 많은 경험과 지식이 필요합니다. 경험을 토대로, 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." + "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 좌우됩니다. 머신러닝의 여러측면과 마찬가지로, 최적의 신경망 타입을 결정하는것은 많은 경험과 지식이 필요합니다. 경험을 토대로, 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." ] }, { @@ -713,7 +713,7 @@ "id": "uRZmchElo481" }, "source": [ - "`tf.argmax`는 예측된 값들 중 가장 큰 확률(원하는 클래스)을 반환합니다. 하지만 모델이 아직 훈련되지 않았으므로 이는 좋은 예측이 아닙니다." + "`tf.argmax`는 예측된 값 중 가장 큰 확률(원하는 클래스)을 반환합니다. 하지만 모델이 아직 훈련되지 않았으므로 이는 좋은 예측이 아닙니다." ] }, { @@ -750,7 +750,7 @@ "\n", "*[훈련 단계](https://developers.google.com/machine-learning/crash-course/glossary#training)*는 모델이 점진적으로 최적화되거나 데이터셋을 학습하는 머신러닝의 과정입니다. 훈련의 목적은 미지의 데이터를 예측하기 위해, 훈련 데이터셋의 구조에 대해서 충분히 학습하는 것입니다. 만약 모델이 훈련 데이터셋에 대해서 과하게 학습된다면 오직 훈련 데이터셋에 대해서 작동할 것이며, 일반화되기 힘들 것입니다. 이러한 문제를 *[과대적합(overfitting)](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)* 이라고 합니다. 이는 마치 문제를 이해하고 해결한다기보다는 답을 기억하는 것이라고 생각할 수 있습니다. \n", "\n", - "붓꽃 분류 문제는 지도학습 *[지도학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시 중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고 있지않습니다. 대신에 모델은 특성들의 패턴을 찾습니다. " + "붓꽃 분류 문제는 지도학습 *[지도 학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시 중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도 학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고 있지않습니다. 대신에 모델은 특성간의 패턴을 찾습니다. " ] }, { @@ -921,13 +921,13 @@ "모든 조각을 가지고, 모델은 학습할 준비가 되었습니다! 훈련 루프는 더 나은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 아래의 훈련 단계를 작성한 것입니다. \n", "\n", "1. 각 *에포크(epoch)* 반복. 에포크는 데이터셋을 통과시키는 횟수입니다. \n", - "2. 에포크내에서, `Dataset`의 *features* (`x`)와 *label* (`y`)를 가져오는 예제를 반복합니다.\n", + "2. 에포크내에서, `데이터셋`의 *특성* (`x`)와 *레이블* (`y`)를 가져오는 예제를 반복합니다.\n", "3. 예제의 특성을 사용하여 결과를 예측을 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기위해 사용합니다. \n", - "4. 모델의 변수를 업데이트하기위해 `옵티마이저(optimizer)`를 사용합니다. \n", + "4. 모델의 변수를 업데이트하기위해 `옵티마이저`를 사용합니다. \n", "5. 시각화를 위해 몇가지 값을 추적합니다.\n", "6. 각 에포크를 반복합니다.\n", "\n", - "`num_epochs` 변수는 데이터셋 반복 횟수입니다. 반직관적으로, 모델을 길게 학습하는것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 여러분들이 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는것은 경험과 직관을 필요로 합니다. " + "`num_epochs` 변수는 데이터셋 반복 횟수입니다. 반직관적으로, 모델을 길게 학습하는것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는것은 경험과 직관을 필요로 합니다. " ] }, { @@ -957,7 +957,7 @@ "from tensorflow import contrib\n", "tfe = contrib.eager\n", "\n", - "# 도식화를 위해 결과 저장\n", + "# 도식화를 위해 결과를 저장합니다.\n", "train_loss_results = []\n", "train_accuracy_results = []\n", "\n", @@ -967,16 +967,16 @@ " epoch_loss_avg = tfe.metrics.Mean()\n", " epoch_accuracy = tfe.metrics.Accuracy()\n", "\n", - " # 훈련 루프 - 32번의 배치 실행\n", + " # 훈련 루프 - 32개의 배치를 사용합니다.\n", " for x, y in train_dataset:\n", - " # Optimize the model\n", + " # 모델을 최적화합니다.\n", " loss_value, grads = grad(model, x, y)\n", " optimizer.apply_gradients(zip(grads, model.trainable_variables),\n", " global_step)\n", "\n", - " # 진행 상황 추적\n", - " epoch_loss_avg(loss_value) # 현재 배치의 손실 추가\n", - " # 예측된 레이블과 실제 레이블 비교\n", + " # 진행 상황을 추적합니다.\n", + " epoch_loss_avg(loss_value) # 현재 배치 손실을 추가합니다.\n", + " # 예측된 레이블과 실제 레이블 비교합니다.\n", " epoch_accuracy(tf.argmax(model(x), axis=1, output_type=tf.int32), y)\n", "\n", " # epoch 종료\n", @@ -1180,7 +1180,7 @@ "id": "HcKEZMtCOeK-" }, "source": [ - "예를들어, 마지막 배치에서 모델이 일반적으로 정확하다는 것을 확인할 수 있습니다. " + "예를 들어, 마지막 배치에서 모델이 일반적으로 정확하다는 것을 확인할 수 있습니다. " ] }, { @@ -1205,7 +1205,7 @@ "source": [ "## 예측을 위해 훈련된 모델 사용하기\n", "\n", - "이제 붓꽃을 분류하기위해 완벽하지는 않지만 어느정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)들을 예측해봅시다.\n", + "이제 붓꽃을 분류하기위해 완벽하지는 않지만 어느정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)를 예측해봅시다.\n", "\n", "실제로는 레이블되지 않은 예제들은 여러 소스(앱, CSV 파일, 직접제공 등)로 부터 제공될 수 있습니다. 지금은 레이블을 예측하기위해 수동으로 3개의 레이블되지 않은 예제를 제공하겠습니다. 레이블은 다음과 붓꽃이름으로 맵핑되어있습니다.\n", "* `0`: Iris setosa\n", @@ -1263,7 +1263,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 1d8a1522cd1..9f43f37cb82 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -116,7 +116,7 @@ "source": [ "## 텐서\n", "\n", - "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 형태를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 계산하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자들은 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" + "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 크기를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 소비하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자는 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" ] }, { @@ -136,7 +136,7 @@ "print(tf.reduce_sum([1, 2, 3]))\n", "print(tf.encode_base64(\"hello world\"))\n", "\n", - "# 연산자의 오버로딩 또한 지원합니다.\n", + "# 연산자의 오버로딩(overloding) 또한 지원합니다.\n", "print(tf.square(2) + tf.square(3))" ] }, @@ -147,7 +147,7 @@ "id": "IDY4WsYRhP81" }, "source": [ - "각각의 텐서는 형태와 데이터 타입을 가지고 있습니다." + "각각의 텐서는 데이터 타입과 크기를 가지고 있습니다." ] }, { @@ -174,8 +174,8 @@ "source": [ "넘파이 `ndarray`와 텐서플로 `Tensor`의 가장 확연한 차이는 다음과 같습니다:\n", "\n", - "1. `Tensor`는 가속기 메모리(GPU, TPU와 같은)의 사용이 가능합니다.\n", - "2. `Tensor`는 불변성(immutable)을 가집니다." + "1. `텐서`는 가속기 메모리(GPU, TPU와 같은)의 사용이 가능합니다.\n", + "2. `텐서`는 불변성(immutable)을 가집니다." ] }, { @@ -467,7 +467,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md index e75df364cb0..65c9547aced 100644 --- a/site/ko/tutorials/eager/index.md +++ b/site/ko/tutorials/eager/index.md @@ -11,11 +11,11 @@ 즉시실행(Eager execution)은 더 나은 연산을 위한 실행에 의해 정의되는 명령형 인터페이스를 제공합니다. 사용자 정의 layer, 정방향 전파, 자동미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 시작한 다음 순서대로 진행하세요. -[eager execution guide](../../guide/eager). +[즉시 실행 가이드](../../guide/eager). -1. [즉시실행(Eager execution)](eager_basics.ipynb) -2. [자동미분과 그래디언트 테이프(Automatic differentiation and gradient tape)](automatic_differentiation.ipynb) +1. [즉시 실행(Eager execution)](eager_basics.ipynb) +2. [자동 미분과 그래디언트 테이프(Automatic differentiation and gradient tape)](automatic_differentiation.ipynb) 3. [사용자 정의 학습 : 기초(Custom training: basics)](custom_training.ipynb) 4. [사용자 정의 layer(Custom layers)](custom_layers.ipynb) -5. [사용자 정의 학습 : walkthrough(Custom training: walkthrough)](custom_training_walkthrough.ipynb) +5. [사용자 정의 학습 : 둘러보기(Custom training: walkthrough)](custom_training_walkthrough.ipynb) From c6658190b8a05386ab728cdbcae5fd4d57eb04ab Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Wed, 3 Apr 2019 23:35:32 +0900 Subject: [PATCH 09/19] Update from b5b0882a --- .../eager/automatic_differentiation.ipynb | 2 +- site/ko/tutorials/eager/custom_layers.ipynb | 6 ++-- site/ko/tutorials/eager/custom_training.ipynb | 33 +++++++++++-------- .../eager/custom_training_walkthrough.ipynb | 22 ++++++------- site/ko/tutorials/eager/eager_basics.ipynb | 30 ++++++++--------- site/ko/tutorials/eager/index.md | 6 ++-- 6 files changed, 53 insertions(+), 46 deletions(-) diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index 611488b4a2d..27866a090d4 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -176,7 +176,7 @@ "id": "ISkXuY7YzIcS" }, "source": [ - "기본적으로 GradientTape.gradient() 메서드가 호출되면 GradientTape에 포함된 리소스가 해제됩니다. 동일한 연산을 대해 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. 이 그래디언트 테이프는 `gradient()` 메서드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다.\n", + "기본적으로 GradientTape.gradient() 메서드가 호출되면 GradientTape에 포함된 리소스가 해제됩니다. 동일한 연산 대해 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. 이 그래디언트 테이프는 `gradient()` 메서드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다.\n", "예를 들면 다음과 같습니다:" ] }, diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index 7222bc1990f..e87e0d1fa0b 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -102,7 +102,7 @@ "\n", "많은 머신러닝 모델은 비교적 단순한 layer의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로는 여러 표준 layer 세트를 제공하므로 사용자 고유의 응용 프로그램에 관련된 layer를 처음부터 작성하거나, 기존 layer의 구성으로 쉽게 작성할 수 있습니다.\n", "\n", - "텐서플로는 [Keras](https://keras.io) API 의 풀패키지를 tf.keras package에 포함하고 있습니다. Keras layer는 모델을 구축하는데 매우 유용합니다." + "텐서플로는 [케라스](https://keras.io) API 의 풀패키지를 tf.keras package에 포함하고 있습니다. 케라스 layer는 모델을 구축하는데 매우 유용합니다." ] }, { @@ -159,7 +159,7 @@ "source": [ "# layer는 유용한 메서드를 내재하고있습니다. 예를 들어, `layer.variables`를 사용하여 layer안에 있는 모든 변수를 확인할 수 있으며, \n", "# `layer.trainable_variables`를 사용하여 학습가능한 변수를 확인할 수 있습니다. \n", - "# 이번 케이스에서 완전연결(fully-connected) 레이어는 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", + "# 이번 케이스에서 완전 연결(fully-connected) 레이어는 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", "layer.variables" ] }, @@ -173,7 +173,7 @@ }, "outputs": [], "source": [ - "# 또한 변수는 여러 accessors를 통해 접근가능합니다. \n", + "# 또한 변수는 여러 접근자(accessors)를 통해 접근가능합니다. \n", "layer.kernel, layer.bias" ] }, diff --git a/site/ko/tutorials/eager/custom_training.ipynb b/site/ko/tutorials/eager/custom_training.ipynb index 5b1a8e93108..f83e416b129 100644 --- a/site/ko/tutorials/eager/custom_training.ipynb +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -73,7 +73,7 @@ "source": [ "이전 튜토리얼에서는 머신러닝을 위한 기초 빌딩 블록인 자동 미분(automatic differentiation)을 위한 텐서플로 API를 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 초기 타입의 텐서플로를 사용하여 간단한 머신러닝을 구축해보겠습니다. \n", "\n", - "텐서플로는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 `tf.keras`를 포함하고 있습니다. 신경망에 관련하여 일을 하고 있는 사람에게는 이러한 고수준의 API을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " + "텐서플로는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 `tf.keras`를 포함하고 있습니다. 신경망에 관련된 일을 하고 있는 사람에게는 이러한 고수준의 API을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " ] }, { @@ -119,7 +119,7 @@ "source": [ "## 변수\n", "\n", - "텐서플로 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로, 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 연산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어에 의존한 선택이 가능합니다. " + "텐서플로 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝 모델은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 연산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어에 의존한 선택이 가능합니다. " ] }, { @@ -163,11 +163,11 @@ "v = tf.Variable(1.0)\n", "assert v.numpy() == 1.0\n", "\n", - "# 값 재배열\n", + "# 값을 재배열합니다.\n", "v.assign(3.0)\n", "assert v.numpy() == 3.0\n", "\n", - "# 텐서플로 연산내에서 `v` 사용 \n", + "# 텐서플로 연산내에서 `v` 사용합니다. \n", "v.assign(tf.square(v))\n", "assert v.numpy() == 9.0" ] @@ -179,9 +179,9 @@ "id": "-paSaeq1JzwC" }, "source": [ - "변수를 사용한 연산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 초기로부터 드물게 업데이트됩니다. 이는 연산과 메모리에 있어 더욱 효율적입니다. \n", + "변수를 사용한 연산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 초기로부터 드물게 업데이트됩니다. 이는 연산과 메모리에 더욱 효율적입니다. \n", "\n", - "또한 변수를 사용하는 것은 코드를 읽는 과정에서 상태가 변경 가능한 상태(state mutable)의 조각을 빠르게 인식하는 방법입니다." + "또한 변수를 사용하는 것은 코드를 읽는 독자가 이 상태가 변경 가능하다는 것을 빠르게 인식하는 방법입니다." ] }, { @@ -193,7 +193,7 @@ "source": [ "## 예: 선형모델 피팅\n", "\n", - "몇가지 개념을 설명해보겠습니다. 우리는 지금까지 간단한 모델을 구축하고 학습시키기 위해 ---`Tensor`, `GradientTape`, `Variable` --- 등을 사용하였습니다. 이것은 전형적으로 다음의 과정을 포함합니다.\n", + "몇가지 개념을 설명해보겠습니다. 우리는 지금까지 간단한 모델을 구축하고 학습시키기 위해 ---`Tensor`, `GradientTape`, `Variable` --- 등을 사용하였습니다. 이것은 일반적으로 다음의 과정을 포함합니다.\n", "\n", "1. 모델 정의\n", "2. 손실함수 정의\n", @@ -227,7 +227,7 @@ "source": [ "class Model(object):\n", " def __init__(self):\n", - " # 변수 초기화 (5.0, 0.0)\n", + " # 변수를 (5.0, 0.0)으로 초기화 합니다.\n", " # 실제로는 임의의 값으로 초기화 되어야합니다.\n", " self.W = tf.Variable(5.0)\n", " self.b = tf.Variable(0.0)\n", @@ -304,7 +304,7 @@ "id": "-50nq-wPBsAW" }, "source": [ - "모델을 훈련시키기 전에, 모델의 현재 상태를 시각화합시다. 모델의 예측을 빨간색으로, 훈련데이터를 파란색으로 구성합니다." + "모델을 훈련시키기 전에, 모델의 현재 상태를 시각화합시다. 모델의 예측을 빨간색으로, 훈련 데이터를 파란색으로 구성합니다." ] }, { @@ -354,7 +354,7 @@ "source": [ "### 훈련 루프 정의\n", "\n", - "현재 우리는 네트워크와 훈련 데이터를 가지고 있습니다. 모델의 변수(`W` 와 `b`)를 업데이트하기 위해 훈련 데이터를 사용하여 훈련시킵니다. 그리고 [경사하강(gradient descent)](https://en.wikipedia.org/wiki/Gradient_descent)를 사용하여 손실을 감소시킵니다. 경사하강에는 여러가지 방법이 있으며, `tf.train.Optimizer` 에 구현되어있습니다. 이러한 구현을 사용하는것을 강력히 추천드립니다. 그러나 이번 튜토리얼에서는 기본적인 방법을 사용하겠습니다." + "현재 우리는 네트워크와 훈련 데이터를 가지고 있습니다. 모델의 변수(`W` 와 `b`)를 업데이트하기 위해 훈련 데이터를 사용하여 훈련시킵니다. 그리고 [경사 하강(gradient descent)](https://en.wikipedia.org/wiki/Gradient_descent)을 사용하여 손실을 감소시킵니다. 경사 하강에는 여러가지 방법이 있으며, `tf.train.Optimizer` 에 구현되어있습니다. 이러한 구현을 사용하는것을 강력히 추천드립니다. 그러나 이번 튜토리얼에서는 기본적인 방법을 사용하겠습니다." ] }, { @@ -409,7 +409,7 @@ " print('에포크 %2d: W=%1.2f b=%1.2f, 손실=%2.5f' %\n", " (epoch, Ws[-1], bs[-1], current_loss))\n", "\n", - "# Let's plot it all\n", + "# 저장된 값들을 도식화합니다.\n", "plt.plot(epochs, Ws, 'r',\n", " epochs, bs, 'b')\n", "plt.plot([TRUE_W] * len(epochs), 'r--',\n", @@ -428,10 +428,17 @@ "source": [ "## 다음 단계\n", "\n", - "이번 튜토리얼에서는 `Variable`를 다루었으며, 지금까지 논의된 초기 타입의 텐서플로를 사용하여 간단한 선형모델을 구축하고 훈련시켰습니다.\n", + "이번 튜토리얼에서는 변수를 다루었으며, 지금까지 논의된 초기 타입의 텐서플로를 사용하여 간단한 선형모델을 구축하고 훈련시켰습니다.\n", "\n", - "이론적으로, 이것은 머신러닝 연구에 텐서플로를 사용하는데 필요한 대부분입니다. 실제로, 신경망에 있어 `tf.keras`와 같은 고수준 API는 고수준 빌딩 블록(\"layer\"로 불리는)을 제공하고, 저장 및 복원을 위한 유틸리티, 손실함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " + "이론적으로, 이것은 텐서플로를 머신러닝 연구에 사용하는데 필요한 대부분입니다. 실제로 신경망에 있어 `tf.keras`와 같은 고수준 API는 고수준 빌딩 블록(\"layer\"로 불리는)을 제공하고, 저장 및 복원을 위한 유틸리티, 손실 함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index 4f99b339195..ccd4cf0586c 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -220,7 +220,7 @@ "train_dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(train_dataset_url),\n", " origin=train_dataset_url)\n", "\n", - "print(\"Local copy of the dataset file: {}\".format(train_dataset_fp))" + "print(\"데이터셋이 복사된 위치: {}\".format(train_dataset_fp))" ] }, { @@ -232,7 +232,7 @@ "source": [ "### 데이터 탐색\n", "\n", - "이 데이터셋(`iris_training.csv`)은 ','로 구분된 CSV 파일입니다. `head -n5` 명령을 사용하여 처음 5개 항목을 확인합니다. " + "이 데이터셋(`iris_training.csv`)은 콤마 ','로 구분된 CSV 파일입니다. `head -n5` 명령을 사용하여 처음 5개 항목을 확인합니다. " ] }, { @@ -565,7 +565,7 @@ "\n", "### 모델 선정\n", "\n", - "이제 학습을 위한 모델의 종류를 선정해야합니다. 여러 종류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*으로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[dense(또는 fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전 연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전 연결 신경망입니다. \n", + "이제 학습을 위한 모델의 종류를 선정해야합니다. 여러 종류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*으로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[dense(또는 완전 연결 신경망(fully-connected neural network))](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전 연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전 연결 신경망입니다. \n", "\n", "\n", " \n", "
\n", @@ -587,11 +587,11 @@ "id": "W23DIMVPQEBt" }, "source": [ - "### Keras를 사용한 모델 생성\n", + "### 케라스를 사용한 모델 생성\n", "\n", "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 layer를 생성하기위한 풍부한 라이브러리를 제공합니다. 이는 연결되있는 모든것을 케라스가 처리하여 모델을 구축하기 쉽게 만듭니다.\n", "\n", - "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 layer의 선형 적층 모델입니다. 이 구조는 layer의 인스턴스를 취하며, 아래의 케이스의 경우 각 layer당 10개의 노드(node)를 가지는 2개의 [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)층과 3개의 예측(레이블의 개수)노드를 가지는 출력 층으로 구성되어있습니다. 첫번째 layer의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." + "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 layer의 선형 적층 모델입니다. 이 구조는 layer의 인스턴스를 취하며, 아래의 케이스의 경우 각 layer당 10개의 노드(node)를 가지는 2개의 [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)층과 3개의 예측(레이블의 수)노드를 가지는 출력 층으로 구성되어있습니다. 첫번째 layer의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." ] }, { @@ -1097,11 +1097,11 @@ "id": "z-EvK7hGL0d8" }, "source": [ - "### 테스트 데이터셋 설정\n", + "### 테스트 데이터 세트 설정\n", "\n", - "모델을 평가하는것은 모델을 학습하는것과 유사합니다. 가장 큰 차이는 훈련 데이터가 아닌 *[테스트 데이터셋](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* 을 사용했다는 것입니다. 공정하게 모델의 유효성을 평가하기위해, 모델을 평가하기위한 예제는 반드시 훈련 데이터와 달라야합니다. \n", + "모델을 평가하는것은 모델을 학습하는것과 유사합니다. 가장 큰 차이는 훈련 데이터가 아닌 *[테스트 데이터 세트](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* 를 사용했다는 것입니다. 공정하게 모델의 유효성을 평가하기위해, 모델을 평가하기위한 예제는 반드시 훈련 데이터와 달라야합니다. \n", "\n", - "테스트 데이터셋을 설정하는것은 훈련 데이터셋을 설정하는 것과 유사합니다. CSV 파일을 다운로드하고 값을 구분합니다. 그 후 약간의 셔플을 적용합니다." + "테스트 데이터 세트를 설정하는것은 훈련 데이터 세트를 설정하는 것과 유사합니다. CSV 파일을 다운로드하고 값을 구분합니다. 그 후 약간의 셔플을 적용합니다." ] }, { @@ -1148,9 +1148,9 @@ "id": "HFuOKXJdMAdm" }, "source": [ - "### 테스트 데이터셋을 사용한 모델 평가\n", + "### 테스트 데이터 세트를 사용한 모델 평가\n", "\n", - "훈련 단계와는 다르게 모델은 테스트 데이터에 대해서 오직 한번의 [epoch](https://developers.google.com/machine-learning/glossary/#epoch)을 진행합니다. 다음의 코드셀은 테스트 셋을 반복하여 실행하고 실제 레이블과 비교합니다. 이는 전체 테스트 데이터셋에 대한 정확도를 측정하는데 사용됩니다." + "훈련 단계와는 다르게 모델은 테스트 데이터에 대해서 오직 한번의 [에포크](https://developers.google.com/machine-learning/glossary/#epoch)을 진행합니다. 다음의 코드셀은 테스트 셋을 반복하여 실행하고 실제 레이블과 비교합니다. 이는 전체 테스트 데이터 세트에 대한 정확도를 측정하는데 사용됩니다." ] }, { @@ -1170,7 +1170,7 @@ " prediction = tf.argmax(logits, axis=1, output_type=tf.int32)\n", " test_accuracy(prediction, y)\n", "\n", - "print(\"테스트셋 정확도: {:.3%}\".format(test_accuracy.result()))" + "print(\"테스트 세트 정확도: {:.3%}\".format(test_accuracy.result()))" ] }, { diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 9f43f37cb82..afafd614e23 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -116,7 +116,7 @@ "source": [ "## 텐서\n", "\n", - "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 크기를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 소비하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자는 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" + "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 크기를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 이용하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자는 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" ] }, { @@ -147,7 +147,7 @@ "id": "IDY4WsYRhP81" }, "source": [ - "각각의 텐서는 데이터 타입과 크기를 가지고 있습니다." + "각각의 텐서는 크기와 데이터 타입을 가지고 있습니다." ] }, { @@ -218,7 +218,7 @@ "print(\"그리고 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 전환합니다.\")\n", "print(np.add(tensor, 1))\n", "\n", - "print(\".numpy() 메서드는 텐서를 넘파이 배열로 전환시킵니다.\")\n", + "print(\".numpy() 메서드는 텐서를 넘파이 배열로 전환합니다.\")\n", "print(tensor.numpy())" ] }, @@ -231,7 +231,7 @@ "source": [ "## GPU 가속기\n", "\n", - "대부분의 텐서플로 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 CPU 와 GPU에 텐서를 복사합니다.) 명령에 의해 생성된 텐서는 전형적으로 명령이 실행된 장치의 메모리에 의해 실행됩니다. 예를 들어:" + "대부분의 텐서플로 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 텐서를 CPU 와 GPU에 복사합니다.) 연산에 의해 생성된 텐서는 전형적으로 연산이 실행된 장치의 메모리에 의해 실행됩니다. 예를 들어:" ] }, { @@ -286,7 +286,7 @@ "source": [ "### 명시적 장치 배치\n", "\n", - "텐서플로에서 \"배치\"라는 용어는 개별 명령이 실행을 위해 장치를 할당(배치)하는 방법을 나타냅니다. 앞서 언급되었듯이, 명시적 지침이 없을경우 텐서플로는 명령을 실행하기위한 장치를 자동으로 결정하고, 필요시 텐서를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. 예를 들어:" + "텐서플로에서 \"배치\"라는 용어는 개별 연산을 실행하기 위해 장치에 할당(배치)하는 것입니다. 앞서 언급했듯이, 명시적 지침이 없을경우 텐서플로는 연산을 실행하기위한 장치를 자동으로 결정하고, 필요시 텐서를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. 예를 들어:" ] }, { @@ -311,14 +311,14 @@ " print(\"10 loops: {:0.2f}ms\".format(1000*result))\n", "\n", "\n", - "# CPU에 강제실행\n", + "# CPU에서 강제실행합니다.\n", "print(\"On CPU:\")\n", "with tf.device(\"CPU:0\"):\n", " x = tf.random_uniform([1000, 1000])\n", " assert x.device.endswith(\"CPU:0\")\n", " time_matmul(x)\n", "\n", - "# 이용가능시 GPU #0에 강제실행\n", + "# GPU #0가 이용가능시 GPU #0에서 강제실행합니다.\n", "if tf.test.is_gpu_available():\n", " with tf.device(\"GPU:0\"): # 또는 GPU:1, GPU:2\n", " x = tf.random_uniform([1000, 1000])\n", @@ -337,12 +337,12 @@ "\n", "이번 섹션에서는 모델에 데이터를 제공하기 위한 파이프라인을 구축하기 위해 [`tf.data.Dataset` API](https://www.tensorflow.org/guide/datasets)를 시연해볼 것입니다. 이는 다음을 포함합니다.\n", "\n", - "* `Dataset` 생성.\n", - "* 즉시 실행 활성화와 `Dataset`을 통한 반복\n", + "* 데이터셋 생성.\n", + "* 즉시 실행 활성화를 통한 데이터셋 반복\n", "\n", - "모델을 학습시키고, 평가 루프를 제공할 간단하고 재사용 가능한 조각으로부터 복잡한 입력 파이프라인을 구축하기위해 `Dataset`s API를 사용하기를 권장합니다. \n", + "모델을 학습시키고 평가 루프를 제공할 간단하고 재사용 가능한 조각으로부터, 복잡한 입력 파이프라인을 구축하기위해 데이터셋 API를 사용하기를 권장합니다. \n", "\n", - "만약 텐서플로 그래프에 익숙하다면, `Dataset` 객체를 생성하기 위한 API는 즉시 실행이 활성화 되어도 동일하게 유지됩니다. 하지만 그러나 데이터셋의 요소를 반복하는 프로세스는 약간 더 간단합니다.\n", + "만약 텐서플로 그래프에 익숙하다면, 데이터셋 객체를 생성하기 위한 API는 즉시 실행이 활성화 되어도 동일하게 유지됩니다. 하지만 데이터셋의 요소를 반복하는 프로세스가 약간 더 간단해집니다.\n", "또한 `tf.data.Dataset` 객체를 통하여 파이썬 반복문을 사용할 수 있으며, 명시적으로 `tf.data.Iterator` 객체를 생성할 필요가 없습니다.\n", "그 결과, [텐서플로 가이드](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시 실행이 활성화될 때에는 관계없습니다. " ] @@ -354,7 +354,7 @@ "id": "zI0fmOynH-Ne" }, "source": [ - "### `Dataset` 소스 생성\n", + "### 데이터셋 소스 생성\n", "\n", "굉장히 유용한 함수중 하나인 [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices)를 사용하여 데이터셋 소스를 생성하거나 파일로부터 읽어들이는 객체인 [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) 또는 [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset)를 사용하여 데이터셋 소스를 생성하세요. 더 많은 정보를 위해서 [텐서플로 가이드](https://www.tensorflow.org/guide/datasets#reading_input_data)를 참조하세요." ] @@ -371,7 +371,7 @@ "source": [ "ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6])\n", "\n", - "# CSV 파일 생성\n", + "# CSV 파일을 생성합니다.\n", "import tempfile\n", "_, filename = tempfile.mkstemp()\n", "\n", @@ -393,7 +393,7 @@ "source": [ "### 변환 적용\n", "\n", - "[`map`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`batch`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`shuffle`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle)과 같은 변환 함수를 사용하세요. 또한 데이터셋의 레코드에 변환을 적용하세요. 세부사항은 [`tf.data.Dataset`을 위한 API 문서](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)을 참조하세요." + "[`map`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`batch`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`shuffle`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle)과 같은 변환 함수를 사용하여 데이터셋의 레코드에 적용하세요. 세부사항은 [tf.data.Dataset을 위한 API 문서](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)을 참조하세요." ] }, { @@ -420,7 +420,7 @@ "source": [ "### 반복\n", "\n", - "즉시 실행이 활성화되면 `Dataset` 객체는 반복을 지원합니다. 만약 텐서플로 그래프에서 `Dataset`을 사용하는게 익숙하다면, `Dataset.make_one_shot_iterator()` 또는 `get_next()`와 같은 객체를 호출할 필요가 없는다는 것에 주목하세요." + "즉시 실행이 활성화되면 `Dataset` 객체는 반복이 가능합니다. 만약 텐서플로 그래프에서 데이터셋을 사용하는게 익숙하다면, `Dataset.make_one_shot_iterator()` 또는 `get_next()`와 같은 객체를 호출할 필요가 없는다는 것에 주목하세요." ] }, { diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md index 65c9547aced..5f0a17f5956 100644 --- a/site/ko/tutorials/eager/index.md +++ b/site/ko/tutorials/eager/index.md @@ -15,7 +15,7 @@ 1. [즉시 실행(Eager execution)](eager_basics.ipynb) 2. [자동 미분과 그래디언트 테이프(Automatic differentiation and gradient tape)](automatic_differentiation.ipynb) -3. [사용자 정의 학습 : 기초(Custom training: basics)](custom_training.ipynb) -4. [사용자 정의 layer(Custom layers)](custom_layers.ipynb) -5. [사용자 정의 학습 : 둘러보기(Custom training: walkthrough)](custom_training_walkthrough.ipynb) +3. [사용자 정의 학습 : 기초](custom_training.ipynb) +4. [사용자 정의 layer](custom_layers.ipynb) +5. [사용자 정의 학습 : 둘러보기](custom_training_walkthrough.ipynb) From 26d9447747c86cb8e7e12fac042ec964475447c5 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Thu, 4 Apr 2019 01:18:47 +0900 Subject: [PATCH 10/19] Update from 2e78c664 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change some word layer → 층 --- site/ko/tutorials/eager/custom_layers.ipynb | 43 ++++++++++++--------- site/ko/tutorials/eager/index.md | 4 +- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index e87e0d1fa0b..ad547086db7 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -41,7 +41,7 @@ "id": "60RdWsg1tETW" }, "source": [ - "# 사용자 정의 layer" + "# 사용자 정의 층" ] }, { @@ -96,13 +96,13 @@ "id": "zSFfVVjkrrsI" }, "source": [ - "## layer: 유용한 연산자 집합\n", + "## 층: 유용한 연산자 집합\n", "\n", "머신러닝을 위한 코드를 작성하는 대부분의 시간동안 개별적인 연산과 변수를 조작하는 것보다는 고수준의 추상화 수준에서 작업하기를 원합니다.\n", "\n", - "많은 머신러닝 모델은 비교적 단순한 layer의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로는 여러 표준 layer 세트를 제공하므로 사용자 고유의 응용 프로그램에 관련된 layer를 처음부터 작성하거나, 기존 layer의 구성으로 쉽게 작성할 수 있습니다.\n", + "많은 머신러닝 모델은 비교적 단순한 층(layer)의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로는 여러 표준형 층을 제공하므로 사용자 고유의 응용 프로그램에 관련된 층을 처음부터 작성하거나, 기존 층의 구성으로 쉽게 작성할 수 있습니다.\n", "\n", - "텐서플로는 [케라스](https://keras.io) API 의 풀패키지를 tf.keras package에 포함하고 있습니다. 케라스 layer는 모델을 구축하는데 매우 유용합니다." + "텐서플로는 [케라스](https://keras.io) API 의 풀패키지를 tf.keras package에 포함하고 있습니다. 케라스 층은 모델을 구축하는데 매우 유용합니다." ] }, { @@ -115,7 +115,7 @@ }, "outputs": [], "source": [ - "# tf.keras.layers 패키지에서 layer는 객체입니다. layer를 구성하려면 간단히 객체를 생성하십시오.\n", + "# tf.keras.layers 패키지에서 층은 객체입니다. 층을 구성하려면 간단히 객체를 생성하십시오.\n", "# 대부분의 layer는 첫번째 인수로 출력 차원(크기) 또는 채널을 취합니다.\n", "layer = tf.keras.layers.Dense(100)\n", "# 입력 차원의 수는 유추할 수 있기 때문에 종종 불필요합니다. \n", @@ -130,7 +130,7 @@ "id": "Fn69xxPO5Psr" }, "source": [ - "미리 구성되어있는 layer는 다음 [문서](https://www.tensorflow.org/api_docs/python/tf/keras/layers)에서 확인할 수 있습니다. Dense, Conv2D, LSTM, BatchNormalization, Dropout, 등을 포함하고 있습니다." + "미리 구성되어있는 층은 다음 [문서](https://www.tensorflow.org/api_docs/python/tf/keras/layers)에서 확인할 수 있습니다. Dense, Conv2D, LSTM, BatchNormalization, Dropout, 등을 포함하고 있습니다." ] }, { @@ -143,7 +143,7 @@ }, "outputs": [], "source": [ - "# layer를 사용하기 위해서 간단하게 호출합니다.\n", + "# 층을 사용하기 위해서 간단하게 호출합니다.\n", "layer(tf.zeros([10, 5]))" ] }, @@ -157,9 +157,9 @@ }, "outputs": [], "source": [ - "# layer는 유용한 메서드를 내재하고있습니다. 예를 들어, `layer.variables`를 사용하여 layer안에 있는 모든 변수를 확인할 수 있으며, \n", + "# layer는 유용한 메서드를 내재하고있습니다. 예를 들어, `layer.variables`를 사용하여 층안에 있는 모든 변수를 확인할 수 있으며, \n", "# `layer.trainable_variables`를 사용하여 학습가능한 변수를 확인할 수 있습니다. \n", - "# 이번 케이스에서 완전 연결(fully-connected) 레이어는 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", + "# 이번 케이스에서 완전 연결(fully-connected)층은 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", "layer.variables" ] }, @@ -184,13 +184,13 @@ "id": "O0kDbE54-5VS" }, "source": [ - "## 사용자 정의 layer 구현\n", - "사용자 정의 layer를 구현하는 가장 좋은 방법은 tf.keras.Layer 클래스를 상속하고 다음과 같이 구현하는 것입니다.\n", - " * `__init__` , 모든 독립적인 입력값을 초기화를 할 수 있습니다.\n", + "## 사용자 정의 층 구현\n", + "사용자 정의 층을 구현하는 가장 좋은 방법은 tf.keras.Layer 클래스를 상속하고 다음과 같이 구현하는 것입니다.\n", + " * `__init__` 에서 층에 필요한 매개변수를 입력 받습니다..\n", " * `build`, 입력 텐서의 크기를 알고 나머지를 초기화 할 수 있습니다.\n", " * `call`, 정방향 연산(forward computation)을 진행 할 수 있습니다.\n", "\n", - "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 layer가 작동할 입력의 크기를 기준으로 나중에 변수를 만들 수 있습니다. 반면에, `__init__`에 변수를 생성하는것은 변수 생성에 필요한 크기가 명시적으로 지정되어야 함을 의미합니다." + "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 층이 작동할 입력의 크기를 기준으로 나중에 변수를 만들 수 있습니다. 반면에, `__init__`에 변수를 생성하는것은 변수 생성에 필요한 크기가 명시적으로 지정되어야 함을 의미합니다." ] }, { @@ -230,7 +230,7 @@ "source": [ "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. \n", "\n", - "다른 독자가 표준 layer의 동작을 잘 알고 있기 때문에, 가능한 경우 표준 layer를 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers 또는 tf.contrib.layers에 없는 layer를 사용하기 원하면 [github issue](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀리퀘스트를 요청하세요." + "다른 독자가 표준형 층의 동작을 잘 알고 있기 때문에, 가능한 경우 표준형 층을 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers 또는 tf.contrib.layers에 없는 층을 사용하기 원하면 [github issue](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀리퀘스트를 요청하세요." ] }, { @@ -240,11 +240,11 @@ "id": "Qhg4KlbKrs3G" }, "source": [ - "## 모델: layer 구성\n", + "## 모델: 층 구성\n", "\n", - "머신러닝 모델에서 대부분의 흥미로운 유사 layer(layer-likely)는 layer의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 잔여 블록(residual block)은 합성곱(convolution), 배치 정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", + "머신러닝 모델에서 대부분의 흥미로운 유사 layer(layer-likely)는 여러 층의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 잔여 블록(residual block)은 합성곱(convolution), 배치 정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", "\n", - "layer 집합을 포함한 유사 layer를 생성하기위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현합니다." + "여러 층의 집합을 포함한 유사 layer를 생성하기위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현합니다." ] }, { @@ -321,8 +321,15 @@ "source": [ "# 다음 단계\n", "\n", - "이제 이전 노트북으로 돌아가서 선형 회귀 예제에 좀 더 나은 구조를 만들기 위해 layer와 모델을 적용할 수 있습니다." + "이제 이전 노트북으로 돌아가서 선형 회귀 예제에 좀 더 나은 구조를 만들기 위해 층과 모델을 적용할 수 있습니다." ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md index 5f0a17f5956..5966fe1e419 100644 --- a/site/ko/tutorials/eager/index.md +++ b/site/ko/tutorials/eager/index.md @@ -10,12 +10,12 @@ 메일을 보내주시기 바랍니다. 즉시실행(Eager execution)은 더 나은 연산을 위한 실행에 의해 정의되는 명령형 인터페이스를 제공합니다. -사용자 정의 layer, 정방향 전파, 자동미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 시작한 다음 순서대로 진행하세요. +사용자 정의 층, 정방향 전파, 자동 미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 시작한 다음 순서대로 진행하세요. [즉시 실행 가이드](../../guide/eager). 1. [즉시 실행(Eager execution)](eager_basics.ipynb) 2. [자동 미분과 그래디언트 테이프(Automatic differentiation and gradient tape)](automatic_differentiation.ipynb) 3. [사용자 정의 학습 : 기초](custom_training.ipynb) -4. [사용자 정의 layer](custom_layers.ipynb) +4. [사용자 정의 층](custom_layers.ipynb) 5. [사용자 정의 학습 : 둘러보기](custom_training_walkthrough.ipynb) From bbdbecb1c9748153243dd2b86e6777d67d94dd39 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Thu, 4 Apr 2019 16:47:57 +0900 Subject: [PATCH 11/19] Update from f50c18c4 Second review with @rickiepark --- .../eager/automatic_differentiation.ipynb | 20 +++++- site/ko/tutorials/eager/custom_layers.ipynb | 68 ++++++++++-------- site/ko/tutorials/eager/custom_training.ipynb | 24 +++++-- .../eager/custom_training_walkthrough.ipynb | 72 +++++++++++-------- site/ko/tutorials/eager/eager_basics.ipynb | 20 +++++- site/ko/tutorials/eager/index.md | 4 +- 6 files changed, 138 insertions(+), 70 deletions(-) diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index 27866a090d4..e0649886ffc 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -53,17 +53,31 @@ "source": [ "\n", " \n", " \n", " \n", "
\n", - " View on TensorFlow.org\n", + " TensorFlow.org에서 보기\n", " \n", - " Run in Google Colab\n", + " 구글 코랩(Colab)에서 실행하기\n", " \n", - " View source on GitHub\n", + " 깃허브(GitHub) 소스 보기\n", "
" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", + "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", + "이 번역에 개선할 부분이 있다면\n", + "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", + "문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을\n", + "작성하거나\n", + "[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로\n", + "메일을 보내주시기 바랍니다." + ] + }, { "cell_type": "markdown", "metadata": { diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index ad547086db7..c716311304c 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -53,17 +53,31 @@ "source": [ "\n", " \n", " \n", " \n", "
\n", - " View on TensorFlow.org\n", + " TensorFlow.org에서 보기\n", " \n", - " Run in Google Colab\n", + " 구글 코랩(Colab)에서 실행하기\n", " \n", - " View source on GitHub\n", + " 깃허브(GitHub) 소스 보기\n", "
" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", + "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", + "이 번역에 개선할 부분이 있다면\n", + "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", + "문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을\n", + "작성하거나\n", + "[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로\n", + "메일을 보내주시기 바랍니다." + ] + }, { "cell_type": "markdown", "metadata": { @@ -71,7 +85,7 @@ "id": "UEu3q4jmpKVT" }, "source": [ - "신경망을 구축하기 위해서 고수준 API인 `tf.keras`를 사용하길 권합니다. 대부분의 텐서플로 API는 즉시 실행(eager execution)을 활성화할 수 있습니다." + "신경망을 구축하기 위해서 고수준 API인 `tf.keras`를 사용하길 권합니다. 대부분의 텐서플로 API는 즉시 실행(eager execution)과 함께 사용할 수 있습니다." ] }, { @@ -98,11 +112,11 @@ "source": [ "## 층: 유용한 연산자 집합\n", "\n", - "머신러닝을 위한 코드를 작성하는 대부분의 시간동안 개별적인 연산과 변수를 조작하는 것보다는 고수준의 추상화 수준에서 작업하기를 원합니다.\n", + "머신러닝을 위한 코드를 작성하는 대부분의 경우에 개별적인 연산과 변수를 조작하는 것보다는 높은 수준의 추상화에서 작업할 것입니다.\n", "\n", - "많은 머신러닝 모델은 비교적 단순한 층(layer)의 구성과 적층(stacking)으로 표현가능합니다. 또한 텐서플로는 여러 표준형 층을 제공하므로 사용자 고유의 응용 프로그램에 관련된 층을 처음부터 작성하거나, 기존 층의 구성으로 쉽게 작성할 수 있습니다.\n", + "많은 머신러닝 모델은 비교적 단순한 층(layer)을 조합하고 쌓아서 표현가능합니다. 또한 텐서플로는 여러 표준형 층을 제공하므로 사용자 고유의 응용 프로그램에 관련된 층을 처음부터 작성하거나, 기존 층의 조합으로 쉽게 만들 수 있습니다.\n", "\n", - "텐서플로는 [케라스](https://keras.io) API 의 풀패키지를 tf.keras package에 포함하고 있습니다. 케라스 층은 모델을 구축하는데 매우 유용합니다." + "텐서플로는 [전체 케라스](https://keras.io) API를 tf.keras 패키지에 포함하고 있습니다. 케라스 층은 모델을 구축하는데 매우 유용합니다." ] }, { @@ -118,7 +132,7 @@ "# tf.keras.layers 패키지에서 층은 객체입니다. 층을 구성하려면 간단히 객체를 생성하십시오.\n", "# 대부분의 layer는 첫번째 인수로 출력 차원(크기) 또는 채널을 취합니다.\n", "layer = tf.keras.layers.Dense(100)\n", - "# 입력 차원의 수는 유추할 수 있기 때문에 종종 불필요합니다. \n", + "# 입력 차원의 수는 층을 처음 실행할 때 유추할 수 있기 때문에 종종 불필요합니다. \n", "# 일부 복잡한 모델에서는 수동으로 입력 차원의 수를 제공하는것이 유용할 수 있습니다.\n", "layer = tf.keras.layers.Dense(10, input_shape=(None, 5))" ] @@ -130,7 +144,7 @@ "id": "Fn69xxPO5Psr" }, "source": [ - "미리 구성되어있는 층은 다음 [문서](https://www.tensorflow.org/api_docs/python/tf/keras/layers)에서 확인할 수 있습니다. Dense, Conv2D, LSTM, BatchNormalization, Dropout, 등을 포함하고 있습니다." + "미리 구성되어있는 층은 다음 [문서](https://www.tensorflow.org/api_docs/python/tf/keras/layers)에서 확인할 수 있습니다. Dense(완전 연결 층), Conv2D, LSTM, BatchNormalization, Dropout, 등을 포함하고 있습니다." ] }, { @@ -143,7 +157,7 @@ }, "outputs": [], "source": [ - "# 층을 사용하기 위해서 간단하게 호출합니다.\n", + "# 층을 사용하려면, 간단하게 호출합니다.\n", "layer(tf.zeros([10, 5]))" ] }, @@ -157,9 +171,9 @@ }, "outputs": [], "source": [ - "# layer는 유용한 메서드를 내재하고있습니다. 예를 들어, `layer.variables`를 사용하여 층안에 있는 모든 변수를 확인할 수 있으며, \n", - "# `layer.trainable_variables`를 사용하여 학습가능한 변수를 확인할 수 있습니다. \n", - "# 이번 케이스에서 완전 연결(fully-connected)층은 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", + "# layer는 유용한 메서드를 많이 가지고 있습니다. 예를 들어, `layer.variables`를 사용하여 층안에 있는 모든 변수를 확인할 수 있으며, \n", + "# `layer.trainable_variables`를 사용하여 훈련가능한 변수를 확인할 수 있습니다. \n", + "# 완전 연결(fully-connected)층은 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", "layer.variables" ] }, @@ -173,7 +187,7 @@ }, "outputs": [], "source": [ - "# 또한 변수는 여러 접근자(accessors)를 통해 접근가능합니다. \n", + "# 또한 변수는 객체의 속성을 통해 편리하게 접근가능합니다. \n", "layer.kernel, layer.bias" ] }, @@ -190,7 +204,7 @@ " * `build`, 입력 텐서의 크기를 알고 나머지를 초기화 할 수 있습니다.\n", " * `call`, 정방향 연산(forward computation)을 진행 할 수 있습니다.\n", "\n", - "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 층이 작동할 입력의 크기를 기준으로 나중에 변수를 만들 수 있습니다. 반면에, `__init__`에 변수를 생성하는것은 변수 생성에 필요한 크기가 명시적으로 지정되어야 함을 의미합니다." + "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도 있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 층이 작동할 입력의 크기를 기준으로 나중에 변수를 만들 수 있다는 것입니다. 반면에, `__init__`에 변수를 생성하는 것은 변수 생성에 필요한 크기가 명시적으로 지정되어야 함을 의미합니다." ] }, { @@ -228,9 +242,7 @@ "id": "tk8E2vY0-z4Z" }, "source": [ - "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도있습니다. \n", - "\n", - "다른 독자가 표준형 층의 동작을 잘 알고 있기 때문에, 가능한 경우 표준형 층을 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers 또는 tf.contrib.layers에 없는 층을 사용하기 원하면 [github issue](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀리퀘스트를 요청하세요." + "다른 독자가 표준형 층의 동작을 잘 알고 있기 때문에, 가능한 경우 표준형 층을 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers 또는 tf.contrib.layers에 없는 층을 사용하기 원하면 [깃허브](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀 리퀘스트(pull request)를 보내세요." ] }, { @@ -242,9 +254,9 @@ "source": [ "## 모델: 층 구성\n", "\n", - "머신러닝 모델에서 대부분의 흥미로운 유사 layer(layer-likely)는 여러 층의 집합으로 구현되어집니다. 예를 들어, 레스넷(resnet)의 각 잔여 블록(residual block)은 합성곱(convolution), 배치 정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어있습니다. \n", + "머신러닝 모델에서 대부분의 재미있는 많은 것들은 기존의 층을 조합하여 구현됩니다. 예를 들어, 레스넷(resnet)의 각 잔여 블록(residual block)은 합성곱(convolution), 배치 정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어 있습니다. \n", "\n", - "여러 층의 집합을 포함한 유사 layer를 생성하기위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현합니다." + "다른층을 포함한 모델을 만들기 위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현한 코드입니다." ] }, { @@ -292,6 +304,13 @@ "print([x.name for x in block.trainable_variables])" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "그러나 대부분의 경우에, 많은 층으로 구성된 모델은 간단하게 연이어 하나의 층으로 호출할 수 있습니다. 이는 tf.keras.Sequential 사용하여 간단한 코드로 구현 가능합니다." + ] + }, { "cell_type": "code", "execution_count": null, @@ -321,15 +340,8 @@ "source": [ "# 다음 단계\n", "\n", - "이제 이전 노트북으로 돌아가서 선형 회귀 예제에 좀 더 나은 구조를 만들기 위해 층과 모델을 적용할 수 있습니다." + "이제 이전 노트북으로 돌아가서 선형 회귀 예제에 층과 모델을 사용하여 좀 더 나은 구조를 적용할 수 있습니다." ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/site/ko/tutorials/eager/custom_training.ipynb b/site/ko/tutorials/eager/custom_training.ipynb index f83e416b129..ee45fd16603 100644 --- a/site/ko/tutorials/eager/custom_training.ipynb +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -53,17 +53,31 @@ "source": [ "\n", " \n", " \n", " \n", "
\n", - " View on TensorFlow.org\n", + " TensorFlow.org에서 보기\n", " \n", - " Run in Google Colab\n", + " 구글 코랩(Colab)에서 실행하기\n", " \n", - " View source on GitHub\n", + " 깃허브(GitHub) 소스 보기\n", "
" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", + "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", + "이 번역에 개선할 부분이 있다면\n", + "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", + "문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을\n", + "작성하거나\n", + "[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로\n", + "메일을 보내주시기 바랍니다." + ] + }, { "cell_type": "markdown", "metadata": { @@ -119,7 +133,7 @@ "source": [ "## 변수\n", "\n", - "텐서플로 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝 모델은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 연산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어에 의존한 선택이 가능합니다. " + "텐서플로 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝 모델은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 연산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어를 사용 할 수 있습니다. " ] }, { @@ -430,7 +444,7 @@ "\n", "이번 튜토리얼에서는 변수를 다루었으며, 지금까지 논의된 초기 타입의 텐서플로를 사용하여 간단한 선형모델을 구축하고 훈련시켰습니다.\n", "\n", - "이론적으로, 이것은 텐서플로를 머신러닝 연구에 사용하는데 필요한 대부분입니다. 실제로 신경망에 있어 `tf.keras`와 같은 고수준 API는 고수준 빌딩 블록(\"layer\"로 불리는)을 제공하고, 저장 및 복원을 위한 유틸리티, 손실 함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " + "이론적으로, 이것은 텐서플로를 머신러닝 연구에 사용하는데 필요한 대부분입니다. 실제로 신경망에 있어 `tf.keras`와 같은 고수준 API는 고수준 빌딩 블록(\"층\"으로 불리는)을 제공하고, 저장 및 복원을 위한 유틸리티, 손실 함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " ] }, { diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index ccd4cf0586c..46b3469ab9a 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -53,17 +53,31 @@ "source": [ "\n", " \n", " \n", " \n", "
\n", - " View on TensorFlow.org\n", + " TensorFlow.org에서 보기\n", " \n", - " Run in Google Colab\n", + " 구글 코랩(Colab)에서 실행하기\n", " \n", - " View source on GitHub\n", + " 깃허브(GitHub) 소스 보기\n", "
" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", + "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", + "이 번역에 개선할 부분이 있다면\n", + "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", + "문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을\n", + "작성하거나\n", + "[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로\n", + "메일을 보내주시기 바랍니다." + ] + }, { "cell_type": "markdown", "metadata": { @@ -112,9 +126,9 @@ "source": [ "### 임포트 및 즉시 실행 구성\n", "\n", - "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화할 것입니다. 즉시 실행은 텐서플로가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게합니다. 만약 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙하실겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용가능합니다.\n", + "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화할 것입니다. 즉시 실행은 텐서플로가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게 합니다. 만약 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙할 겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용 가능합니다.\n", "\n", - "즉시 실행이 활성화 될때, 동일한 프로그램내에서는 비활성화를 할 수 없습니다. 더 많은 세부사항은 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)을 참조하세요." + "즉시 실행이 활성화될 때, 동일한 프로그램내에서 비활성화 할 수 없습니다. 더 많은 세부사항은 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)을 참조하세요." ] }, { @@ -257,7 +271,7 @@ "source": [ "처음 5개의 데이터로부터 다음을 주목하세요.\n", "\n", - "1. 첫번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", + "1. 첫 번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", " * 총 120개의 예가 있으며, 각 예들은 4가지의 특성(feature), 3가지 가능한 레이블(label)을 가지고 있습니다.\n", "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[예](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 예제의 특징을 나타냅니다. 이 필드들는 붓꽃의 측정값을 부동소수점으로 나타냅니다.\n", @@ -285,7 +299,7 @@ } ], "source": [ - "# CSV 파일내에서 컬럼의 순서\n", + "# CSV 파일안에서 컬럼의 순서\n", "column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']\n", "\n", "feature_names = column_names[:-1]\n", @@ -302,13 +316,13 @@ "id": "CCtwLoJhhDNc" }, "source": [ - "각각의 레이블은 \"setosa\"와 같은 문자형 이름과 연관되어있습니다. 하지만 머신러닝은 전형적으로 숫자형값에 의존합니다. 레이블을 다음과 같이 맵핑(mapping) 합니다. \n", + "각각의 레이블은 \"setosa\"와 같은 문자형 이름과 연관되어있습니다. 하지만 머신러닝은 전형적으로 숫자형 값에 의존합니다. 레이블을 다음과 같이 맵핑(mapping) 합니다. \n", "\n", "* `0`: Iris setosa\n", "* `1`: Iris versicolor\n", "* `2`: Iris virginica\n", "\n", - "특성과 레이블에 관한 더 많은 정보를 위해서는 다음을 참조하세요. [ML Terminology section of the Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/framing/ml-terminology)." + "특성과 레이블에 관한 더 많은 정보를 위해서는 [머신러닝 특강의 전문용어 부분](https://developers.google.com/machine-learning/crash-course/framing/ml-terminology)을 참조하세요." ] }, { @@ -333,7 +347,7 @@ "source": [ "### `tf.data.Dataset` 생성\n", "\n", - "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위한 많은 케이스를 다룹니다. 이는 훈련을 위한 형식으로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 다음을 참조하세요. [Datasets Quick Start guide](https://www.tensorflow.org/get_started/datasets_quickstart) \n", + "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위한 많은 케이스를 다룹니다. 이는 훈련을 위한 형식으로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 [데이터셋 빠른 실행 가이드](https://www.tensorflow.org/get_started/datasets_quickstart)를 참조하세요. \n", "\n", "\n", "데이터셋이 CSV 형태의 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 [배치 사이즈(batch_size)](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." @@ -422,7 +436,7 @@ "id": "E63mArnQaAGz" }, "source": [ - "유사한 특성의 값은 같이 그룹되어있거나, *배치* 되있다는 사실에 주목하세요. 각 예제행의 필드는 해당 특성 배열에 추가됩니다. `batch_size` 조절하여 이 특성 배열에 저장된 예제의 수를 설정하세요.\n", + "유사한 특성의 값은 같이 그룹되어있거나, *배치* 되있다는 사실에 주목하세요. 각 예제행의 필드는 해당 특성 배열에 추가됩니다. `batch_size`를 조절하여 이 특성 배열에 저장된 예제의 수를 설정하세요.\n", "\n", "또한 배치(batch)로부터 약간의 특성을 도식화하여 군집되있는 데이터를 확인할 수 있습니다. " ] @@ -468,7 +482,7 @@ "source": [ "모델 구축단계를 단순화하기 위해서, 특성(사전형 객체)을 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", "\n", - "이 함수는 `텐서`의 list로부터 값을 취하고 특정한 차원으로 결합된 `텐서`를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메서드(method)를 사용합니다." + "이 함수는 텐서의 list로부터 값을 취하고 특정한 차원으로 결합된 텐서를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메서드(method)를 사용합니다." ] }, { @@ -494,7 +508,7 @@ "id": "V1Vuph_eDl8x" }, "source": [ - "그 후 각 `(features,label)`쌍의 `features`을 훈련 데이터셋에 적재하기위해 [tf.data.Dataset.map](https://www.tensorflow.org/api_docs/python/tf/data/dataset/map) 메서드를 사용합니다. " + "그 후 각 `(features,label)`쌍의 특성을 훈련 데이터셋에 쌓기위해 [tf.data.Dataset.map](https://www.tensorflow.org/api_docs/python/tf/data/dataset/map) 메서드를 사용합니다. " ] }, { @@ -577,7 +591,7 @@ "
\n", "\n", - "그림 2의 모델이 훈련되고 레이블 되어있지 않은 데이터를 제공했을때, 모델은 주어진 데이터의 3가지 예측을 출력(주어진 레이블의 개수)합니다. 이러한 예측은 *[추론(inference)](https://developers.google.com/machine-learning/crash-course/glossary#inference)*이라고 정의합니다. 이 예제에서 출력의 합은 1.0입니다. 그림 2에서 예측은 *Iris setosa* `0.02`, *Iris versicolor* `0.95`, *Iris virginica*에 `0.03`로 주어집니다. 이는 모델이 95%의 확률로 주어진 데이터를 *Iris versicolor*로 예측한다는 것을 의미합니다. " + "그림 2의 모델이 훈련되고 레이블 되어있지 않은 데이터를 제공했을때, 모델은 주어진 데이터의 3가지 예측을 출력(주어진 레이블의 개수)합니다. 이러한 예측은 *[추론(inference)](https://developers.google.com/machine-learning/crash-course/glossary#inference)*이라고 불립니다. 이 예제에서 출력의 합은 1.0입니다. 그림 2에서 예측은 *Iris setosa* `0.02`, *Iris versicolor* `0.95`, *Iris virginica*에 `0.03`로 주어집니다. 이는 모델이 95%의 확률로 주어진 데이터를 *Iris versicolor*로 예측한다는 것을 의미합니다. " ] }, { @@ -591,7 +605,7 @@ "\n", "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 layer를 생성하기위한 풍부한 라이브러리를 제공합니다. 이는 연결되있는 모든것을 케라스가 처리하여 모델을 구축하기 쉽게 만듭니다.\n", "\n", - "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 layer의 선형 적층 모델입니다. 이 구조는 layer의 인스턴스를 취하며, 아래의 케이스의 경우 각 layer당 10개의 노드(node)를 가지는 2개의 [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)층과 3개의 예측(레이블의 수)노드를 가지는 출력 층으로 구성되어있습니다. 첫번째 layer의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." + "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 여러 층을 연이어 쌓은 모델입니다. 이 구조는 층의 인스턴스를 취하며, 아래의 케이스의 경우 각 층당 10개의 노드(node)를 가지는 2개의 [Dense(완전 연결 층)](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)와 3개의 예측(레이블의 수)노드를 가지는 출력 층으로 구성되어있습니다. 첫번째 층의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." ] }, { @@ -618,9 +632,9 @@ "id": "FHcbEzMpxbHL" }, "source": [ - "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 층의 출력의 크기를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 단일층과 동일하다고 생각할 수 있습니다. 사용가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", + "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 층의 출력의 크기를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 하나의 층과 동일하다고 생각할 수 있습니다. 사용 가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", "\n", - "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 좌우됩니다. 머신러닝의 여러측면과 마찬가지로, 최적의 신경망 타입을 결정하는것은 많은 경험과 지식이 필요합니다. 경험을 토대로, 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." + "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 좌우됩니다. 머신러닝의 여러 측면과 마찬가지로, 최적의 신경망 타입을 결정하는 것은 많은 경험과 지식이 필요합니다. 경험을 토대로, 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." ] }, { @@ -750,7 +764,7 @@ "\n", "*[훈련 단계](https://developers.google.com/machine-learning/crash-course/glossary#training)*는 모델이 점진적으로 최적화되거나 데이터셋을 학습하는 머신러닝의 과정입니다. 훈련의 목적은 미지의 데이터를 예측하기 위해, 훈련 데이터셋의 구조에 대해서 충분히 학습하는 것입니다. 만약 모델이 훈련 데이터셋에 대해서 과하게 학습된다면 오직 훈련 데이터셋에 대해서 작동할 것이며, 일반화되기 힘들 것입니다. 이러한 문제를 *[과대적합(overfitting)](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)* 이라고 합니다. 이는 마치 문제를 이해하고 해결한다기보다는 답을 기억하는 것이라고 생각할 수 있습니다. \n", "\n", - "붓꽃 분류 문제는 지도학습 *[지도 학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시 중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도 학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고 있지않습니다. 대신에 모델은 특성간의 패턴을 찾습니다. " + "붓꽃 분류 문제는 *[지도 학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시 중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도 학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고 있지 않습니다. 대신에 모델은 특성간의 패턴을 찾습니다. " ] }, { @@ -827,9 +841,9 @@ "id": "lOxFimtlKruu" }, "source": [ - "### 옵티마이저(Optimizer) 생성 \n", + "### 옵티마이저 생성 \n", "\n", - "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 `손실`함수를 최소화하기위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 이 함수의 최저점을 찾고자합니다. 그래디언트는 가장 가파른 상승방향을 가르키며 따라서 반대방향으로 이동하는 여행을 합니다.각 배치마다의 손실과 기울기를 반복적으로 계산하여 훈련 중에 모델을 조정합니다. 점진적으로, 모델은 손실을 최소화하기위해 가중치(weight)와 편향(bias)의 최적의 조합을 찾아냅니다. 더 적은 손실을 통해 더 좋은 모델의 예측을 기대할 수 있습니다. \n", + "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 `손실` 함수를 최소화하기 위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실 함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 이 함수의 최저점을 찾고자 합니다. 그래디언트는 가장 가파른 상승 방향을 가리키며 따라서 반대 방향으로 이동하는 여행을 합니다. 각 배치마다의 손실과 기울기를 반복적으로 계산하여 훈련 중에 모델을 조정합니다. 점진적으로, 모델은 손실을 최소화하기 위해 가중치(weight)와 편향(bias)의 최적의 조합을 찾아냅니다. 더 적은 손실을 통해 더 좋은 모델의 예측을 기대할 수 있습니다. \n", "\n", "\n", " \n", "
\n", @@ -841,7 +855,7 @@ "
\n", "\n", - "텐서플로는 학습을 위해 이용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 그래디언트 하강(stochastic gradient descent, SGD)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현하는 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. 매개변수 `learning_rate`은 경사하강 과정의 크기를 나타내는 척도이며, 더 나은 결과를 위해 공동적으로 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " + "텐서플로는 학습을 위해 이용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 경사 하강(stochastic gradient descent, SGD)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현하는 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. 매개변수 `learning_rate`은 경사하강 과정의 크기를 나타내는 척도이며, 더 나은 결과를 위해 공동적으로 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " ] }, { @@ -876,7 +890,7 @@ "id": "pJVRZ0hP52ZB" }, "source": [ - "이 값들을 단일 최적화 단계를 계산하기위해 사용합니다. " + "이 값들을 단일 최적화 단계를 계산하기 위해 사용합니다. " ] }, { @@ -905,7 +919,7 @@ "\n", "optimizer.apply_gradients(zip(grads, model.trainable_variables), global_step)\n", "\n", - "print(\"단계: {}, 손실: {}\".format(global_step.numpy(),\n", + "print(\"단계: {}, 손실: {}\".format(global_step.numpy(),\n", " loss(model, features, labels).numpy()))" ] }, @@ -918,16 +932,16 @@ "source": [ "### 훈련 루프\n", "\n", - "모든 조각을 가지고, 모델은 학습할 준비가 되었습니다! 훈련 루프는 더 나은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 아래의 훈련 단계를 작성한 것입니다. \n", + "모든 조각을 가지고, 모델은 학습할 준비가 되었습니다! 훈련 루프는 더 좋은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 아래의 훈련 단계를 작성한 것입니다. \n", "\n", "1. 각 *에포크(epoch)* 반복. 에포크는 데이터셋을 통과시키는 횟수입니다. \n", - "2. 에포크내에서, `데이터셋`의 *특성* (`x`)와 *레이블* (`y`)를 가져오는 예제를 반복합니다.\n", - "3. 예제의 특성을 사용하여 결과를 예측을 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기위해 사용합니다. \n", - "4. 모델의 변수를 업데이트하기위해 `옵티마이저`를 사용합니다. \n", + "2. 에포크 내에서, `데이터셋`의 *특성* (`x`)와 *레이블* (`y`)를 가져오는 예제를 반복합니다.\n", + "3. 예제의 특성을 사용하여 결과를 예측을 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기 위해 사용합니다. \n", + "4. 모델의 변수를 업데이트하기 위해 `옵티마이저`를 사용합니다. \n", "5. 시각화를 위해 몇가지 값을 추적합니다.\n", "6. 각 에포크를 반복합니다.\n", "\n", - "`num_epochs` 변수는 데이터셋 반복 횟수입니다. 반직관적으로, 모델을 길게 학습하는것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는것은 경험과 직관을 필요로 합니다. " + "`num_epochs` 변수는 데이터셋 반복 횟수입니다. 반직관적으로, 모델을 길게 학습하는것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는것은 많은 경험과 직관을 필요로 합니다. " ] }, { @@ -1207,7 +1221,7 @@ "\n", "이제 붓꽃을 분류하기위해 완벽하지는 않지만 어느정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)를 예측해봅시다.\n", "\n", - "실제로는 레이블되지 않은 예제들은 여러 소스(앱, CSV 파일, 직접제공 등)로 부터 제공될 수 있습니다. 지금은 레이블을 예측하기위해 수동으로 3개의 레이블되지 않은 예제를 제공하겠습니다. 레이블은 다음과 붓꽃이름으로 맵핑되어있습니다.\n", + "실제로는 레이블 되지 않은 예제들은 여러 소스(앱, CSV 파일, 직접 제공 등)로부터 제공될 수 있습니다. 지금은 레이블을 예측하기 위해 수동으로 3개의 레이블되지 않은 예제를 제공하겠습니다. 레이블은 다음과 붓꽃 이름으로 매핑되어있습니다.\n", "* `0`: Iris setosa\n", "* `1`: Iris versicolor\n", "* `2`: Iris virginica" diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index afafd614e23..95f18839886 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -53,17 +53,31 @@ "source": [ "\n", " \n", " \n", " \n", "
\n", - " View on TensorFlow.org\n", + " TensorFlow.org에서 보기\n", " \n", - " Run in Google Colab\n", + " 구글 코랩(Colab)에서 실행하기\n", " \n", - " View source on GitHub\n", + " 깃허브(GitHub) 소스 보기\n", "
" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", + "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", + "이 번역에 개선할 부분이 있다면\n", + "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", + "문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을\n", + "작성하거나\n", + "[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로\n", + "메일을 보내주시기 바랍니다." + ] + }, { "cell_type": "markdown", "metadata": { diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md index 5966fe1e419..cdb89aeae1c 100644 --- a/site/ko/tutorials/eager/index.md +++ b/site/ko/tutorials/eager/index.md @@ -13,8 +13,8 @@ 사용자 정의 층, 정방향 전파, 자동 미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 시작한 다음 순서대로 진행하세요. [즉시 실행 가이드](../../guide/eager). -1. [즉시 실행(Eager execution)](eager_basics.ipynb) -2. [자동 미분과 그래디언트 테이프(Automatic differentiation and gradient tape)](automatic_differentiation.ipynb) +1. [즉시 실행](eager_basics.ipynb) +2. [자동 미분과 그래디언트 테이프](automatic_differentiation.ipynb) 3. [사용자 정의 학습 : 기초](custom_training.ipynb) 4. [사용자 정의 층](custom_layers.ipynb) 5. [사용자 정의 학습 : 둘러보기](custom_training_walkthrough.ipynb) From d14335d2de650ad36b207c06728a81544a3bc9b7 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Tue, 9 Apr 2019 15:33:46 +0900 Subject: [PATCH 12/19] Update from 61d453b5 --- site/ko/tutorials/eager/custom_training.ipynb | 87 ++--- .../eager/custom_training_walkthrough.ipynb | 325 +++++------------- site/ko/tutorials/eager/eager_basics.ipynb | 17 +- site/ko/tutorials/eager/index.md | 2 +- 4 files changed, 120 insertions(+), 311 deletions(-) diff --git a/site/ko/tutorials/eager/custom_training.ipynb b/site/ko/tutorials/eager/custom_training.ipynb index ee45fd16603..8431c372bcf 100644 --- a/site/ko/tutorials/eager/custom_training.ipynb +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -85,9 +85,9 @@ "id": "k2o3TTG4TFpt" }, "source": [ - "이전 튜토리얼에서는 머신러닝을 위한 기초 빌딩 블록인 자동 미분(automatic differentiation)을 위한 텐서플로 API를 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 초기 타입의 텐서플로를 사용하여 간단한 머신러닝을 구축해보겠습니다. \n", + "이전 튜토리얼에서는 머신러닝을 위한 기본 구성 요소인 자동 미분(automatic differentiation)을 위한 텐서플로 API를 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 텐서플로의 기본 요소를 사용하여 간단한 머신러닝을 수행해보겠습니다. \n", "\n", - "텐서플로는 상용구를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 `tf.keras`를 포함하고 있습니다. 신경망에 관련된 일을 하고 있는 사람에게는 이러한 고수준의 API을 강하게 추천합니다. 그러나 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위한 신경망 학습을 다루겠습니다. " + "텐서플로는 반복되는 코드를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 `tf.keras`를 포함하고 있습니다. 신경망을 다룰 때 이러한 고수준의 API을 강하게 추천합니다. 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위해 기본적인 요소만으로 신경망 훈련시켜 보겠습니다." ] }, { @@ -102,23 +102,16 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "PJ64L90aVir3" }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\82108\\Anaconda3\\lib\\site-packages\\h5py\\__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n", - " from ._conv import register_converters as _register_converters\n" - ] - } - ], + "outputs": [], "source": [ + "from __future__ import absolute_import, division, print_function, unicode_literals\n", + "\n", "import tensorflow as tf\n", "\n", "tf.enable_eager_execution()" @@ -133,7 +126,7 @@ "source": [ "## 변수\n", "\n", - "텐서플로 안에서 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝 모델은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다른 양상(희망적으로 더 낮은 손실로 가는 방향으로)을 보여야 합니다. 이 연산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 상태가 변경 가능한 파이썬 언어를 사용 할 수 있습니다. " + "텐서플로의 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝 모델은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다르게(희망하건대 더 낮은 손실로 가는 방향으로)동작해야 합니다. 이 연산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 명령형 프로그래밍 언어인 파이썬을 사용 할 수 있습니다. " ] }, { @@ -146,9 +139,9 @@ }, "outputs": [], "source": [ - "# 파이썬 state 사용\n", + "# 파이썬 구문 사용\n", "x = tf.zeros([10, 10])\n", - "x += 2 # 이것은 x = x + 2와 같으며, 초기값 x를 변경하지 않습니다.\n", + "x += 2 # 이것은 x = x + 2와 같으며, x의 초기값을 변경하지 않습니다.\n", "print(x)" ] }, @@ -159,9 +152,9 @@ "id": "wfneTXy7JcUz" }, "source": [ - "그러나 텐서플로는 상태가 변경 가능한 연산자가 내장되어 있으며, 이러한 연산자는 상태를 표현하기 위한 저수준 파이썬 표현보다 사용하기가 더 좋습니다. 예를 들어, 모델에서 가중치를 나타내기 위해서 텐서플로 변수를 사용하는것이 편하고 효율적입니다. \n", + "텐서플로는 상태를 변경할 수 있는 연산자가 내장되어 있으며, 이러한 연산자는 상태를 표현하기 위한 저수준 파이썬 표현보다 사용하기가 더 좋습니다. 예를 들어, 모델에서 가중치를 나타내기 위해서 텐서플로 변수를 사용하는 것이 편하고 효율적입니다. \n", "\n", - "텐서플로 변수는 값을 저장하고 텐서플로 연산에 사용될 때 묵시적으로 저장된 값을 읽어오는 객체입니다. `tf.assign_sub`, `tf.scatter_update` 등은 텐서플로 변수에 저장되있는 값을 조작하는 연산자입니다." + "텐서플로 변수는 값을 저장하는 객체로 텐서플로 연산에 사용될 때 저장된 이 값을 읽어올 것입니다. `tf.assign_sub`, `tf.scatter_update` 등은 텐서플로 변수에 저장되있는 값을 조작하는 연산자입니다." ] }, { @@ -181,7 +174,7 @@ "v.assign(3.0)\n", "assert v.numpy() == 3.0\n", "\n", - "# 텐서플로 연산내에서 `v` 사용합니다. \n", + "# tf.square()와 같은 텐서플로 연산에 `v`를 사용하고 재할당합니다. \n", "v.assign(tf.square(v))\n", "assert v.numpy() == 9.0" ] @@ -193,9 +186,9 @@ "id": "-paSaeq1JzwC" }, "source": [ - "변수를 사용한 연산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 초기로부터 드물게 업데이트됩니다. 이는 연산과 메모리에 더욱 효율적입니다. \n", + "변수를 사용한 연산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 기본적으로 희소 텐서(sparse tensor)를 사용하여 업데이트됩니다. 이는 연산과 메모리에 더욱 효율적입니다. \n", "\n", - "또한 변수를 사용하는 것은 코드를 읽는 독자가 이 상태가 변경 가능하다는 것을 빠르게 인식하는 방법입니다." + "또한 변수를 사용하는 것은 코드를 읽는 독자에게 상태가 변경될 수 있다는 것을 알려주는 손쉬운 방법입니다." ] }, { @@ -205,16 +198,16 @@ "id": "BMiFcDzE7Qu3" }, "source": [ - "## 예: 선형모델 피팅\n", + "## 예: 선형 모델 훈련\n", "\n", - "몇가지 개념을 설명해보겠습니다. 우리는 지금까지 간단한 모델을 구축하고 학습시키기 위해 ---`Tensor`, `GradientTape`, `Variable` --- 등을 사용하였습니다. 이것은 일반적으로 다음의 과정을 포함합니다.\n", + "지금까지 몇 가지 개념을 설명했습니다. 간단한 모델을 구축하고 학습시키기 위해 ---`Tensor`, `GradientTape`, `Variable` --- 등을 사용하였고, 이는 일반적으로 다음의 과정을 포함합니다.\n", "\n", "1. 모델 정의\n", - "2. 손실함수 정의\n", + "2. 손실 함수 정의\n", "3. 훈련 데이터 가져오기\n", - "4. 훈련 데이터를 통한 실행, 데이터에 최적화하기 위한 \"옵티마이저(optimizer)\" 사용한 변수 조정\n", + "4. 훈련 데이터에서 실행, 데이터에 최적화하기 위해 \"옵티마이저(optimizer)\"를 사용한 변수 조정\n", "\n", - "이번 튜토리얼에서는 선형모델의 간단한 예제를 살펴보겠습니다. `f(x) = x * W + b`, 위 모델은 `W` 와 `b` 두 변수를 가지고 있는 선형모델이며, 잘 학습된 모델이 `W = 3.0` and `b = 2.0`의 값을 갖도록 데이터를 합성할 것입니다." + "이번 튜토리얼에서는 선형 모델의 간단한 예제를 살펴보겠습니다. `f(x) = x * W + b`, 모델은 `W` 와 `b` 두 변수를 가지고 있는 선형모델이며, 잘 학습된 모델이 `W = 3.0` and `b = 2.0`의 값을 갖도록 합성 데이터를 만들겠습니다." ] }, { @@ -226,12 +219,12 @@ "source": [ "### 모델 정의\n", "\n", - "변수와 연산을 요약하기 위한 간단한 클래스를 정의해봅시다." + "변수와 연산을 캡슐화하기 위한 간단한 클래스를 정의해봅시다." ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", @@ -263,12 +256,12 @@ "source": [ "### 손실 함수 정의\n", "\n", - "손실 함수는 주어진 입력에 대한 모델의 출력이 원하는 출력과 얼마나 잘 일치하는지를 측정합니다. L2 규제항(regularization)을 적용한 손실 함수를 사용하겠습니다." + "손실 함수는 주어진 입력에 대한 모델의 출력이 원하는 출력과 얼마나 잘 일치하는지를 측정합니다. 평균 제곱 오차(mean square error)를 적용한 손실 함수를 사용하겠습니다." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", @@ -287,14 +280,14 @@ "id": "qutT_fkl_CBc" }, "source": [ - "### 훈련 데이터 얻기\n", + "### 훈련 데이터 가져오기\n", "\n", "약간의 잡음과 훈련 데이터를 합칩니다." ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", @@ -323,31 +316,13 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "_eb83LtrB4nt" }, - "outputs": [ - { - "data": { - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Current loss: \n", - "9.401943\n" - ] - } - ], + "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "\n", @@ -368,7 +343,7 @@ "source": [ "### 훈련 루프 정의\n", "\n", - "현재 우리는 네트워크와 훈련 데이터를 가지고 있습니다. 모델의 변수(`W` 와 `b`)를 업데이트하기 위해 훈련 데이터를 사용하여 훈련시킵니다. 그리고 [경사 하강(gradient descent)](https://en.wikipedia.org/wiki/Gradient_descent)을 사용하여 손실을 감소시킵니다. 경사 하강에는 여러가지 방법이 있으며, `tf.train.Optimizer` 에 구현되어있습니다. 이러한 구현을 사용하는것을 강력히 추천드립니다. 그러나 이번 튜토리얼에서는 기본적인 방법을 사용하겠습니다." + "이제 네트워크와 훈련 데이터가 준비되었습니다. 모델의 변수(`W` 와 `b`)를 업데이트하기 위해 훈련 데이터를 사용하여 훈련시켜 보죠. 그리고 [경사 하강법(gradient descent)](https://en.wikipedia.org/wiki/Gradient_descent)을 사용하여 손실을 감소시킵니다. 경사 하강법에는 여러가지 방법이 있으며, `tf.train.Optimizer` 에 구현되어있습니다. 이러한 구현을 사용하는것을 강력히 추천드립니다. 그러나 이번 튜토리얼에서는 기본적인 방법을 사용하겠습니다." ] }, { @@ -396,7 +371,7 @@ "id": "RwWPaJryD2aN" }, "source": [ - "마지막으로, 훈련 데이터를 반복적으로 실행하고, `W` 와 `b`의 변화과정을 확인합니다." + "마지막으로, 훈련 데이터를 반복적으로 실행하고, `W` 와 `b`의 변화 과정을 확인합니다." ] }, { @@ -442,9 +417,9 @@ "source": [ "## 다음 단계\n", "\n", - "이번 튜토리얼에서는 변수를 다루었으며, 지금까지 논의된 초기 타입의 텐서플로를 사용하여 간단한 선형모델을 구축하고 훈련시켰습니다.\n", + "이번 튜토리얼에서는 변수를 다루었으며, 지금까지 논의된 텐서플로의 기본 요소를 사용하여 간단한 선형 모델을 구축하고 훈련시켰습니다.\n", "\n", - "이론적으로, 이것은 텐서플로를 머신러닝 연구에 사용하는데 필요한 대부분입니다. 실제로 신경망에 있어 `tf.keras`와 같은 고수준 API는 고수준 빌딩 블록(\"층\"으로 불리는)을 제공하고, 저장 및 복원을 위한 유틸리티, 손실 함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " + "이론적으로, 텐서플로를 머신러닝 연구에 사용하기 위해 알아야 할 것이 매우 많습니다. 실제로 신경망에 있어 `tf.keras`와 같은 고수준 API는 고수준 구성 요소(\"층\"으로 불리는)를 제공하고, 저장 및 복원을 위한 유틸리티, 손실 함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " ] }, { diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index 46b3469ab9a..159af60744c 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -94,17 +94,17 @@ "\n", "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로의 개념을 사용합니다.\n", "\n", - "* [즉시 실행(eager execution)](https://www.tensorflow.org/guide/eager) 개발환경,\n", - "* [데이터셋 API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 불러오기,\n", - "* [케라스 API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 layer 구축 .\n", + "* [즉시 실행(eager execution)](https://www.tensorflow.org/guide/eager) 개발 환경,\n", + "* [데이터셋 API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 가져오기,\n", + "* [케라스 API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 층(layer) 구축 .\n", "\n", "이번 튜토리얼은 다른 텐서플로 프로그램과 유사하게 구성되어있습니다.\n", "\n", - "1. 데이터 불러오기 및 분석.\n", + "1. 데이터 가져오기 및 분석.\n", "2. 모델 타입 선정.\n", - "3. 모델 학습.\n", + "3. 모델 훈련.\n", "4. 모델 효과 검증.\n", - "5. 예측을 위한 학습된 모델 사용." + "5. 예측을 위한 훈련된 모델 사용." ] }, { @@ -126,31 +126,22 @@ "source": [ "### 임포트 및 즉시 실행 구성\n", "\n", - "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화할 것입니다. 즉시 실행은 텐서플로가 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게 합니다. 만약 파이썬 대화형 창이나 인터렉티브 콘솔을 사용하시면, 더욱 익숙할 겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용 가능합니다.\n", + "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화합니다. 즉시 실행은 텐서플로가 연산이 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게 합니다. 만약 파이썬 대화형 창이나 상호작용 콘솔을 사용하시면 더욱 익숙할 겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용 가능합니다.\n", "\n", - "즉시 실행이 활성화될 때, 동일한 프로그램내에서 비활성화 할 수 없습니다. 더 많은 세부사항은 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)을 참조하세요." + "즉시 실행이 활성화될 때, 동일한 프로그램내에서 비활성화 할 수 없습니다. 더 많은 세부사항은 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 참조하세요." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "g4Wzg69bnwK2" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "텐서플로 버전: 1.10.0\n", - "즉시실행: True\n" - ] - } - ], + "outputs": [], "source": [ - "from __future__ import absolute_import, division, print_function\n", + "from __future__ import absolute_import, division, print_function, unicode_literals\n", "\n", "import os\n", "import matplotlib.pyplot as plt\n", @@ -172,9 +163,9 @@ "source": [ "## 붓꽃 분류 문제\n", "\n", - "당신이 식물학자라고 상상하고, 주어진 붓꽃을 자동적으로 분류하는 방법을 찾고있다고 가정합시다. 머신러닝은 통계적으로 꽃을 분류할 수 있는 다양한 알고리즘을 제공합니다. 예를 들어, 정교한 머신러닝 프로그램은 사진을 통해 꽃을 분류할 수 있습니다. 이번 튜토리얼의 목적은 좀 더 겸손하게, 측정된 [꽃받침](https://en.wikipedia.org/wiki/Sepal)과 [꽃잎](https://en.wikipedia.org/wiki/Petal)의 길이와 폭을 토대로 붓꽃을 분류하는것입니다.\n", + "당신이 식물학자라고 상상하고, 주어진 붓꽃을 자동적으로 분류하는 방법을 찾고 있다고 가정합시다. 머신러닝은 통계적으로 꽃을 분류할 수 있는 다양한 알고리즘을 제공합니다. 예를 들어, 정교한 머신러닝 프로그램은 사진을 통해 꽃을 분류할 수 있습니다. 이번 튜토리얼의 목적은 좀 더 겸손하게, 측정된 [꽃받침](https://en.wikipedia.org/wiki/Sepal)과 [꽃잎](https://en.wikipedia.org/wiki/Petal)의 길이와 폭을 토대로 붓꽃을 분류하는 것입니다.\n", "\n", - "이 붓꽃은 약 300종 입니다. 하지만 이번 튜토리얼에서는 오직 3가지 품종을 기준으로 분류할 것입니다. \n", + "이 붓꽃은 약 300종입니다. 하지만 이번 튜토리얼에서는 오직 3가지 품종을 기준으로 분류할 것입니다. \n", "\n", "* Iris setosa\n", "* Iris virginica\n", @@ -200,7 +191,7 @@ "id": "3Px6KAg0Jowz" }, "source": [ - "## 훈련 데이터 불러오기 및 분석\n", + "## 훈련 데이터 가져오기 및 분석\n", "\n", "데이터를 불러오고 파이썬 프로그램이 사용할 수 있는 구조로 전환합니다.\n", "\n", @@ -211,23 +202,13 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "J6c7uEU9rjRM" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv\n", - "8192/2194 [================================================================================================================] - 0s 0us/step\n", - "Local copy of the dataset file: C:\\Users\\82108\\.keras\\datasets\\iris_training.csv\n" - ] - } - ], + "outputs": [], "source": [ "train_dataset_url = \"https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv\"\n", "\n", @@ -272,7 +253,7 @@ "처음 5개의 데이터로부터 다음을 주목하세요.\n", "\n", "1. 첫 번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", - " * 총 120개의 예가 있으며, 각 예들은 4가지의 특성(feature), 3가지 가능한 레이블(label)을 가지고 있습니다.\n", + " * 총 120개의 예가 있으며, 각 예들은 4개의 특성(feature), 3개의 레이블(label)을 가지고 있습니다.\n", "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[예](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 예제의 특징을 나타냅니다. 이 필드들는 붓꽃의 측정값을 부동소수점으로 나타냅니다.\n", " * 마지막 컬럼(column)은 *[레이블(label)](https://developers.google.com/machine-learning/glossary/#label)*입니다.: 레이블은 예측하고자 하는 값을 나타냅니다. 이 데이터셋에서는 꽃의 이름과 관련된 정수값 0, 1, 2를 나타냅니다.\n", @@ -282,22 +263,13 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "9Edhevw7exl6" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "특성: ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']\n", - "레이블: species\n" - ] - } - ], + "outputs": [], "source": [ "# CSV 파일안에서 컬럼의 순서\n", "column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']\n", @@ -327,7 +299,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", @@ -347,15 +319,15 @@ "source": [ "### `tf.data.Dataset` 생성\n", "\n", - "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위한 많은 케이스를 다룹니다. 이는 훈련을 위한 형식으로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 [데이터셋 빠른 실행 가이드](https://www.tensorflow.org/get_started/datasets_quickstart)를 참조하세요. \n", + "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위해 많은 케이스를 다룹니다. 이는 훈련을 위해 형식으로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 [데이터셋 빠른 실행 가이드](https://www.tensorflow.org/get_started/datasets_quickstart)를 참조하세요. \n", "\n", "\n", - "데이터셋이 CSV 형태의 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 [배치 사이즈(batch_size)](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." + "데이터셋이 CSV 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련 모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 [배치 사이즈(batch_size)](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", @@ -386,43 +358,13 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "iDuG94H-C122" }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([('sepal_length',\n", - " ),\n", - " ('sepal_width',\n", - " ),\n", - " ('petal_length',\n", - " ),\n", - " ('petal_width',\n", - " )])" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "features, labels = next(iter(train_dataset))\n", "\n", @@ -436,33 +378,20 @@ "id": "E63mArnQaAGz" }, "source": [ - "유사한 특성의 값은 같이 그룹되어있거나, *배치* 되있다는 사실에 주목하세요. 각 예제행의 필드는 해당 특성 배열에 추가됩니다. `batch_size`를 조절하여 이 특성 배열에 저장된 예제의 수를 설정하세요.\n", + "유사한 특성의 값은 같이 그룹 되어있거나, *배치* 돼있다는 사실에 주목하세요. 각 예제행의 필드는 해당 특성 배열에 추가됩니다. `batch_size`를 조절하여 이 특성 배열에 저장된 예제의 수를 설정하세요.\n", "\n", - "또한 배치(batch)로부터 약간의 특성을 도식화하여 군집되있는 데이터를 확인할 수 있습니다. " + "또한 배치(batch)로부터 약간의 특성을 도식화하여 군집돼있는 데이터를 확인할 수 있습니다. " ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "me5Wn-9FcyyO" }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "plt.scatter(features['petal_length'].numpy(),\n", " features['sepal_length'].numpy(),\n", @@ -480,14 +409,14 @@ "id": "YlxpSyHlhT6M" }, "source": [ - "모델 구축단계를 단순화하기 위해서, 특성(사전형 객체)을 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", + "모델 구축 단계를 단순화하기 위해, 특성(사전형 객체)을 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", "\n", - "이 함수는 텐서의 list로부터 값을 취하고 특정한 차원으로 결합된 텐서를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메서드(method)를 사용합니다." + "이 함수는 텐서의 리스트(list)로부터 값을 취하고 특정한 차원으로 결합된 텐서를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메서드(method)를 사용합니다." ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", @@ -531,31 +460,18 @@ "id": "NLy0Q1xCldVO" }, "source": [ - "데이터셋의 특성 요소는 이제 형태가 `(batch_size, num_features)`인 배열입니다. 첫 5행의 예제를 살펴봅시다." + "데이터셋의 특성 요소는 이제 형태가 `(batch_size, num_features)`인 배열입니다. 첫 5개행의 예제를 살펴봅시다." ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "kex9ibEek6Tr" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "tf.Tensor(\n", - "[[4.9 3. 1.4 0.2]\n", - " [6.6 2.9 4.6 1.3]\n", - " [6.8 3.2 5.9 2.3]\n", - " [5. 3.5 1.3 0.3]\n", - " [7.7 2.8 6.7 2. ]], shape=(5, 4), dtype=float32)\n" - ] - } - ], + "outputs": [], "source": [ "features, labels = next(iter(train_dataset))\n", "\n", @@ -573,9 +489,9 @@ "\n", "### 왜 모델을 사용해야하는가?\n", "\n", - " *[모델](https://developers.google.com/machine-learning/crash-course/glossary#model)*은 특성(feature)과 레이블(label)과의 관계입니다. 붓꽃 분류 문제에서 모델은 측정된 꽃받침과 꽃잎 사이의 관계를 정의하고 붓꽃의 품종을 예측합니다. 몇가지 간단한 모델은 몇 줄의 대수학으로 표현할 수 있으나, 복잡한 머신러닝 모델은 요약하기 힘든 굉장히 많은 수의 매개변수를 가지고 있습니다.\n", + " *[모델](https://developers.google.com/machine-learning/crash-course/glossary#model)*은 특성(feature)과 레이블(label) 과의 관계입니다. 붓꽃 분류 문제에서 모델은 측정된 꽃받침과 꽃잎 사이의 관계를 정의하고 붓꽃의 품종을 예측합니다. 몇 가지 간단한 모델은 몇 줄의 대수학으로 표현할 수 있으나, 복잡한 머신러닝 모델은 요약하기 힘든 굉장히 많은 수의 매개변수를 가지고 있습니다.\n", "\n", - "머신러닝을 사용하지 않고 4가지의 특성 사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 사용자를 위한 모델을 결정합니다. 만약 충분한 예제를 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 사용자를 위한 특성간의 관계를 이해하고 제공합니다. \n", + "머신러닝을 사용하지 않고 4가지의 특성 사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을 정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 사용자를 위한 모델을 결정합니다. 만약 충분한 예제를 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 사용자를 위한 특성 간의 관계를 이해하고 제공합니다. \n", "\n", "### 모델 선정\n", "\n", @@ -603,14 +519,14 @@ "source": [ "### 케라스를 사용한 모델 생성\n", "\n", - "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 layer를 생성하기위한 풍부한 라이브러리를 제공합니다. 이는 연결되있는 모든것을 케라스가 처리하여 모델을 구축하기 쉽게 만듭니다.\n", + "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 층을 생성하기 위한 풍부한 라이브러리를 제공합니다. 이는 파이프라인의 모든 것을 케라스가 처리하여 모델을 구축하기 쉽게 만듭니다.\n", "\n", - "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 여러 층을 연이어 쌓은 모델입니다. 이 구조는 층의 인스턴스를 취하며, 아래의 케이스의 경우 각 층당 10개의 노드(node)를 가지는 2개의 [Dense(완전 연결 층)](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)와 3개의 예측(레이블의 수)노드를 가지는 출력 층으로 구성되어있습니다. 첫번째 층의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." + "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 여러 층을 연이어 쌓은 모델입니다. 이 구조는 층의 인스턴스를 취하며, 아래의 케이스의 경우 각 층당 10개의 노드(node)를 가지는 2개의 [Dense(완전 연결 층)](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)와 3개의 예측(레이블의 수) 노드를 가지는 출력 층으로 구성되어있습니다. 첫 번째 층의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", @@ -632,9 +548,9 @@ "id": "FHcbEzMpxbHL" }, "source": [ - "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 층의 출력의 크기를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 하나의 층과 동일하다고 생각할 수 있습니다. 사용 가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", + "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 층에서 출력의 크기를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 하나의 층과 동일하다고 생각할 수 있습니다. 사용 가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", "\n", - "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 좌우됩니다. 머신러닝의 여러 측면과 마찬가지로, 최적의 신경망 타입을 결정하는 것은 많은 경험과 지식이 필요합니다. 경험을 토대로, 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." + "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 의해 좌우됩니다. 머신러닝의 여러 측면과 마찬가지로, 최적의 신경망 타입을 결정하는 것은 많은 경험과 지식이 필요합니다. 경험을 토대로 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." ] }, { @@ -646,34 +562,18 @@ "source": [ "### 모델 사용\n", "\n", - "이 모델이 배치 특성에 대해 수행하는 작업을 간단히 살펴보겠습니다. " + "이 모델이 특성의 배치에 대해 수행하는 작업을 간단히 살펴봅시다. " ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "xe6SQ5NrpB-I" }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "predictions = model(features)\n", "predictions[:5]" @@ -693,29 +593,13 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "_tRwHZmTNTX2" }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "tf.nn.softmax(predictions[:5])" ] @@ -732,22 +616,13 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "-Jzm_GoErz8B" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "예측: [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]\n", - " 레이블: [0 1 2 0 2 1 0 0 2 1 1 2 2 2 0 2 0 2 0 2 0 0 1 0 0 1 2 2 2 1 0 2]\n" - ] - } - ], + "outputs": [], "source": [ "print(\"예측: {}\".format(tf.argmax(predictions, axis=1)))\n", "print(\" 레이블: {}\".format(labels))" @@ -764,7 +639,7 @@ "\n", "*[훈련 단계](https://developers.google.com/machine-learning/crash-course/glossary#training)*는 모델이 점진적으로 최적화되거나 데이터셋을 학습하는 머신러닝의 과정입니다. 훈련의 목적은 미지의 데이터를 예측하기 위해, 훈련 데이터셋의 구조에 대해서 충분히 학습하는 것입니다. 만약 모델이 훈련 데이터셋에 대해서 과하게 학습된다면 오직 훈련 데이터셋에 대해서 작동할 것이며, 일반화되기 힘들 것입니다. 이러한 문제를 *[과대적합(overfitting)](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)* 이라고 합니다. 이는 마치 문제를 이해하고 해결한다기보다는 답을 기억하는 것이라고 생각할 수 있습니다. \n", "\n", - "붓꽃 분류 문제는 *[지도 학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시 중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도 학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고 있지 않습니다. 대신에 모델은 특성간의 패턴을 찾습니다. " + "붓꽃 분류 문제는 *[지도 학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시 중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도 학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고 있지 않습니다. 대신에 모델은 특성 간의 패턴을 찾습니다. " ] }, { @@ -776,28 +651,20 @@ "source": [ "### 손실 함수와 그래디언트 함수 정의하기\n", "\n", - "훈련과 평가단계는 모델의 *[손실(loss)](https://developers.google.com/machine-learning/crash-course/glossary#loss)* 계산할 필요가 있습니다. 손실은 모델의 예측이 원하는 레이블과 얼마나 일치하는지, 또한 모델이 잘 작동하는지에 대한 척도로 사용됩니다. 이 값은 최소화하고, 최적화하기를 원합니다. \n", + "훈련과 평가단계에서 모델의 *[손실(loss)](https://developers.google.com/machine-learning/crash-course/glossary#loss)*을 계산해야 합니다. 손실은 모델의 예측이 원하는 레이블과 얼마나 일치하는지, 또한 모델이 잘 작동하는지에 대한 척도로 사용됩니다. 이 값을 최소화하고, 최적화 해야합니다.\n", "\n", - "모델의 손실은 [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) 함수를 사용하여 계산할 것입니다. 이 함수는 모델의 클래스(레이블)과 예측된 값(로짓)을 입력받아 예제를 통한 평균 손실을 반환합니다." + "모델의 손실은 [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) 함수를 사용해 계산할 것입니다. 이 함수는 모델의 클래스(레이블)과 예측된 값(로짓)을 입력받아 예제를 통한 평균 손실을 반환합니다." ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "tMAT4DcMPwI-" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "손실 테스트: 1.5565308332443237\n" - ] - } - ], + "outputs": [], "source": [ "def loss(model, x, y):\n", " y_ = model(x)\n", @@ -820,7 +687,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", @@ -843,7 +710,7 @@ "source": [ "### 옵티마이저 생성 \n", "\n", - "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 `손실` 함수를 최소화하기 위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실 함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 이 함수의 최저점을 찾고자 합니다. 그래디언트는 가장 가파른 상승 방향을 가리키며 따라서 반대 방향으로 이동하는 여행을 합니다. 각 배치마다의 손실과 기울기를 반복적으로 계산하여 훈련 중에 모델을 조정합니다. 점진적으로, 모델은 손실을 최소화하기 위해 가중치(weight)와 편향(bias)의 최적의 조합을 찾아냅니다. 더 적은 손실을 통해 더 좋은 모델의 예측을 기대할 수 있습니다. \n", + "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 손실 함수를 최소화하기 위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실 함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 이 함수의 최저점을 찾고자 합니다. 그래디언트는 가장 가파른 상승 방향을 가리키며 따라서 반대 방향으로 이동하는 여행을 합니다. 각 배치마다의 손실과 기울기를 반복적으로 계산하여 훈련과정 동안 모델을 조정합니다. 점진적으로, 모델은 손실을 최소화하기 위해 가중치(weight)와 편향(bias)의 최적의 조합을 찾아냅니다. 손실이 낮을수록 더 좋은 모델의 예측을 기대할 수 있습니다.\n", "\n", "\n", " \n", " \n", "
\n", @@ -851,11 +718,11 @@ " alt=\"Optimization algorithms visualized over time in 3D space.\">\n", "
\n", - " 그림 3. Optimization algorithms visualized over time in 3D space.
(Source: Stanford class CS231n, MIT License, Image credit: Alec Radford)\n", + " 그림 3. 3차원 공간에 대한 최적화 알고리즘 시각화.
(Source: Stanford class CS231n, MIT License, Image credit: Alec Radford)\n", "
\n", "\n", - "텐서플로는 학습을 위해 이용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 경사 하강(stochastic gradient descent, SGD)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현하는 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. 매개변수 `learning_rate`은 경사하강 과정의 크기를 나타내는 척도이며, 더 나은 결과를 위해 공동적으로 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " + "텐서플로는 훈련을 위해 사용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 경사 하강법(stochastic gradient descent, SGD)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현하는 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. `learning_rate`은 경사하강 과정의 크기를 나타내는 매개변수이며, 더 나은 결과를 위해 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " ] }, { @@ -870,7 +737,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", @@ -895,22 +762,13 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "rxRNTFVe56RG" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "단계: 0, 초기 손실: 1.5565308332443237\n", - "단계: 1, 손실: 1.4113397598266602\n" - ] - } - ], + "outputs": [], "source": [ "loss_value, grads = grad(model, features, labels)\n", "\n", @@ -932,39 +790,27 @@ "source": [ "### 훈련 루프\n", "\n", - "모든 조각을 가지고, 모델은 학습할 준비가 되었습니다! 훈련 루프는 더 좋은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 아래의 훈련 단계를 작성한 것입니다. \n", + "모든 조각을 가지고 모델을 훈련할 준비가 되었습니다! 훈련 루프는 더 좋은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 아래의 훈련 단계를 작성한 것입니다. \n", "\n", "1. 각 *에포크(epoch)* 반복. 에포크는 데이터셋을 통과시키는 횟수입니다. \n", "2. 에포크 내에서, `데이터셋`의 *특성* (`x`)와 *레이블* (`y`)를 가져오는 예제를 반복합니다.\n", - "3. 예제의 특성을 사용하여 결과를 예측을 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기 위해 사용합니다. \n", + "3. 예제의 특성을 사용하여 결과를 예측 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기 위해 사용합니다. \n", "4. 모델의 변수를 업데이트하기 위해 `옵티마이저`를 사용합니다. \n", - "5. 시각화를 위해 몇가지 값을 추적합니다.\n", + "5. 시각화를 위해 몇가지 값들을 저장합니다.\n", "6. 각 에포크를 반복합니다.\n", "\n", - "`num_epochs` 변수는 데이터셋 반복 횟수입니다. 반직관적으로, 모델을 길게 학습하는것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는것은 많은 경험과 직관을 필요로 합니다. " + "`num_epochs` 변수는 데이터셋의 반복 횟수입니다. 반직관적으로, 모델을 길게 학습하는것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는것은 많은 경험과 직관을 필요로 합니다. " ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "AIgulGRUhpto" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "에포크 000: 손실: 1.364, 정확도: 35.000%\n", - "에포크 050: 손실: 0.732, 정확도: 70.833%\n", - "에포크 100: 손실: 0.434, 정확도: 95.000%\n", - "에포크 150: 손실: 0.273, 정확도: 98.333%\n", - "에포크 200: 손실: 0.231, 정확도: 99.167%\n" - ] - } - ], + "outputs": [], "source": [ "## Note: 이 셀을 다시 실행하면 동일한 모델의 변수가 사용됩니다.\n", "\n", @@ -1020,33 +866,20 @@ "id": "j3wdbmtLVTyr" }, "source": [ - "모델의 훈련 과정을 출력하는 것은 도움이 되지만, 훈련 과정을 직접 보는 것이 더 도움이 되곤합니다. [TensorBoard](https://www.tensorflow.org/guide/summaries_and_tensorboard)는 텐서플로에 패키지되어있는 굉장히 유용한 시각화 툴입니다. 하지만 `matplotlib` 모듈을 사용하여 일반적인 차트를 출력할 수 있습니다.\n", + "모델의 훈련 과정을 출력하는 것도 도움이 되지만, 훈련 과정을 직접 보는 것이 더 도움이 되곤합니다. [텐서보드(tensorboard)](https://www.tensorflow.org/guide/summaries_and_tensorboard)는 텐서플로에 패키지 되어있는 굉장히 유용한 시각화 툴입니다. 하지만 `matplotlib` 모듈을 사용하여 일반적인 도표를 출력할 수 있습니다.\n", "\n", - "이 차트를 해석하는것은 여러 경험이 필요하지만, 모델을 최적화하기위해 *손실*이 내려가고 *정확도*가 올라가는 것을 보고싶습니다." + "이 도표를 해석하는 것은 여러 경험이 필요하지만, 결국 모델을 최적화하기 위해 *손실*이 내려가고 *정확도*가 올라가는 것을 원합니다." ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "id": "agjvNd2iUGFn" }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAtgAAAIdCAYAAAAH9goCAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzs3Xd8XNWd///X0WjUe++WLbl34wLYGINxsE1NQkKAhMCGOCGBzS9tU78hu2lks8kCIQlLWCAkYEhC6KE3U9zk3mVbtrrVex3NnN8fM3jlLskjjSS/n4+HHnjuPXP1mWswbx997jnGWouIiIiIiPhHUKALEBEREREZTRSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RkkBhjHMaYVmNMjj/HDmfGmHHGmNZA1yEiEkgK2CIiPr6A+9GXxxjT0ev1Tf29nrXWba2NstaW+HNsfxljfmqMscaYrxx3/Fu+4z/s43XKjDFLTjfGWltkrY06i3JFREY8BWwRER9fwI3yBcQS4Kpexx4/frwxJnjoqxywQuDzxx37nO+4X4yw+yEiMmgUsEVE+sg3E/yUMWa1MaYF+Kwx5gJjzDpjTKMxptIYc58xxukbH+ybIc71vf6L7/zLxpgWY8xaY8zY/o71nV9hjCk0xjQZY35rjPnAGHPLacpfCyQYYyb63j8L7/8Dthz3Ga82xmzzfZ73jTHTfMdXAxnAy74Z/W8YY/J9Nd9qjCkBXvvoWK/rJRpjHvXdmwZjzNO+4ynGmH/6vk+9MWbNgH9jRESGGQVsEZH++TjwBBALPAX0AF8DkoCFwHLgS6d5/43A/wMS8M6S/6S/Y40xKcBfgW/7vu8hYH4fav8zcLPv1zcDj/U+aYyZB/wRuA1IBB4GnjPGhFhrbwAqgBW+Gf3f9HrrYmAScMVJvucTQAgwBUgF7vUd/zZQBCQDab7PKSIyKihgi4j0z/vW2hestR5rbYe1dqO1dr21tsdaWwQ8CFx8mvf/3VpbYK11AY8DswYw9kpgq7X2Od+5/wZq+1D7n4GbfDPsn/Zds7dVwO99n8ltrX3Yd3zeGa57l7W23Vrb0fugMSYbWArcbq1tsNZ2W2s/mql24Z0Rz/Edf7cP9YuIjAgK2CIi/VPa+4UxZpIx5iVjzBFjTDPwH3hnlU/lSK9ftwOneyDwVGMzetdhrbVA2ZkKt9YewjsT/nNgl7W24rghY4Dv+No2Go0xjUA6kHmGS5ee4ng2UGutbTrJubuBYuBNY8xBY8y3z1S/iMhIoYAtItI/9rjX/wPsBPKttTHAjwAzyDVUAlkfvTDGGM4cgj/yGPBNjmsP8SkF/t1aG9frK8Ja+1ff+eM/u/egN+CfTCmQZIyJOcl7mq21X7fW5gLX4g32p5v5FxEZMRSwRUTOTjTQBLQZYyZz+v5rf3kRmGOMucq3csfX8PYy98UTwMeAp09y7kHgq8aYecYryvc9In3nq4BxfS3SWlsKvAH8zhgTZ4xxGmMWA/ium+f7y0ET4PZ9iYiMeArYIiJn55t4l79rwTub/dRgf0NrbRVwPfAboA7Iw7saSFcf3tturX3DWtt5knPrgduBPwANeJfw+2yvIT8H/t3XPvL/9bHcj95fiDeg3+l7PRF4C2gFPgDutda+38driogMa+bUP9kTEZGRwBjjwLvCx3XW2vcCXY+IyLlOM9giIiOQMWa5MSbWGBOKd4m7HmBDgMsSEREUsEVERqpFeNeRrsW79va11toztoiIiMjgU4uIiIiIiIgfaQZbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPgofqGxljHgauBKqttdNOM24esA643lr79zNdNykpyebm5vqtThERERGRk9m0aVOttTb5TOOGLGADjwL3A4+daoAxxgH8Eni1rxfNzc2loKDgrIsTERERETkdY0xxX8YNWYuItXYNUH+GYXcCTwPVg1+RiIiIiIj/DZsebGNMJvBx4IE+jF1ljCkwxhTU1NQMfnEiIiIiIn00bAI2cA/wHWut+0wDrbUPWmvnWmvnJiefsQ1GRERERGTIDGUP9pnMBZ40xgAkASuNMT3W2mcDW5aIiIiISN8Nm4BtrR370a+NMY8CLypci4iIiMhIM5TL9K0GlgBJxpgy4C7ACWCtPWPftYiIiIjISDBkAdtae0M/xt4yiKWctYrGDm5+eAPfXDaBFdPTA12OiIiIiAwjw+khxxEjMiSYA9WtlDd2BLoUERERERlmFLAHICY8mOAgQ11bd6BLEREREZFhRgF7AIwxJEaFUNfaFehSRERERGSYUcAeoMTIUOpaNYMtIiIiIsdSwB6gxKgQatUiIiIiIiLHUcAeoKSoULWIiIiIiMgJFLAHKDEyRC0iIiIiInICBewBSooOpcPlpr27J9CliIiIiMgwooA9QImRIQDUtmgWW0RERET+jwL2ACVFhQJQ26Y+bBERERH5PwrYA5QY5Z3BVh+2iIiIiPSmgD1Aib4ZbK0kIiIiIiK9KWAP0Ec92NouXURERER6U8AeoDCng6jQYGo1gy0iIiIivShgn4XEKK2FLSIiIiLHUsA+C0lRodRpFRERERER6UUB+yxoN0cREREROZ4C9llIjApVD7aIiIiIHEMB+ywkRYVQ39aN22MDXYqIiIiIDBMK2GchMTIEj4XGdrWJiIiIiIiXAvZZOLrZjNbCFhEREREfBeyz8NF26erDFhEREZGPDFnANsY8bIypNsbsPMX5m4wx231fHxpjZg5VbQOVfHS7dM1gi4iIiIjXUM5gPwosP835Q8DF1toZwE+AB4eiqLNxtEVEM9giIiIi4hM8VN/IWrvGGJN7mvMf9nq5Dsga7JrOVly4kyCjHmwRERER+T/DtQf7C8DLpzppjFlljCkwxhTU1NQMYVnHCgoyJESGUqsWERERERHxGXYB2xhzCd6A/Z1TjbHWPmitnWutnZucnDx0xZ1EUlSIHnIUERERkaOGrEWkL4wxM4CHgBXW2rpA19MXiVEh6sEWERERkaOGzQy2MSYH+AfwOWttYaDr6avEyFD1YIuIiIjIUUM2g22MWQ0sAZKMMWXAXYATwFr7APAjIBH4vTEGoMdaO3eo6hso7wy2AraIiIiIeA3lKiI3nOH8bcBtQ1SO3yRFhdLa1UOny02Y0xHockREREQkwIZNi8hIleTbzVFtIiIiIiICCthnLTFSm82IiIiIyP9RwD5LiR/NYKsPW0RERERQwD5rSb7t0ms0gy0iIiIiKGCftZSYUKJDg1l3cEQs2y0iIiIig0wB+yyFBju4dnYmL+6opLFdbSIiIiIi5zoFbD+4YX4O3T0entlSHuhSRERERCTAFLD9YEpGDDOz43hifQnW2kCXIyIiIiIBpIDtJzfOz2Z/dSubihsCXYqIiIiIBJACtp9cOSODqNBgnthQEuhSRERERCSAFLD9JDI0mGtnZ/DS9kqa2l2BLkdEREREAkQB249umJ9DV4+HX766F49HvdgiIiIi5yIFbD+amhHLbYvG8sT6Eu58cgudLnegSxIRERGRIRYc6AJGmx9cMZnUmDB+9s891LR08bNrpzEuOQpHkAl0aSIiIiIyBBSw/cwYwxcXjyMlJpRv/W0by/57DeFOB5PTo7lyRgY3LsghzOkIdJkiIiIiMkjMSF+3ee7cubagoCDQZZxUaX07Gw7Vs7Oiic3FDWwrayItJow7l+YzOzuemtYu6lq7mJEVS35KdKDLFREREZHTMMZsstbOPeM4Beyh8+GBWn712j62lDQeczw4yPCVS/L56iV5hAZrdltERERkOOprwFaLyBC6MD+Jf+QlsraojqZ2F8nRoUSHOXng3YPc9+Z+XtlZybc+NpGF+UlEhuq3RkRERGQk0gz2MPHW3ip+8MxOKps6cToM542J59JJKaycnk5WfESgyxMRERE556lFZATq6nFTcLiBNYU1vFtYw94jLQDMzonjY1PSWJifyNSMWK1IIiIiIhIACtijQHFdGy/tqOTFbZXsrmwGIDosmEX5SayYns7SSSlqJREREREZIsMuYBtjHgauBKqttdNOct4A9wIrgXbgFmvt5jNddzQH7N6qWzpZe7CODw/U8da+ampauggNDmL5tDS+ftkEcpMiA12iiIiIyKg2HAP2YqAVeOwUAXslcCfegL0AuNdau+BM1z1XAnZvbo9lU3EDL22v4G+byuju8XDTghxuX5JPakwo3r+riIiIiIg/DbtVRKy1a4wxuacZcg3e8G2BdcaYOGNMurW2ckgKHEEcQYb5YxOYPzaBr16az71v7Ocv60v409piokKDyYoPZ0p6DJ88L4sLxiUSpJ5tERERkSEznBp4M4HSXq/LfMdOCNjGmFXAKoCcnJwhKW64SokO42cfn84XFo3lrb3VlDV0UFrfzpt7q/nHlnJyEiK4aUEOtyzM1RrbIiIiIkNgOAXsk02znrR/xVr7IPAgeFtEBrOokWJcchTjkqOOvu50uXl11xFWbyjhFy/v5amCUn567TQuzEsKYJUiIiIio99wCthlQHav11lARYBqGfHCnA6umZXJNbMyebewhv/37E5u/ON6LpucypjECGLCnKTHhXH1zAzCnJrZFhEREfGX4RSwnwfuMMY8ifchxyb1X/vHxROSee3ri/ntW/t5ZnM5aw/W0tbtBuDXr+3jjkvHc/3cbEKCgwJcqYiIiMjIN5SriKwGlgBJQBVwF+AEsNY+4Fum735gOd5l+m611p5xeZBzcRURf+hxe9h4uIFfv7aPguIGMuPCuXFBDp86L4uUmLBAlyciIiIy7Ay7ZfoGiwL22bHW8m5hDX945yDrD9XjCDJcMjGF5dPSuGRiMolRoYEuUURERGRYGHbL9MnwZIxhycQUlkxMoaimlac2lvLMlnLe2FOFMXBeTjxfvjiPpZNTtL62iIiISB9oBltO4PFYdlc28+aeap7ZUsbhunbOGxPPd5ZPYv7YhECXJyIiIhIQahERv3C5PfytoIx73iikuqWL88cl8KWL81gyIVkz2iIiInJOUcAWv+rodvP4+mIeeu8QR5o7mZQWzZcvzuPKGekEO7T6iIiIiIx+CtgyKLp7PDy3tZz/WVPEgepWMuPC+eJFY7lqZoYeiBQREZFRTQFbBpXHY3lzbzUPvHuQTcUNGAMzMmO5eEIyV8/KID8lOtAlioiIiPiVArYMmZ3lTby1t5p3C2vYUtKAx8J5Y+K5fm42UzNjSIoKJSEyBKdaSURERGQEU8CWgKhp6eKZLWU8ubGUopq2o8eNgY/PzuSuK6cSG+EMYIUiIiIiA6OALQFlrWVneTNlDe3UtXVTWNXC4+tLSIwM4Wcfn86yKamBLlFERESkXxSwZdjZWd7Et/62jb1HWrh2VgZ3XTWV+MiQQJclIiIi0id9DdhqipUhMy0zlufvWMTXlo7nxe2VLPvvNby660igyxIRERHxK81gS0DsqmjiW3/bzp7KZvKSI5mWGcu0jFgumpDEpLSYQJcnIiIicgK1iMiw193j4c/rill7sJZdFc1UNnUCMDk9hk/OyeTjszO1traIiIgMGwrYMuJUt3Tyys4jPL25nG2ljYQ7HXz+wlxWLR5Hgnq1RUREJMAUsGVEK6xq4XdvH+D5bRVEOB0sn5bOlIwYpqTHMDUzhpgwLfUnIiIiQ0sBW0aF/VUt3P/2AT44UEttazfgXVN7UloM83PjmZubwPyxCaTGhAW4UhERERntFLBl1Klu6WR3RTNbSxspONzA5pIG2rvdAGQnhLNgbCKL8pO4MD+RlGgFbhEREfGvvgbs4KEoRsQfUqLDSJkYxpKJKQC43B72VDaz8XADGw/V88aeKv6+qQyAGVmx3HxBLlfOSCfM6Qhk2SIiInKO0Qy2jBoej2VXRTPvHajhmc3l7K9uJTEyhM9dMIZ/WTRWfdsiIiJyVgalRcQYkwxgra3xvZ4OXA/sstauHmCtZ0UBW07GWsuHB+t45INDvLGnmrgIJ19ZksfNF+RqRltEREQGZLAC9tvAn621DxtjkoD9QAWQBfyHtfbXAy14oBSw5Ux2ljfxn6/uY01hDeFOB1nx4WTGhzM9M5avLMknPESBW0RERM5ssLZKnwGs8/36OuCAtXYqcDPwpX5eS2RITMuM5bF/mc+Tq87nM/OzGZsUSXVzF/e/fYCr73+ffUdaAl2iiIiIjCL9fcgxHGj1/foy4HnfrzcD2Wd6szFmOXAv4AAestbefdz5WOAvQI6vtv+y1j7SzxpFTur8cYmcPy7x6Ov39tfw9ae2cfX97/PtyyeydHIqYxIiCAoyAaxSRERERrr+tohsAx4BngZ2AcusteuNMXOBF6y16ad5rwMoBJYBZcBG4AZr7e5eY74PxFprv+Pr994HpFlru091XbWIyNmoaeniG3/dynv7awGIDg1melYsF4xL5ML8JGZmxRLs6O8PekRERGQ0Gqxl+v4dWA38GnjTWrved/xyYMsZ3jsfb0tJka/AJ4FrgN29xlgg2hhjgCigHujpZ40ifZYcHcpj/zKf3ZXN7CxvYntZE5tLGvn164X8+vVC4iKcfGlxHrcu1MORIiIi0jf9XqbPGJMKZADbrLUe37EFQJO1du9p3ncdsNxae5vv9eeABdbaO3qNicbbdjIJiAaut9a+dJJrrQJWAeTk5JxXXFzcr88gcib1bd2sK6rj75vKeGtvNWkxYfzr0vFcMyuDyFAtHy8iInIuGrKdHI0x+UCZtbbzDOM+BVx+XMCeb629s9eY64CFwDeAPOB1YKa1tvlU11WLiAy29UV13P3KXraUNBLmDGLppFRWTE9jUlo0WfERmtkWERE5RwxKi4gx5ufAPmvtn3xtHK8BS4EmY8zyXi0jJ1PGsQ9CZuFd4q+3W4G7rTf1HzDGHMI7m72hP3WK+NOCcYn84/YL2Xi4gRe2VfDyzkpe2lEJgDGQFR/OlxbnccP8HBx6QFJEROSc19+HHIvxtm2sM8asBP4EXAHcBMyw1l5ymvcG433IcSlQjvchxxuttbt6jfkDUGWt/bGvFWUz3hns2lNdVzPYMtR63B52lDdxuK6NkroOPjhQy4bD9czIiuUn10xjZnZcoEsUERGRQTBYG810AvnW2jJjzP2+93/V1yZSYK09bbLwhfJ78C7T97C19mfGmC8DWGsfMMZkAI8C6YDBO5v9l9NdUwFbAs1ay/PbKvjpS3uoaeliXm48V87IYNmUVOpau9lZ4Q3j183JYnxqdKDLFRERkQEarIBdDnzaWvuBMaYQ+J619mljzCRgvbU2duAlD4wCtgwXLZ0u/vThYZ7fVkFhVesJ56NDg/nDZ89j0fikAFQnIiIiZ2uwAvZ9eJfWKwRmA2OstW3GmM8A37bWnjfQggdKAVuGo8KqFtYU1pAWG8b0zFgcQYYvPFrAwZpWfv6J6Xx67hn3ZRIREZFhZrACdjDwNbw7LT5qrd3iO/51oMVa+9AA6x0wBWwZKZo7XXz18c28t7+WebnxfGxKGsumpJKbFBno0kRERKQPhmyZvkBTwJaRxOX28OCaIl7cXsmeSu/qk6kxoUzPjGV6ZhyLxicyOzte27WLiIgMQ4MWsH2re3wVmIJ358XdwO+stdUDKfRsKWDLSFVa386be6rYWtrIjvImimrbsNYbuFdMS+fiicnMHRNPdJgz0KWKiIgIg9cishB4BagC1voOXwCk4N1EZu2p3jtYFLBltGjudPH23mr+uaOSd/bV0NXjIcjAtMxYlkxI5upZGeSnaBUSERGRQBmsgL0W2AF8udc26UHAA8A0a+2FA6x3wBSwZTTq6HazuaSB9UV1rC2qo6C4AWthUlo0V83M4KoZGeQkRgS6TBERkXPKYAXsDmCWtXbfcccnAVusteH9rvQsKWDLuaC6uZN/7qjkhe2VbCpuAGBWdhzXnZfFdedlabt2ERGRITBYAfsIcIu19pXjjq/Au3FMer8rPUsK2HKuKWto56XtlTy7tYI9lc0kRIZw8wVjuHF+DikxYYEuT0REZNQarIB9D/Ap4N+AD/E+5LgIuBv4q7X2GwMrd+AUsOVcZa1lw6F6/mdNEW/t9T5jnJ8SxQXjEpmbG8/UjBjGJkXh0IokIiIiftHXgB3cz+v+G94tzB/2vdcA3cAfgO/2t0gRGThjDAvGJbJgXCIHqlt4Y081aw/W8fTmMv68rhiAMGcQk9JimJIRw9SMGBaMTSQ/JSrAlYuIiIxuA1oH2xgTAeThDdgHrLXt/i6srzSDLXIsl9vDgepWdlc0s6uimd2VTeyuaKa5sweAK2ek8/VlE8hLVtAWERHpD7+1iBhjnu/rN7XWXt3Xsf6igC1yZtZayho6eHJjCY98cJhOl5vLJqcyJSOG/JQoxqdEk5sUQWiwHpYUERE5FX+2iNT5oR4RCSBjDNkJEXz78kncunAsD7xzkFd3H+H1PVV89HdsR5AhJyGCqRkxXD0zgyUTUwgJDgps4SIiIiOQtkoXOYd1dLspqm3lQLX3a39VKxsP11PX1k1CZAiXT01jWmYME1KjmZAaTWy4dpUUEZFz12A95Cgio0h4iIOpGbFMzYg9eszl9vDe/hqe3lzOC9sqWL2hBABjYHJaDBfkJXLBuETmj0sgRtu4i4iInEAz2CJyStZaKpo6KTzSwo7yJtYerGNTSQPdvm3cp2fGsmh8ErdcOJbk6NBAlysiIjKoBmUd7OFIAVtkaHW63GwpaWRtUR1rD9ayuaSRsOAgvnJJPl9YNFa7SoqIyKilgC0iQ6KoppW7X97La7urSI8N47Pnj+FT52VpV0kRERl1FLBFZEitK6rj3jf2s7aoDkeQ4ZKJKVw7O4NLJ6UQEaLHPUREZOTTQ44iMqTOH5fI+asSOVTbxlMbS3l6cxlv7Kki3Olg8YQkYsKcuNweLHDVjAyWTk7BGG3jLiIio49msEVkULg9lg2H6nlpRwXvFtbgdlucwUG0dfVQ29rNzOw4vrFsAovHJyloi4jIiDAsZ7CNMcuBewEH8JC19u6TjFkC3AM4gVpr7cVDWaOI+IcjyHiX9MtLPOa4y+3hH5vLuO/NA3z+4Q2kx4Zx6aQUlk5O4aLxyTgd2txGRERGtiGbwTbGOIBCYBlQBmwEbrDW7u41Jg74EFhurS0xxqRYa6tPd13NYIuMTF09bl7YVsnru4/w3v5a2rvdZCeEc+cl4/n4nEwFbRERGXaG3UOOxpgLgB9bay/3vf4egLX2F73GfAXIsNb+sK/XVcAWGfm6ety8s6+G+986wI7yJnISIpiTE0d4SDBRoQ6WTUlj/tiEQJcpIiLnuOHYIpIJlPZ6XQYsOG7MBMBpjHkHiAbutdY+NjTliUighAY7uHxqGh+bksqbe6p58L0iNpU00NHtprmzhz++d4grpqfz3RWTyE6ICHS5IiIipzWUAftkTzEdP30eDJwHLAXCgbXGmHXW2sJjLmTMKmAVQE5OziCUKiKBYIzhsimpXDYl9eixjm43D64p4oF3D/L6niqumJ7OkonJXDQ+mYTIkABWKyIicnJDGbDLgOxer7OAipOMqbXWtgFtxpg1wEy8vdtHWWsfBB4Eb4vIoFUsIgEXHuLga5eN59Pzsrjvzf28uquKZ7aUYwxMSY9hXm4C88cmsDAvidgIZ6DLFRERGdIe7GC8QXkpUI73IccbrbW7eo2ZDNwPXA6EABuAz1hrd57quurBFjm3uD2WHeVNvLOvmvVF9WwpbaDT5SE0OIirZmbwufPHMDM7LtBliojIKDTserCttT3GmDuAV/Eu0/ewtXaXMebLvvMPWGv3GGNeAbYDHrxL+Z0yXIvIuccRZJiVHccsX4h2uT1sL2vk6c3lPLulnL9vKmN6ZiyfPT+Hq2ZmaBdJEREZctpoRkRGjZZOF89sKecv64oprGolOiyYxROSyU2MYExCJFMyYpiaEaONbUREZECG3TJ9g0UBW0SOZ61l4+EGnlhfzOaSRsobO3B7vH/WpcaEcumkVC6fmsqi/CSCtd62iIj00bBrERERGSrGGOaPTTi6dnaP20NFYycbDtfz1t4qXthWweoNJSRHh3LtrAw+NjWNvOQo4iOcmt0WEZGzphlsETnndPW4eXtvDU9vLuPtvdX0+Ga3Y8KCmZ0Tz3dXTGJyekyAqxQRkeFGLSIiIn1Q39bNlpIGDte1c7i2jRe3V9DU4eLmC3L5+mUTtPSfiIgcpYAtIjIAje3d/Ob1Qv6yrpgwp4OF+UnejW3yk8mKDycoSC0kIiLnKgVsEZGzsKuiiSfWl/DOvhrKGzsAiAhxkJ8SxYTUaGZmxTIzO45JaTGEBOtBSRGRc4ECtoiIH1hrOVjTyoZDDeyvbmF/VSt7Kpupa+sGvKH7qhkZfGZ+NrOy4/SQpIjIKKZVRERE/MAYQ35KNPkp0UePWWspb+xga2kj7+6r4fltFTxVUMrE1GhWTk/n8mmpTEyNVtgWETlHaQZbROQstXS6eH5bBc9sLmdTSQPWQm5iBNfMyuSTc7LISYwIdIkiIuIHahEREQmA6pZO3thdzUs7KvjwYB3Wwtwx8VyQl8icnHhmZccRHxkS6DJFRGQAFLBFRAKsorGDZ7eW888dleypbMHtsRgDSyYk89nzx7BkYgoOrUoiIjJiKGCLiAwj7d11wIUYAAAgAElEQVQ9bC9r4v39tTxVUEpNSxeZceEsnpDEeWMSmJcbz5jEyECXKSIip6GALSIyTLncHl7fXcXfN5Wx8XA9LZ09AMwfm8DtF+exZGKyHpAUERmGFLBFREYAj8dyoKaVd/fV8MgHh6ho6mRSWjSzc+JJjg4lKSqEEEcQQcZgDCRFhZIeF0ZGXDgxYdplUkRkKGmZPhGRESAoyDAhNZoJqdF8/sJcnt9WwV/WFfP67iPUtXVzujmQi8Yn8d0Vk5iaETt0BYuIyBlpBltEZJhyeywN7d243B481jvbXdPaRUVjB/urWvnT2sM0dbj4+KxMbrtoHJPTtfa2iMhgUouIiMgo19Th4vfvHOCRDw7T3eMhPTaMJRNTuGh8EnNz40mJDgt0iSIio4oCtojIOaKmpYu391bz1t5q3ttfQ1u3G/BudpOXHEVsuJOYcCcLxiawfFqaZrlFRAZIAVtE5BzkcnvYWd7ExsP1bDjUQEVjB00dLhrbu2nrdjMnJ44fXjmFOTnxgS5VRGTEUcAWEZGj3B7L05vK+NVr+6hp6eL8cQnMzolnZlYcYxIjcDoMjqAgUmNCiQjR8+8iIiejVUREROQoR5Dh0/OyuWJGOn98r4g39lTxxzVF9HiOnWSJDXfyrY9N4MYFY7TLpIjIAGkGW0TkHNXpcrO7spmqpk5cHourx8M/tpTxwYE6JqfH8LWl45maEUNGXLjCtogIw7RFxBizHLgXcAAPWWvvPsW4ecA64Hpr7d9Pd00FbBER/7HW8vLOI/z0xd1UNHUCEBocxNikSPKSoxiXHMmktBgW5ScRG6GNbkTk3DLsWkSMMQ7gd8AyoAzYaIx53lq7+yTjfgm8OlS1iYiIlzGGldPTuXRSCtvLmiiqaeVgTStFNW3sqmjilV1HcHssjiDDnJw4LpmUwiUTU5iUpjW4RUQ+MpQ92POBA9baIgBjzJPANcDu48bdCTwNzBvC2kREpJcwp4P5YxOYPzbhmOPdPR52lDfyzr4a3t5XzX++so//fGUfaTFhzMiKpaa1i/KGDrrdHq6akcGNC3KYnB4ToE8hIhIYQxmwM4HSXq/LgAW9BxhjMoGPA5dymoBtjFkFrALIycnxe6EiInJyIcFBnDcmgfPGJPDNj02kqrmTd31he19VC2kxYVw8IZmuHg9PFZTy53XFTM+MZWJaNNnxEeQmRbB0cipRoXrGXkRGr6H8E+5kPzs8vgH8HuA71lr36X7UaK19EHgQvD3YfqtQRET6JTUmjE/Py+bT87JPONfQ1s3Tm8t4bVcV7+2voaq5C4DIEAdXz8rkhvnZTM+MVWuJiIw6Qxmwy4DefwJnARXHjZkLPOn7wzYJWGmM6bHWPjs0JYqIiL/ER4Zw20XjuO2icYB31ZJdFU08uaGUZ7aUsXpDCeOSIrliRjpLJqZQ29rF3soWiuvamJgWzYV5SUzJiMHl9nC4ro3yhg4mpEaTnRBxxu/t8Vh+/fo+5uTEs3Ry6mB/VBGRYwzZKiLGmGCgEFgKlAMbgRuttbtOMf5R4EWtIiIiMvo0dbh4aXslL26vYF1RHR8tx20MJEeFUt3ine0OdzrocLmPeW9eciQXT0jhgrxE5uXGExcRcsL1f/XqXn739kFCg4N4+vYLmZYZO+ifSURGv+G6TN9KvG0gDuBha+3PjDFfBrDWPnDc2EdRwBYRGfVqWrrYcKiejLgwJqZFExESTHVLJ2sP1rGlpJGEyBBykyJJjw1jR1kT7xTWsK6oju4eDwATUqO4cX4ON50/BqcjiBe2VXDn6i1cMyuDjYfqMcbw/B0LSYwKDfAnFZGRblgG7MGggC0icu7pdLnZXtbExsP1vL23moLiBsanRHHLwlx+8uJupmXE8sQXz2ffkRaue+BDZufE8ecvLMDpCAp06SIygilgi4jIOcFay2u7q/jpS7spre8gPTaM5+9YRHK0d8b6mS1lfP2pbSydlMKPr57apx5uEZGTUcAWEZFzSqfLzdOby1gwNpH8lKhjzj30XhH/9do+PBZWXTSO5dPSaO3qoa2rh5yECManRgeoahEZSRSwRUREeqlo7OCXr+zlua3HL2AFM7PjuH5uNmMSI9hV0cTO8mbCnEGsnJ7OwvwktZaICKCALSIiclI7y5sob+wgOjSYiNBgCg7X89eCUgqrWo+OyYgNo6Wrh5bOHuIjnHxsShqLJySzMD/xpKuWiMi5QQFbRESkj6y17CxvpqnDxZSMGBIiQ+jqcbOmsJbnt1Xwzr5qWjp7CDIwIyuOxeOTWDwhmfGp0dS2dlHV3ElHt5v4yBASI0NIjg4lIkS7VYqMNgrYIiIiftLj9rCtrJE1hbWs2V/DttLGo2t3n0pydChjEyMZkxhBbpLvn77X0WHOo+PcHkt3j4fwEMcgfwoROVsK2CIiIoOkqd3FBwdrKWtoJyU6jJQY74x1Q1s3dW3dVDV3UlzXxuG6dg7Xth3dOOcjSVEhpESHUdfWRY3v3K0Lx/KNZROIDNXMt8hw1deArf+KRURE+ik2wsnK6el9Ht/e3cPh2naK69o4VNdGcW07Na1dTM2IIS02jCNNnfzv+4d4ZecR7rpqCvNyE4iLcGKMOe11O11uNhc3MC0rlphes+IiEliawRYRERkGNh6u53v/2MGBau/Dlk6HISU6jMUTklg5PZ0LxiUSZAy1bV0U1bTx3NYKXtxeQUtnD+mxYfz8E9O5ZGIKAB3dbjYVNxztJxcR/1CLiIiIyAjT3ePhzT1VVDZ1UtPaRUldO+/sq6at201UaDBdPW5cbu//t8OcQaycls5FE5L4/dsH2V/dyrWzMnBbeHNPFe3dbpKiQvjVp2YeDd594XJ7eHxdMfGRIVwzK3OwPqrIiKQWERERkREmJDiIFce1nnS63LxbWMP7+2uJDA0mIy6MjNhwFoxLOPqw5Mrp6fz2zQP84d2DxIQFc82sTC7MS+T+tw5w6yMbuXVhLl9fNuGYNpLyxg7e2F1FuNPBwvFJZMaFs6m4gR88s4O9R1oA2F7WxPdXTsYRdPpWFRE5lmawRURERommDhcRIY6jG+N0utzc/fJeHv3wMMZAfnIU07NiOVjTxrbSxmPemxUfTnljB2kxYdx11VTWH6rjkQ8Oc8nEZO67YfYxK5+InKvUIiIiIiIAbClp4L39tWwpaWBHeRPpseGsmJ7GimnpuNwe3t9fy7qiOsYmR3LnpeOJ8q1k8vj6Yn703C6SokL4/IW53Dg/h7iIENweS0l9O6HBQWTEhR/zvSoaO9hwqJ76tm4afYH/k3OySI4ODcRHF/ErBWwRERE5awWH67nnjf28f6CWcKeDvJRIDlS30unyYAxcPCGZmy8YQ1JUKA+9d4iXdlTiPm6R8BBHENfOzuCSiSlsLW3kw4N11LZ28aXF47jp/DFHZ9zdHktbd49WRJFhSwFbRERE/GZPZTOPfHCIyqZOJqRGMzEtmvKGDp7YUHJ0Le+o0GA+My+b6+ZmkRIdRmy4k8N1bTzywSH+vqmMTpeHEEcQs3PisMCGQ/XkJUfyufPHsL2siXcKa2ho7+auK6dwy8KxZ6zJWnv0AVCRoaCALSIiIoOuu8fDa7uP0NDu4ppZGaecfW5o6+ZATSvTMmIJD3FgreWNPdX8/J97OFTbRlyEk0smptDQ3s07+2q489J8vrFswjFrgbd19bCtrJEtJd6vraWN1LZ2ccP8bO66aiphTu9umJuK6/nly/tYmJ/EFxeP1bb14jcK2CIiIjLsdfd4OFzXRl5yFI4gQ4/bww+e2clTBaVcPTOD9LgwSuvbKappo7Cq5egW9eOSI5mdHU9IcBCrN5QwPTOW+26Yzd8KSnng3YNEhzlp6nCRGhPKtz42kY/PziTY14oymFxuD909Hu3IOUopYIuIiMiIZK3lv17bx+/ePkiII4ishHDGJEQwIyuO2TlxzMqOIy7i/zbQeW3XEb751220dPUAcP3cbH545WT2Hmnhpy/tYVtpIzFhwSyZmMLSySkszE8iKer0D126PZbXdx/hz+uKSYkO43srJpESE3ba93S63Nzwx3UcaerkxTsXkXiG7yEjjwK2iIiIjGjNnS4iQ4L7tA734do2/uu1fVwzK5NlU1KPHrfW8uaeal7ddYS391VT29oNQF5yJPPHJhAfEYLL7cHlthjjXYs8yBhe2XmEQ7VtZMaFU9PaRWhwEN9fOZnr52YTdJJ6rLX865NbeWFbBU6HYVF+Eg/fMu+M291L/3g8Fre1Rx+MHWoK2CIiIiK9eDyW7eVNrC+qY8OhejYerqfT5cHpMAQ7gvB4LF1uDy63hxmZsXxx8TiWT02jpL6d7z+zg3VF9aTGhDIxLYbxKVHMzI7j4gnJxIY7ue/N/fzm9UL+bflEokKD+dFzu/jhFZO57aJxgf7Yo8qbe6r40XO7eOwL88lLjhry76+dHEVERER6CQoyzMr2tph86eK8U46z1h4z8zwuOYrVXzyf57ZW8G5hDYVVLawvquN/3z9EcJBhZnYcm4ob+MScTG73XfeDA7X88pW9TE6PITbcSWVTJ8EOw8K8JEKCvbOvbV09rN5Qwv6qVm5dlMuktJgBf7a2rh7eP1DL/NwE4iNDzvyGEerBNUVYa8lJiAh0Kac1pDPYxpjlwL2AA3jIWnv3cedvAr7je9kK3G6t3Xa6a2oGW0RERIaa22PZWtrAG3uqeXNPFakxYTz0+bmEBntXMmlqd7Hyvvcob+w45n1xEU6umJ5OYmQIj60rprHdRWhwEN1uD5+YncVtF42lpbOHkvp2qpo76e7x0OPxEBbs4JpZmeQkHhssu3s8rN5Qwm/f2k9tazcRIQ5uWpDDbReNI/UMPeMjzfayRq6+/wN+sHIyX1wcmJ8MDLsWEWOMAygElgFlwEbgBmvt7l5jLgT2WGsbjDErgB9baxec7roK2CIiIjIclda3805hDclRoaTHhlHX1sWzWyp4bfcROl0eLpucwu1L8slLjuT37xzk0Q8O0+32nHAdR5DB7fH2iF82OZVPzsmkuqWLXeXNvH+glvLGDs4fl8CtC8fyys4jPL+tAoDIEAdORxBhTgfLpqTyhUVjyR7gzG9daxd3Pb+LTpeHq2amc9nk1D6vlGKt5enN5RTVtHLVzAwmpw9spv7O1Vt4Z281H37vUqIDtBnRcAzYF+ANzJf7Xn8PwFr7i1OMjwd2WmszT3ddBWwREREZSVq7emjucJ2wzXxZQzsfHqgjNTaMnIQI0mPDCHEEERRkqGru5M9ri3liQwn1bd4HNeMjnEzPiuMLi8ayeHzS0baWkrp2/r6plObOHlxuD3Wt3byxpwoLLJ+WRkZsGK1dPbR1uclNimRebjyzc+JPuWHPnspmbvtTATWtXSREhHCkuZMwZxCXT03jhvk5LBibcMqHOWtauvju09t5c281xoC1MC0zhpsvyOVT52X1+SHQsoZ2Lv7VO/zLwlx+cMWUPt5p/xuOAfs6YLm19jbf688BC6y1d5xi/LeASR+NPxUFbBERETlXdLrcbCttZExiJKkxoX0OqJVNHTzywWGe3FBCj8cSFRpMmNNBWUM7HgtBBhIiQ4kJDyY23ElaTBhZ8eFEhTr5nzUHiQ4L5sHPzWV6ZiwFxQ08v62c57ZW0NLZw7ikSFZOT2dmdhwzs2JxOoLYc6SZXeXNPPDuQVq6evju8klcMyuDF7ZV8FRBGXsqm7lscgr/ed1MEvrQM/6TF3fzpw8Ps+bfLjnhLyZDaTgG7E8Blx8XsOdba+88ydhLgN8Di6y1dSc5vwpYBZCTk3NecXHxoNYuIiIiMhq1dLrYUtLIpuIGqlu6aO500dTuorKpg7KGDrp6PMzKjuPBz513wjrgHd1u/rmjkic3lrC5pBG358RMOS0zht98ehYTUqOPHrPW8sgHh7n75b3ERzr59uWTCA0OotPlxmMtYU4H4U4HESHBhIc4cAQZbvrjOi6bksq9n5k96PfkdIZjwO5Ti4gxZgbwDLDCWlt4putqBltERETE/6y11Ld1Ex8RctK1v3vr6Hazq6KJbWVNuD0eJqXFMCk9mpToUz9oubO8iX9dvYWi2rY+1fPinYuYlhnbr8/gb8MxYAfjfchxKVCO9yHHG621u3qNyQHeAm621n7Yl+sqYIuIiIiMTJ0uNweqWwkNDiI02EFQEHS6PHR0u+lwuWnv7qHT5SYmzMmF+UmBLnf4rYNtre0xxtwBvIp3mb6HrbW7jDFf9p1/APgRkAj83tdT1NOXDyEiIiIiI0+Y0xHwWenBoJ0cRURERET6oK8z2IHZyF1EREREZJRSwBYRERER8SMFbBERERERP1LAFhERERHxIwVsERERERE/UsAWEREREfGjEb9MnzGmBgjUXulJQG2AvvdIpPvVP7pf/aP71T+6X/2j+9U/ul/9o/vVP4G8X2OstclnGjTiA3YgGWMKtBFO3+l+9Y/uV//ofvWP7lf/6H71j+5X/+h+9c9IuF9qERERERER8SMFbBERERERP1LAPjsPBrqAEUb3q390v/pH96t/dL/6R/erf3S/+kf3q3+G/f1SD7aIiIiIiB9pBltERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFbRERERMSPFLBFRERERPxIAVtERERExI8UsEVERERE/EgBW0RERETEjxSwRURERET8SAFb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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))\n", "fig.suptitle('Training Metrics')\n", @@ -1068,9 +901,9 @@ "source": [ "## 모델 유효성 검증\n", "\n", - "이제 모델은 학습되었습니다. 모델의 성능을 검증하기위해 몇가지 통계를 얻을 수 있습니다. \n", + "이제 모델은 훈련되었습니다. 모델의 성능을 검증하기위해 몇가지 통계를 얻을 수 있습니다. \n", "\n", - "*평가(Evaluating)*는 모델이 예측을 얼마나 효과적으로 수행하는지 결정하는것을 의미합니다. 붓꽃 분류 모델의 유효성을 결정하기 위해서, 몇가지 꽃잎과 꽃받침 데이터를 통과시키고 어떠한 품종을 예측하는지 확인합니다. 그 후 실제 품종과 비교합니다. 예를 들어, 절반의 데이터를 올바르게 예측한 모델의 *[정확도](https://developers.google.com/machine-learning/glossary/#accuracy)* 는 `0.5`입니다. 그림 4는 조금 더 효과적인 보여줍니다. 5개의 예측 중 4개를 올바르게 예측한 80% 정확도의 모델입니다.\n", + "*평가(Evaluating)*는 모델이 예측을 얼마나 효과적으로 수행하는지 결정하는것을 의미합니다. 붓꽃 분류 모델의 유효성을 결정하기 위해, 몇가지 꽃잎과 꽃받침 데이터를 통과시키고 어떠한 품종을 예측하는지 확인합니다. 그 후 실제 품종과 비교합니다. 예를 들어, 절반의 데이터를 올바르게 예측한 모델의 *[정확도](https://developers.google.com/machine-learning/glossary/#accuracy)* 는 `0.5`입니다. 그림 4는 조금 더 효과적으로 보여줍니다. 5개의 예측 중 4개를 올바르게 예측한 80% 정확도의 모델입니다.\n", "\n", "\n", " \n", @@ -1099,7 +932,7 @@ " \n", " \n", " \n", "
5.52.54.01.311
\n", - " 그림 4. An Iris classifier that is 80% accurate.
 \n", + " 그림 4. 80% 정확도 붓꽃 분류기.
 \n", "
" ] @@ -1113,7 +946,7 @@ "source": [ "### 테스트 데이터 세트 설정\n", "\n", - "모델을 평가하는것은 모델을 학습하는것과 유사합니다. 가장 큰 차이는 훈련 데이터가 아닌 *[테스트 데이터 세트](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* 를 사용했다는 것입니다. 공정하게 모델의 유효성을 평가하기위해, 모델을 평가하기위한 예제는 반드시 훈련 데이터와 달라야합니다. \n", + "모델을 평가하는것은 모델을 훈련하는것과 유사합니다. 가장 큰 차이는 훈련 데이터가 아닌 *[테스트 데이터 세트](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* 를 사용했다는 것입니다. 공정하게 모델의 유효성을 평가하기위해, 모델을 평가하기위한 예제는 반드시 훈련 데이터와 달라야합니다. \n", "\n", "테스트 데이터 세트를 설정하는것은 훈련 데이터 세트를 설정하는 것과 유사합니다. CSV 파일을 다운로드하고 값을 구분합니다. 그 후 약간의 셔플을 적용합니다." ] @@ -1164,7 +997,7 @@ "source": [ "### 테스트 데이터 세트를 사용한 모델 평가\n", "\n", - "훈련 단계와는 다르게 모델은 테스트 데이터에 대해서 오직 한번의 [에포크](https://developers.google.com/machine-learning/glossary/#epoch)을 진행합니다. 다음의 코드셀은 테스트 셋을 반복하여 실행하고 실제 레이블과 비교합니다. 이는 전체 테스트 데이터 세트에 대한 정확도를 측정하는데 사용됩니다." + "훈련 단계와는 다르게 모델은 테스트 데이터에 대해서 오직 한 번의 [에포크](https://developers.google.com/machine-learning/glossary/#epoch)를 진행합니다. 다음의 코드 셀은 테스트 셋을 반복하여 실행하고 실제 레이블과 비교합니다. 이는 전체 테스트 데이터 세트에 대한 정확도를 측정하는데 사용됩니다." ] }, { @@ -1194,7 +1027,7 @@ "id": "HcKEZMtCOeK-" }, "source": [ - "예를 들어, 마지막 배치에서 모델이 일반적으로 정확하다는 것을 확인할 수 있습니다. " + "마지막 배치에서 모델이 일반적으로 정확하다는 것을 확인할 수 있습니다. " ] }, { @@ -1219,9 +1052,9 @@ "source": [ "## 예측을 위해 훈련된 모델 사용하기\n", "\n", - "이제 붓꽃을 분류하기위해 완벽하지는 않지만 어느정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)를 예측해봅시다.\n", + "이제 붓꽃을 분류하기 위해 완벽하지는 않지만 어느 정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)를 예측해봅시다.\n", "\n", - "실제로는 레이블 되지 않은 예제들은 여러 소스(앱, CSV 파일, 직접 제공 등)로부터 제공될 수 있습니다. 지금은 레이블을 예측하기 위해 수동으로 3개의 레이블되지 않은 예제를 제공하겠습니다. 레이블은 다음과 붓꽃 이름으로 매핑되어있습니다.\n", + "실제로는 레이블 되지 않은 예제들은 여러 소스(앱, CSV 파일, 직접 제공 등)로부터 제공될 수 있습니다. 지금은 레이블을 예측하기 위해 수동으로 3개의 레이블 되지 않은 예제를 제공하겠습니다. 레이블은 다음과 붓꽃 이름으로 매핑되어있습니다.\n", "* `0`: Iris setosa\n", "* `1`: Iris versicolor\n", "* `2`: Iris virginica" diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 95f18839886..3c25dcb5d6d 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -107,7 +107,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "cellView": "code", "colab": {}, @@ -116,7 +116,7 @@ }, "outputs": [], "source": [ - "import tensorflow as tf\n", + "from __future__ import absolute_import, division, print_function\n", "\n", "tf.enable_eager_execution()" ] @@ -130,7 +130,7 @@ "source": [ "## 텐서\n", "\n", - "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 크기를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기내에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 이용하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자는 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" + "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 크기를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기 내에서 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 이용하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자는 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" ] }, { @@ -186,7 +186,7 @@ "id": "eBPw8e8vrsom" }, "source": [ - "넘파이 `ndarray`와 텐서플로 `Tensor`의 가장 확연한 차이는 다음과 같습니다:\n", + "넘파이 배열과 텐서플로 텐서의 가장 확연한 차이는 다음과 같습니다:\n", "\n", "1. `텐서`는 가속기 메모리(GPU, TPU와 같은)의 사용이 가능합니다.\n", "2. `텐서`는 불변성(immutable)을 가집니다." @@ -201,7 +201,7 @@ "source": [ "### 넘파이 적합성\n", "\n", - "`Tensor`와 `ndarray`사이의 전환은 다소 간단합니다.\n", + "텐서와 넘파이 배열 사이의 전환은 다소 간단합니다.\n", "\n", "* 텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 전환합니다.\n", "* 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 전환합니다.\n", @@ -300,7 +300,8 @@ "source": [ "### 명시적 장치 배치\n", "\n", - "텐서플로에서 \"배치\"라는 용어는 개별 연산을 실행하기 위해 장치에 할당(배치)하는 것입니다. 앞서 언급했듯이, 명시적 지침이 없을경우 텐서플로는 연산을 실행하기위한 장치를 자동으로 결정하고, 필요시 텐서를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. 예를 들어:" + "텐서플로에서 \"배치\"라는 용어는 개별 연산을 실행하기 위해 장치에 할당(배치) 하는 것입니다. 앞서 언급했듯이, 명시적 지침이 없을 경우 텐서플로는 연산을 실행하기 위한 장치를 자동으로 결정하고, 필요시 텐서를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. \n", + "예를 들어:" ] }, { @@ -354,7 +355,7 @@ "* 데이터셋 생성.\n", "* 즉시 실행 활성화를 통한 데이터셋 반복\n", "\n", - "모델을 학습시키고 평가 루프를 제공할 간단하고 재사용 가능한 조각으로부터, 복잡한 입력 파이프라인을 구축하기위해 데이터셋 API를 사용하기를 권장합니다. \n", + "모델을 훈련시키고 평가 루프를 제공할 간단하고 재사용 가능한 조각으로부터, 복잡한 입력 파이프라인을 구축하기위해 데이터셋 API를 사용하기를 권장합니다. \n", "\n", "만약 텐서플로 그래프에 익숙하다면, 데이터셋 객체를 생성하기 위한 API는 즉시 실행이 활성화 되어도 동일하게 유지됩니다. 하지만 데이터셋의 요소를 반복하는 프로세스가 약간 더 간단해집니다.\n", "또한 `tf.data.Dataset` 객체를 통하여 파이썬 반복문을 사용할 수 있으며, 명시적으로 `tf.data.Iterator` 객체를 생성할 필요가 없습니다.\n", @@ -407,7 +408,7 @@ "source": [ "### 변환 적용\n", "\n", - "[`map`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`batch`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`shuffle`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle)과 같은 변환 함수를 사용하여 데이터셋의 레코드에 적용하세요. 세부사항은 [tf.data.Dataset을 위한 API 문서](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)을 참조하세요." + "[`맵(map)`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`배치(batch)`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`셔플(shuffle)`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle)과 같은 변환 함수를 사용하여 데이터셋의 레코드에 적용하세요. 세부사항은 [tf.data.Dataset을 위한 API 문서](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)을 참조하세요." ] }, { diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md index cdb89aeae1c..4721c470bae 100644 --- a/site/ko/tutorials/eager/index.md +++ b/site/ko/tutorials/eager/index.md @@ -9,7 +9,7 @@ [docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로 메일을 보내주시기 바랍니다. -즉시실행(Eager execution)은 더 나은 연산을 위한 실행에 의해 정의되는 명령형 인터페이스를 제공합니다. +즉시 실행(Eager execution)은 더 나은 연산을 위한 실행에 의해 정의되는 명령형 인터페이스를 제공합니다. 사용자 정의 층, 정방향 전파, 자동 미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 시작한 다음 순서대로 진행하세요. [즉시 실행 가이드](../../guide/eager). From e817a00a48c50c3493fe745c7f3eeb355425ec74 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Thu, 2 May 2019 12:37:12 +0900 Subject: [PATCH 13/19] Update_from 61d453b5 --- .../eager/custom_training_walkthrough.ipynb | 84 +++++++++---------- site/ko/tutorials/eager/eager_basics.ipynb | 22 ++--- site/ko/tutorials/eager/index.md | 6 +- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index 159af60744c..29e403cbc33 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -41,7 +41,7 @@ "id": "JtEZ1pCPn--z" }, "source": [ - "# 사용자 정의 학습: 둘러보기" + "# 사용자 정의 학습: 자세히 둘러보기" ] }, { @@ -103,7 +103,7 @@ "1. 데이터 가져오기 및 분석.\n", "2. 모델 타입 선정.\n", "3. 모델 훈련.\n", - "4. 모델 효과 검증.\n", + "4. 모델 효과 평가.\n", "5. 예측을 위한 훈련된 모델 사용." ] }, @@ -126,7 +126,7 @@ "source": [ "### 임포트 및 즉시 실행 구성\n", "\n", - "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화합니다. 즉시 실행은 텐서플로가 연산이 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게 합니다. 만약 파이썬 대화형 창이나 상호작용 콘솔을 사용하시면 더욱 익숙할 겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용 가능합니다.\n", + "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화합니다. 즉시 실행은 텐서플로 연산이 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게 합니다. 만약 파이썬 대화형 창이나 상호작용 콘솔을 사용하시면 더욱 익숙할 겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용 가능합니다.\n", "\n", "즉시 실행이 활성화될 때, 동일한 프로그램내에서 비활성화 할 수 없습니다. 더 많은 세부사항은 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 참조하세요." ] @@ -181,7 +181,7 @@ "
\n", "\n", - "다행히도 다른사람들이 먼저 꽃받침과 꽃잎의 길이와 폭이 측정된 [120개의 붓꽃 데이터](https://en.wikipedia.org/wiki/Iris_flower_data_set)를 만들어 놓았습니다. 이것은 머신러닝 분류문제에 있어 초보자에게 유명한 고전 데이터셋입니다. " + "다행히도 다른 사람들이 먼저 꽃받침과 꽃잎의 길이와 폭이 측정된 [120개의 붓꽃 데이터](https://en.wikipedia.org/wiki/Iris_flower_data_set)를 만들어 놓았습니다. 이것은 머신러닝 분류 문제에 있어 초보자에게 유명한 고전 데이터셋입니다. " ] }, { @@ -191,7 +191,7 @@ "id": "3Px6KAg0Jowz" }, "source": [ - "## 훈련 데이터 가져오기 및 분석\n", + "## 훈련 데이터 가져오기 및 파싱\n", "\n", "데이터를 불러오고 파이썬 프로그램이 사용할 수 있는 구조로 전환합니다.\n", "\n", @@ -253,9 +253,9 @@ "처음 5개의 데이터로부터 다음을 주목하세요.\n", "\n", "1. 첫 번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", - " * 총 120개의 예가 있으며, 각 예들은 4개의 특성(feature), 3개의 레이블(label)을 가지고 있습니다.\n", - "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[예](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", - " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 예제의 특징을 나타냅니다. 이 필드들는 붓꽃의 측정값을 부동소수점으로 나타냅니다.\n", + " * 총 120개의 샘플가 있으며, 각 샘플들은 4개의 특성(feature), 3개의 레이블(label)을 가지고 있습니다.\n", + "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[샘플](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", + " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 샘플의 특징을 나타냅니다. 이 필드들는 붓꽃의 측정값을 부동소수점으로 나타냅니다.\n", " * 마지막 컬럼(column)은 *[레이블(label)](https://developers.google.com/machine-learning/glossary/#label)*입니다.: 레이블은 예측하고자 하는 값을 나타냅니다. 이 데이터셋에서는 꽃의 이름과 관련된 정수값 0, 1, 2를 나타냅니다.\n", "\n", "코드로 표현하면 다음과 같습니다.:" @@ -319,7 +319,7 @@ "source": [ "### `tf.data.Dataset` 생성\n", "\n", - "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 모델에 적재하기 위해 많은 케이스를 다룹니다. 이는 훈련을 위해 형식으로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 [데이터셋 빠른 실행 가이드](https://www.tensorflow.org/get_started/datasets_quickstart)를 참조하세요. \n", + "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 적재할 때 발생하는 다양한 경우를 다룰 수 있습니다. 이는 훈련에 필요한 형태로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 [데이터셋 빠른 실행 가이드](https://www.tensorflow.org/get_started/datasets_quickstart)를 참조하세요. \n", "\n", "\n", "데이터셋이 CSV 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련 모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 [배치 사이즈(batch_size)](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." @@ -352,7 +352,7 @@ "id": "gB_RSn62c-3G" }, "source": [ - "`make_csv_dataset` 함수는 `tf.data.Dataset` 의 `(features, label)` 쌍을 반환합니다. `features`는 사전형 객체인: `{'feature_name': value}`로 주어집니다.\n", + "`make_csv_dataset` 함수는 `tf.data.Dataset` 의 `(features, label)` 쌍으로 구성된 `tf.data.Dataset`을 반환합니다. `features`는 딕셔너리 객체인: `{'feature_name': value}`로 주어집니다.\n", "또한 즉시 실행 활성화로 이 `Dataset`은 반복가능합니다. 다음은 특성(feature)을 살펴봅시다." ] }, @@ -378,7 +378,7 @@ "id": "E63mArnQaAGz" }, "source": [ - "유사한 특성의 값은 같이 그룹 되어있거나, *배치* 돼있다는 사실에 주목하세요. 각 예제행의 필드는 해당 특성 배열에 추가됩니다. `batch_size`를 조절하여 이 특성 배열에 저장된 예제의 수를 설정하세요.\n", + "유사한 특성의 값은 같이 그룹 되어있거나, *배치* 돼있다는 사실에 주목하세요. 각 샘플 행의 필드는 해당 특성 배열에 추가됩니다. `batch_size`를 조절하여 이 특성 배열에 저장된 샘플의 수를 설정하세요.\n", "\n", "또한 배치(batch)로부터 약간의 특성을 도식화하여 군집돼있는 데이터를 확인할 수 있습니다. " ] @@ -409,7 +409,7 @@ "id": "YlxpSyHlhT6M" }, "source": [ - "모델 구축 단계를 단순화하기 위해, 특성(사전형 객체)을 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", + "모델 구축 단계를 단순화하기 위해, 특성 딕셔너리를 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", "\n", "이 함수는 텐서의 리스트(list)로부터 값을 취하고 특정한 차원으로 결합된 텐서를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메서드(method)를 사용합니다." ] @@ -460,7 +460,7 @@ "id": "NLy0Q1xCldVO" }, "source": [ - "데이터셋의 특성 요소는 이제 형태가 `(batch_size, num_features)`인 배열입니다. 첫 5개행의 예제를 살펴봅시다." + "데이터셋의 특성 요소는 이제 형태가 `(batch_size, num_features)`인 배열입니다. 첫 5개행의 샘플을 살펴봅시다." ] }, { @@ -491,11 +491,11 @@ "\n", " *[모델](https://developers.google.com/machine-learning/crash-course/glossary#model)*은 특성(feature)과 레이블(label) 과의 관계입니다. 붓꽃 분류 문제에서 모델은 측정된 꽃받침과 꽃잎 사이의 관계를 정의하고 붓꽃의 품종을 예측합니다. 몇 가지 간단한 모델은 몇 줄의 대수학으로 표현할 수 있으나, 복잡한 머신러닝 모델은 요약하기 힘든 굉장히 많은 수의 매개변수를 가지고 있습니다.\n", "\n", - "머신러닝을 사용하지 않고 4가지의 특성 사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을 정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 사용자를 위한 모델을 결정합니다. 만약 충분한 예제를 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 사용자를 위한 특성 간의 관계를 이해하고 제공합니다. \n", + "머신러닝을 사용하지 않고 4가지의 특성 사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을 정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 사용자를 위한 모델을 결정합니다. 만약 충분히 좋은 샘플을 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 사용자를 위한 특성 간의 관계를 이해하고 제공합니다. \n", "\n", "### 모델 선정\n", "\n", - "이제 학습을 위한 모델의 종류를 선정해야합니다. 여러 종류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*으로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[dense(또는 완전 연결 신경망(fully-connected neural network))](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전 연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전 연결 신경망입니다. \n", + "이제 학습을 위한 모델의 종류를 선정해야합니다. 여러 종류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*으로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[밀집(dense) 또는 완전 연결 신경망(fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전 연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전 연결 신경망입니다. \n", "\n", "\n", " \n", "
\n", @@ -507,7 +507,7 @@ "
\n", "\n", - "그림 2의 모델이 훈련되고 레이블 되어있지 않은 데이터를 제공했을때, 모델은 주어진 데이터의 3가지 예측을 출력(주어진 레이블의 개수)합니다. 이러한 예측은 *[추론(inference)](https://developers.google.com/machine-learning/crash-course/glossary#inference)*이라고 불립니다. 이 예제에서 출력의 합은 1.0입니다. 그림 2에서 예측은 *Iris setosa* `0.02`, *Iris versicolor* `0.95`, *Iris virginica*에 `0.03`로 주어집니다. 이는 모델이 95%의 확률로 주어진 데이터를 *Iris versicolor*로 예측한다는 것을 의미합니다. " + "그림 2의 모델이 훈련된 다음 레이블 되어있지 않은 데이터를 제공했을때, 모델은 주어진 데이터의 3가지(주어진 레이블의 개수) 예측을 출력합니다. 이러한 예측은 *[추론(inference)](https://developers.google.com/machine-learning/crash-course/glossary#inference)*이라고 불립니다. 이 샘플에서 출력의 합은 1.0입니다. 그림 2에서 예측은 *Iris setosa* `0.02`, *Iris versicolor* `0.95`, *Iris virginica*에 `0.03`로 주어집니다. 이는 모델이 95%의 확률로 주어진 데이터를 *Iris versicolor*로 예측한다는 것을 의미합니다. " ] }, { @@ -519,9 +519,9 @@ "source": [ "### 케라스를 사용한 모델 생성\n", "\n", - "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 층을 생성하기 위한 풍부한 라이브러리를 제공합니다. 이는 파이프라인의 모든 것을 케라스가 처리하여 모델을 구축하기 쉽게 만듭니다.\n", + "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 층을 생성하기 위한 풍부한 라이브러리를 제공합니다. 케라스가 구성 요소를 연결하기 위한 복잡함을 모두 처리해 주기 때문에 모델을 구축하고 실험하는 것이 쉽습니다.\n", "\n", - "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 여러 층을 연이어 쌓은 모델입니다. 이 구조는 층의 인스턴스를 취하며, 아래의 케이스의 경우 각 층당 10개의 노드(node)를 가지는 2개의 [Dense(완전 연결 층)](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)와 3개의 예측(레이블의 수) 노드를 가지는 출력 층으로 구성되어있습니다. 첫 번째 층의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." + "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 여러 층을 연이어 쌓은 모델입니다. 이 구조는 층의 인스턴스를 취하며, 아래의 경우 각 층당 10개의 노드(node)를 가지는 2개의 [밀집(dense)](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)과 3개의 예측(레이블의 수) 노드를 가지는 출력 층으로 구성되어있습니다. 첫 번째 층의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." ] }, { @@ -550,7 +550,7 @@ "source": [ "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 층에서 출력의 크기를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 하나의 층과 동일하다고 생각할 수 있습니다. 사용 가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", "\n", - "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 의해 좌우됩니다. 머신러닝의 여러 측면과 마찬가지로, 최적의 신경망 타입을 결정하는 것은 많은 경험과 지식이 필요합니다. 경험을 토대로 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." + "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 의해 좌우됩니다. 머신러닝의 여러 측면과 마찬가지로, 최적의 신경망 타입을 결정하는 것은 많은 경험과 지식이 필요합니다. 경험을 토대로 보면 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." ] }, { @@ -586,7 +586,7 @@ "id": "wxyXOhwVr5S3" }, "source": [ - "각 예제는 각 클래스에 대한 [로짓(logit)](https://developers.google.com/machine-learning/crash-course/glossary#logits)을 반환합니다. \n", + "각 샘플은 각 클래스에 대한 [로짓(logit)](https://developers.google.com/machine-learning/crash-course/glossary#logits)을 반환합니다. \n", "\n", "이 로짓(logit)을 각 클래스에 대한 확률로 변환하기 위하서 [소프트맥스(softmax)](https://developers.google.com/machine-learning/crash-course/glossary#softmax) 함수를 사용하겠습니다." ] @@ -653,7 +653,7 @@ "\n", "훈련과 평가단계에서 모델의 *[손실(loss)](https://developers.google.com/machine-learning/crash-course/glossary#loss)*을 계산해야 합니다. 손실은 모델의 예측이 원하는 레이블과 얼마나 일치하는지, 또한 모델이 잘 작동하는지에 대한 척도로 사용됩니다. 이 값을 최소화하고, 최적화 해야합니다.\n", "\n", - "모델의 손실은 [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) 함수를 사용해 계산할 것입니다. 이 함수는 모델의 클래스(레이블)과 예측된 값(로짓)을 입력받아 예제를 통한 평균 손실을 반환합니다." + "모델의 손실은 [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) 함수를 사용해 계산할 것입니다. 이 함수는 모델의 클래스(레이블)과 예측된 값(로짓)을 입력받아 샘플의 평균 손실을 반환합니다." ] }, { @@ -682,7 +682,7 @@ "id": "3IcPqA24QM6B" }, "source": [ - "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)* 계산하기위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 확인하세요. " + "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)* 계산하기 위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 확인하세요. " ] }, { @@ -722,7 +722,7 @@ " \n", "\n", "\n", - "텐서플로는 훈련을 위해 사용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 경사 하강법(stochastic gradient descent, SGD)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현하는 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. `learning_rate`은 경사하강 과정의 크기를 나타내는 매개변수이며, 더 나은 결과를 위해 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " + "텐서플로는 훈련을 위해 사용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 경사 하강법(stochastic gradient descent, SGD)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현한 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. `learning_rate`은 경사하강 과정의 크기를 나타내는 매개변수이며, 더 나은 결과를 위해 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " ] }, { @@ -790,16 +790,16 @@ "source": [ "### 훈련 루프\n", "\n", - "모든 조각을 가지고 모델을 훈련할 준비가 되었습니다! 훈련 루프는 더 좋은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 아래의 훈련 단계를 작성한 것입니다. \n", + "모든 사항이 갖춰졌으므로 모델을 훈련할 준비가 되었습니다! 훈련 루프는 더 좋은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 아래의 훈련 단계를 작성한 것입니다. \n", "\n", "1. 각 *에포크(epoch)* 반복. 에포크는 데이터셋을 통과시키는 횟수입니다. \n", - "2. 에포크 내에서, `데이터셋`의 *특성* (`x`)와 *레이블* (`y`)를 가져오는 예제를 반복합니다.\n", - "3. 예제의 특성을 사용하여 결과를 예측 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기 위해 사용합니다. \n", + "2. 에포크 내에서, *특성* (`x`)와 *레이블* (`y`)가 포함된 훈련 `데이터셋`에 있는 샘플을 반복합니다.\n", + "3. 샘플의 특성을 사용하여 결과를 예측 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기 위해 사용합니다. \n", "4. 모델의 변수를 업데이트하기 위해 `옵티마이저`를 사용합니다. \n", "5. 시각화를 위해 몇가지 값들을 저장합니다.\n", "6. 각 에포크를 반복합니다.\n", "\n", - "`num_epochs` 변수는 데이터셋의 반복 횟수입니다. 반직관적으로, 모델을 길게 학습하는것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는것은 많은 경험과 직관을 필요로 합니다. " + "`num_epochs` 변수는 데이터셋의 반복 횟수입니다. 직관과는 반대로, 모델을 길게 학습하는 것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는 것은 많은 경험과 직관을 필요로 합니다. " ] }, { @@ -844,9 +844,9 @@ " train_accuracy_results.append(epoch_accuracy.result())\n", " \n", " if epoch % 50 == 0:\n", - " print(\"에포크 {:03d}: 손실: {:.3f}, 정확도: {:.3%}\".format(epoch,\n", - " epoch_loss_avg.result(),\n", - " epoch_accuracy.result()))" + " print(\"에포크 {:03d}: 손실: {:.3f}, 정확도: {:.3%}\".format(epoch, \n", + " epoch_loss_avg.result(), \n", + " epoch_accuracy.result()))" ] }, { @@ -899,11 +899,11 @@ "id": "Zg8GoMZhLpGH" }, "source": [ - "## 모델 유효성 검증\n", + "## 모델 유효성 평가\n", "\n", - "이제 모델은 훈련되었습니다. 모델의 성능을 검증하기위해 몇가지 통계를 얻을 수 있습니다. \n", + "이제 모델은 훈련되었습니다. 모델의 성능에 대한 몇가지 통계를 얻을 수 있습니다. \n", "\n", - "*평가(Evaluating)*는 모델이 예측을 얼마나 효과적으로 수행하는지 결정하는것을 의미합니다. 붓꽃 분류 모델의 유효성을 결정하기 위해, 몇가지 꽃잎과 꽃받침 데이터를 통과시키고 어떠한 품종을 예측하는지 확인합니다. 그 후 실제 품종과 비교합니다. 예를 들어, 절반의 데이터를 올바르게 예측한 모델의 *[정확도](https://developers.google.com/machine-learning/glossary/#accuracy)* 는 `0.5`입니다. 그림 4는 조금 더 효과적으로 보여줍니다. 5개의 예측 중 4개를 올바르게 예측한 80% 정확도의 모델입니다.\n", + "*평가(Evaluating)*는 모델이 예측을 얼마나 효과적으로 수행하는지 결정하는 것을 의미합니다. 붓꽃 분류 모델의 유효성을 결정하기 위해, 몇가지 꽃잎과 꽃받침 데이터를 통과시키고 어떠한 품종을 예측하는지 확인합니다. 그 후 실제 품종과 비교합니다. 예를 들어, 절반의 데이터를 올바르게 예측한 모델의 *[정확도](https://developers.google.com/machine-learning/glossary/#accuracy)* 는 `0.5`입니다. 그림 4는 조금 더 효과적인 모델입니다. 5개의 예측 중 4개를 올바르게 예측하여 80% 정확도를 냅니다.\n", "\n", "\n", " \n", @@ -912,9 +912,9 @@ " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", @@ -946,9 +946,9 @@ "source": [ "### 테스트 데이터 세트 설정\n", "\n", - "모델을 평가하는것은 모델을 훈련하는것과 유사합니다. 가장 큰 차이는 훈련 데이터가 아닌 *[테스트 데이터 세트](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* 를 사용했다는 것입니다. 공정하게 모델의 유효성을 평가하기위해, 모델을 평가하기위한 예제는 반드시 훈련 데이터와 달라야합니다. \n", + "모델을 평가하는 것은 모델을 훈련하는 것과 유사합니다. 가장 큰 차이는 훈련 데이터가 아닌 *[테스트 데이터 세트](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* 를 사용했다는 것입니다. 공정하게 모델의 유효성을 평가하기 위해, 모델을 평가하기 위한 샘플은 반드시 훈련 데이터와 달라야합니다. \n", "\n", - "테스트 데이터 세트를 설정하는것은 훈련 데이터 세트를 설정하는 것과 유사합니다. CSV 파일을 다운로드하고 값을 구분합니다. 그 후 약간의 셔플을 적용합니다." + "테스트 데이터 세트를 설정하는 것은 훈련 데이터 세트를 설정하는 것과 유사합니다. CSV 파일을 다운로드하고 값을 파싱합니다. 그 후 셔플은 적용하지 않습니다." ] }, { @@ -997,7 +997,7 @@ "source": [ "### 테스트 데이터 세트를 사용한 모델 평가\n", "\n", - "훈련 단계와는 다르게 모델은 테스트 데이터에 대해서 오직 한 번의 [에포크](https://developers.google.com/machine-learning/glossary/#epoch)를 진행합니다. 다음의 코드 셀은 테스트 셋을 반복하여 실행하고 실제 레이블과 비교합니다. 이는 전체 테스트 데이터 세트에 대한 정확도를 측정하는데 사용됩니다." + "훈련 단계와는 다르게 모델은 테스트 데이터에 대해서 오직 한 번의 [에포크](https://developers.google.com/machine-learning/glossary/#epoch)를 진행합니다. 다음의 코드 셀은 테스트 셋에 있는 샘플에 대해 실행하고 실제 레이블과 비교합니다. 이는 전체 테스트 데이터 세트에 대한 정확도를 측정하는데 사용됩니다." ] }, { @@ -1027,7 +1027,7 @@ "id": "HcKEZMtCOeK-" }, "source": [ - "마지막 배치에서 모델이 일반적으로 정확하다는 것을 확인할 수 있습니다. " + "마지막 배치에서 모델이 올바르게 예측한 것을 확인할 수 있습니다. " ] }, { @@ -1050,11 +1050,11 @@ "id": "7Li2r1tYvW7S" }, "source": [ - "## 예측을 위해 훈련된 모델 사용하기\n", + "## 훈련된 모델로 예측하기\n", "\n", "이제 붓꽃을 분류하기 위해 완벽하지는 않지만 어느 정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)를 예측해봅시다.\n", "\n", - "실제로는 레이블 되지 않은 예제들은 여러 소스(앱, CSV 파일, 직접 제공 등)로부터 제공될 수 있습니다. 지금은 레이블을 예측하기 위해 수동으로 3개의 레이블 되지 않은 예제를 제공하겠습니다. 레이블은 다음과 붓꽃 이름으로 매핑되어있습니다.\n", + "실제로는 레이블 되지 않은 샘플들은 여러 소스(앱, CSV 파일, 직접 제공 등)로부터 제공될 수 있습니다. 지금은 레이블을 예측하기 위해 수동으로 3개의 레이블 되지 않은 샘플을 제공하겠습니다. 레이블은 다음과 같은 붓꽃 이름으로 매핑되어있습니다.\n", "* `0`: Iris setosa\n", "* `1`: Iris versicolor\n", "* `2`: Iris virginica" diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 3c25dcb5d6d..374d8938a6a 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -102,7 +102,7 @@ "source": [ "## 텐서플로 임포트\n", "\n", - "시작하기 위해서 텐서플로 모듈을 임포트하고 즉시 실행(eager execution)을 활성화합니다. 즉시 실행 활성화로 텐서플로에 대한 대화형 프론트엔드(frontend)가 가능합니다. 세부사항은 나중에 이야기할 것입니다." + "시작하기 위해서 텐서플로 모듈을 임포트하고 즉시 실행(eager execution)을 활성화합니다. 즉시 실행 활성화로 텐서플로를 조금 더 대화형 프론트엔드(frontend)에 가깝게 만들어 줍니다. 세부사항은 나중에 이야기할 것입니다." ] }, { @@ -130,7 +130,7 @@ "source": [ "## 텐서\n", "\n", - "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 크기를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기 내에서 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 이용하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자는 자동적으로 순수 파이썬 타입을 전환합니다. 예를 들어:\n" + "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 크기를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기 메모리에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 이용하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자는 자동적으로 순수 파이썬 타입을 변환합니다. 예를 들어:\n" ] }, { @@ -188,7 +188,7 @@ "source": [ "넘파이 배열과 텐서플로 텐서의 가장 확연한 차이는 다음과 같습니다:\n", "\n", - "1. `텐서`는 가속기 메모리(GPU, TPU와 같은)의 사용이 가능합니다.\n", + "1. `텐서`는 가속기 메모리(GPU, TPU와 같은)에서 사용할 수 있습니다.\n", "2. `텐서`는 불변성(immutable)을 가집니다." ] }, @@ -199,7 +199,7 @@ "id": "Dwi1tdW3JBw6" }, "source": [ - "### 넘파이 적합성\n", + "### 넘파이 호환성\n", "\n", "텐서와 넘파이 배열 사이의 전환은 다소 간단합니다.\n", "\n", @@ -207,7 +207,7 @@ "* 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 전환합니다.\n", "\n", "텐서는 `.numpy()` 메서드(method)를 호출하여 넘파이 배열로 전환할 수 있습니다.\n", - "가능한 경우, 텐서와 배열은 메모리 표현을 공유하기 때문에 이러한 전환은 일반적으로 간단(저렴)합니다. 그러나 텐서는 GPU 메모리에 저장될 수 있고, 넘파이 배열은 항상 호스트 메모리에 백업이 되므로, 이러한 전환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 포함됩니다." + "가능한 경우, 텐서와 배열은 메모리 표현을 공유하기 때문에 이러한 전환은 일반적으로 간단(저렴)합니다. 그러나 텐서는 GPU 메모리에 저장될 수 있고, 넘파이 배열은 항상 호스트 메모리에 저장되므로, 이러한 변환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 필요합니다." ] }, { @@ -300,7 +300,7 @@ "source": [ "### 명시적 장치 배치\n", "\n", - "텐서플로에서 \"배치\"라는 용어는 개별 연산을 실행하기 위해 장치에 할당(배치) 하는 것입니다. 앞서 언급했듯이, 명시적 지침이 없을 경우 텐서플로는 연산을 실행하기 위한 장치를 자동으로 결정하고, 필요시 텐서를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. \n", + "텐서플로에서 \"배치(replacement)\"라는 용어는 개별 연산을 실행하기 위해 장치에 할당(배치) 하는 것입니다. 앞서 언급했듯이, 명시적 지침이 없을 경우 텐서플로는 연산을 실행하기 위한 장치를 자동으로 결정하고, 필요시 텐서를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. \n", "예를 들어:" ] }, @@ -355,11 +355,11 @@ "* 데이터셋 생성.\n", "* 즉시 실행 활성화를 통한 데이터셋 반복\n", "\n", - "모델을 훈련시키고 평가 루프를 제공할 간단하고 재사용 가능한 조각으로부터, 복잡한 입력 파이프라인을 구축하기위해 데이터셋 API를 사용하기를 권장합니다. \n", + "모델을 훈련시키고 평가 루프를 제공할 간단하고 재사용 가능한 모듈로부터, 복잡한 입력 파이프라인을 구축하기위해 데이터셋 API를 사용하기를 권장합니다. \n", "\n", - "만약 텐서플로 그래프에 익숙하다면, 데이터셋 객체를 생성하기 위한 API는 즉시 실행이 활성화 되어도 동일하게 유지됩니다. 하지만 데이터셋의 요소를 반복하는 프로세스가 약간 더 간단해집니다.\n", + "만약 텐서플로 그래프에 익숙하다면 알겠지만, 데이터셋 객체를 생성하기 위한 API는 즉시 실행이 활성화 되어도 동일하게 유지됩니다. 하지만 데이터셋의 요소를 반복하는 프로세스가 약간 더 간단해집니다.\n", "또한 `tf.data.Dataset` 객체를 통하여 파이썬 반복문을 사용할 수 있으며, 명시적으로 `tf.data.Iterator` 객체를 생성할 필요가 없습니다.\n", - "그 결과, [텐서플로 가이드](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시 실행이 활성화될 때에는 관계없습니다. " + "그 결과, [텐서플로 가이드](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시 실행이 활성화될 때에는 신경 쓰지 않아도 됩니다. " ] }, { @@ -369,9 +369,9 @@ "id": "zI0fmOynH-Ne" }, "source": [ - "### 데이터셋 소스 생성\n", + "### 소스 Dataset 생성\n", "\n", - "굉장히 유용한 함수중 하나인 [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices)를 사용하여 데이터셋 소스를 생성하거나 파일로부터 읽어들이는 객체인 [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) 또는 [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset)를 사용하여 데이터셋 소스를 생성하세요. 더 많은 정보를 위해서 [텐서플로 가이드](https://www.tensorflow.org/guide/datasets#reading_input_data)를 참조하세요." + "굉장히 유용한 함수중 하나인 [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices)와 같은 팩토리(factory) 함수 중 하나를 사용하거나 파일로부터 읽어들이는 객체인 [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) 또는 [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset)를 사용하여 소스 dataset을 생성하세요. 더 많은 정보를 위해서 [텐서플로 가이드](https://www.tensorflow.org/guide/datasets#reading_input_data)를 참조하세요." ] }, { diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md index 4721c470bae..114fc16091b 100644 --- a/site/ko/tutorials/eager/index.md +++ b/site/ko/tutorials/eager/index.md @@ -9,13 +9,13 @@ [docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로 메일을 보내주시기 바랍니다. -즉시 실행(Eager execution)은 더 나은 연산을 위한 실행에 의해 정의되는 명령형 인터페이스를 제공합니다. -사용자 정의 층, 정방향 전파, 자동 미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 시작한 다음 순서대로 진행하세요. +즉시 실행(Eager execution)은 고급 연산을 위한 실행에 의해 정의되는 명령형 인터페이스를 제공합니다. +사용자 정의 층, 정방향 전파, 자동 미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 보고 난 후에 다음 문서를 읽어보세요. [즉시 실행 가이드](../../guide/eager). 1. [즉시 실행](eager_basics.ipynb) 2. [자동 미분과 그래디언트 테이프](automatic_differentiation.ipynb) 3. [사용자 정의 학습 : 기초](custom_training.ipynb) 4. [사용자 정의 층](custom_layers.ipynb) -5. [사용자 정의 학습 : 둘러보기](custom_training_walkthrough.ipynb) +5. [사용자 정의 학습 : 자세히 둘러보기](custom_training_walkthrough.ipynb) From 8aa79ae3bfe139a6004d391480ed744cc1370de6 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Fri, 3 May 2019 00:42:22 +0900 Subject: [PATCH 14/19] Update custom_training_walkthrough.ipynb --- site/ko/tutorials/eager/custom_training_walkthrough.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index 29e403cbc33..ecd75f39655 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -253,7 +253,7 @@ "처음 5개의 데이터로부터 다음을 주목하세요.\n", "\n", "1. 첫 번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", - " * 총 120개의 샘플가 있으며, 각 샘플들은 4개의 특성(feature), 3개의 레이블(label)을 가지고 있습니다.\n", + " * 총 120개의 샘플이 있으며, 각 샘플들은 4개의 특성(feature), 3개의 레이블(label)을 가지고 있습니다.\n", "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[샘플](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 샘플의 특징을 나타냅니다. 이 필드들는 붓꽃의 측정값을 부동소수점으로 나타냅니다.\n", " * 마지막 컬럼(column)은 *[레이블(label)](https://developers.google.com/machine-learning/glossary/#label)*입니다.: 레이블은 예측하고자 하는 값을 나타냅니다. 이 데이터셋에서는 꽃의 이름과 관련된 정수값 0, 1, 2를 나타냅니다.\n", @@ -352,7 +352,7 @@ "id": "gB_RSn62c-3G" }, "source": [ - "`make_csv_dataset` 함수는 `tf.data.Dataset` 의 `(features, label)` 쌍으로 구성된 `tf.data.Dataset`을 반환합니다. `features`는 딕셔너리 객체인: `{'feature_name': value}`로 주어집니다.\n", + "`make_csv_dataset` 함수는 `(features, label)` 쌍으로 구성된 `tf.data.Dataset`을 반환합니다. `features`는 딕셔너리 객체인: `{'feature_name': value}`로 주어집니다.\n", "또한 즉시 실행 활성화로 이 `Dataset`은 반복가능합니다. 다음은 특성(feature)을 살펴봅시다." ] }, @@ -521,7 +521,7 @@ "\n", "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 층을 생성하기 위한 풍부한 라이브러리를 제공합니다. 케라스가 구성 요소를 연결하기 위한 복잡함을 모두 처리해 주기 때문에 모델을 구축하고 실험하는 것이 쉽습니다.\n", "\n", - "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 여러 층을 연이어 쌓은 모델입니다. 이 구조는 층의 인스턴스를 취하며, 아래의 경우 각 층당 10개의 노드(node)를 가지는 2개의 [밀집(dense)](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)과 3개의 예측(레이블의 수) 노드를 가지는 출력 층으로 구성되어있습니다. 첫 번째 층의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." + "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 여러 층을 연이어 쌓은 모델입니다. 이 구조는 층의 인스턴스를 취하며, 아래의 경우 각 층당 10개의 노드(node)를 가지는 2개의 [Dense(완전 연결 층)](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)과 3개의 예측(레이블의 수) 노드를 가지는 출력 층으로 구성되어있습니다. 첫 번째 층의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." ] }, { From c5848ee0ca3b8a905daabd0eb644f2621ce2bdca Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Fri, 3 May 2019 00:46:06 +0900 Subject: [PATCH 15/19] Update from 338fbdd3 --- site/ko/tutorials/eager/custom_training_walkthrough.ipynb | 2 +- site/ko/tutorials/eager/eager_basics.ipynb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index ecd75f39655..8f42dd20700 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -682,7 +682,7 @@ "id": "3IcPqA24QM6B" }, "source": [ - "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)* 계산하기 위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 확인하세요. " + "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)*를 계산하기 위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 확인하세요. " ] }, { diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 374d8938a6a..8fc5ff858b2 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -201,7 +201,7 @@ "source": [ "### 넘파이 호환성\n", "\n", - "텐서와 넘파이 배열 사이의 전환은 다소 간단합니다.\n", + "텐서와 넘파이 배열 사이의 변환은 다소 간단합니다.\n", "\n", "* 텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 전환합니다.\n", "* 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 전환합니다.\n", From d8663a87245255fd9514c450a3365bf1c5406fac Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Fri, 3 May 2019 00:53:36 +0900 Subject: [PATCH 16/19] Update eager_basics.ipynb --- site/ko/tutorials/eager/eager_basics.ipynb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 8fc5ff858b2..81749da2aa4 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -203,11 +203,11 @@ "\n", "텐서와 넘파이 배열 사이의 변환은 다소 간단합니다.\n", "\n", - "* 텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 전환합니다.\n", - "* 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 전환합니다.\n", + "* 텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 변환합니다.\n", + "* 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 변환합니다.\n", "\n", - "텐서는 `.numpy()` 메서드(method)를 호출하여 넘파이 배열로 전환할 수 있습니다.\n", - "가능한 경우, 텐서와 배열은 메모리 표현을 공유하기 때문에 이러한 전환은 일반적으로 간단(저렴)합니다. 그러나 텐서는 GPU 메모리에 저장될 수 있고, 넘파이 배열은 항상 호스트 메모리에 저장되므로, 이러한 변환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 필요합니다." + "텐서는 `.numpy()` 메서드(method)를 호출하여 넘파이 배열로 변환할 수 있습니다.\n", + "가능한 경우, 텐서와 배열은 메모리 표현을 공유하기 때문에 이러한 변환은 일반적으로 간단(저렴)합니다. 그러나 텐서는 GPU 메모리에 저장될 수 있고, 넘파이 배열은 항상 호스트 메모리에 저장되므로, 이러한 변환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 필요합니다." ] }, { @@ -224,15 +224,15 @@ "\n", "ndarray = np.ones([3, 3])\n", "\n", - "print(\"텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 전환합니다.\")\n", + "print(\"텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 변환합니다.\")\n", "tensor = tf.multiply(ndarray, 42)\n", "print(tensor)\n", "\n", "\n", - "print(\"그리고 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 전환합니다.\")\n", + "print(\"그리고 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 변환합니다.\")\n", "print(np.add(tensor, 1))\n", "\n", - "print(\".numpy() 메서드는 텐서를 넘파이 배열로 전환합니다.\")\n", + "print(\".numpy() 메서드는 텐서를 넘파이 배열로 변환합니다.\")\n", "print(tensor.numpy())" ] }, From 058b8ba3f81d3076b7d7052d443791892f7ef539 Mon Sep 17 00:00:00 2001 From: Choiuijin1125 Date: Fri, 3 May 2019 21:11:21 +0900 Subject: [PATCH 17/19] Update from 9ed23d5c --- site/ko/tutorials/eager/automatic_differentiation.ipynb | 2 ++ site/ko/tutorials/eager/custom_layers.ipynb | 2 ++ site/ko/tutorials/eager/eager_basics.ipynb | 2 ++ 3 files changed, 6 insertions(+) diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index e0649886ffc..e0ce93b6e18 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -108,6 +108,8 @@ }, "outputs": [], "source": [ + "from __future__ import absolute_import, division, print_function, unicode_literals\n", + "\n", "import tensorflow as tf\n", "\n", "tf.enable_eager_execution()" diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index c716311304c..5060a0dafe7 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -98,6 +98,8 @@ }, "outputs": [], "source": [ + "from __future__ import absolute_import, division, print_function, unicode_literals\n", + "\n", "import tensorflow as tf\n", "\n", "tf.enable_eager_execution()" diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index 81749da2aa4..f70825fafd5 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -118,6 +118,8 @@ "source": [ "from __future__ import absolute_import, division, print_function\n", "\n", + "import tensorflow as tf\n", + "\n", "tf.enable_eager_execution()" ] }, From ae0e9400405dd86bdb75aff6a01034605b9556fd Mon Sep 17 00:00:00 2001 From: Billy Lamberta Date: Fri, 3 May 2019 10:43:16 -0700 Subject: [PATCH 18/19] Update translation note. Colab formatting --- .../eager/automatic_differentiation.ipynb | 676 ++--- site/ko/tutorials/eager/custom_layers.ipynb | 757 +++--- site/ko/tutorials/eager/custom_training.ipynb | 928 +++---- .../eager/custom_training_walkthrough.ipynb | 2236 +++++++++-------- site/ko/tutorials/eager/eager_basics.ipynb | 967 ++++--- site/ko/tutorials/eager/index.md | 13 +- 6 files changed, 2791 insertions(+), 2786 deletions(-) diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb index e0ce93b6e18..cdb4c100205 100644 --- a/site/ko/tutorials/eager/automatic_differentiation.ipynb +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -1,339 +1,341 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "t09eeeR5prIJ" - }, - "source": [ - "##### Copyright 2018 The TensorFlow Authors." - ] + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "automatic_differentiation.ipynb", + "version": "0.3.2", + "provenance": [], + "private_outputs": true, + "collapsed_sections": [], + "toc_visible": true + }, + "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.7.1" + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "colab": {}, - "colab_type": "code", - "id": "GCCk8_dHpuNf" - }, - "outputs": [], - "source": [ - "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", - "# you may not use this file except in compliance with the License.\n", - "# You may obtain a copy of the License at\n", - "#\n", - "# https://www.apache.org/licenses/LICENSE-2.0\n", - "#\n", - "# Unless required by applicable law or agreed to in writing, software\n", - "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", - "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", - "# See the License for the specific language governing permissions and\n", - "# limitations under the License." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "xh8WkEwWpnm7" - }, - "source": [ - "# 자동 미분과 그래디언트 테이프" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "idv0bPeCp325" - }, - "source": [ - "
Example featuresLabelModel prediction샘플 특성레이블모델 예측
5.93.04.31.511
\n", - " \n", - " \n", - " \n", - "
\n", - " TensorFlow.org에서 보기\n", - " \n", - " 구글 코랩(Colab)에서 실행하기\n", - " \n", - " 깃허브(GitHub) 소스 보기\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", - "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", - "이 번역에 개선할 부분이 있다면\n", - "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", - "문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을\n", - "작성하거나\n", - "[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로\n", - "메일을 보내주시기 바랍니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "vDJ4XzMqodTy" - }, - "source": [ - "이전 튜토리얼에서는 텐서(tensor)와 텐서의 연산에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술 중 하나인 [자동 미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "GQJysDM__Qb0" - }, - "source": [ - "## 설정\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "OiMPZStlibBv" - }, - "outputs": [], - "source": [ - "from __future__ import absolute_import, division, print_function, unicode_literals\n", - "\n", - "import tensorflow as tf\n", - "\n", - "tf.enable_eager_execution()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "1CLWJl0QliB0" - }, - "source": [ - "## 그래디언트 테이프\n", - "\n", - "텐서플로는 자동 미분(주어진 입력 변수에 대한 연산의 그래디언트(gradient)를 계산하는 것)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape`는 안에서 실행된 모든 연산을 테이프(tape)에 \"기록\"합니다. 그리고 [후진 방식 자동 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 각각의 기록된 연산과 관련된 그래디언트와 테이프를 사용하여 기록된 연산의 그래디언트를 계산합니다. \n", - "\n", - "예를 들면:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "bAFeIE8EuVIq" - }, - "outputs": [], - "source": [ - "x = tf.ones((2, 2))\n", - " \n", - "with tf.GradientTape() as t:\n", - " t.watch(x)\n", - " y = tf.reduce_sum(x)\n", - " z = tf.multiply(y, y)\n", - "\n", - "# 입력 텐서 x에 대한 z의 도함수\n", - "dz_dx = t.gradient(z, x)\n", - "for i in [0, 1]:\n", - " for j in [0, 1]:\n", - " assert dz_dx[i][j].numpy() == 8.0" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "N4VlqKFzzGaC" - }, - "source": [ - "또한 `tf.GradientTape` 컨텍스트 안에서 기록되는 동안 계산된 중간 값에 대한 그래디언트도 구할 수 있습니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "7XaPRAwUyYms" - }, - "outputs": [], - "source": [ - "x = tf.ones((2, 2))\n", - " \n", - "with tf.GradientTape() as t:\n", - " t.watch(x)\n", - " y = tf.reduce_sum(x)\n", - " z = tf.multiply(y, y)\n", - "\n", - "# 테이프 사용하여 중간 값 y에 대한 도함수를 계산합니다. \n", - "dz_dy = t.gradient(z, y)\n", - "assert dz_dy.numpy() == 8.0" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "ISkXuY7YzIcS" - }, - "source": [ - "기본적으로 GradientTape.gradient() 메서드가 호출되면 GradientTape에 포함된 리소스가 해제됩니다. 동일한 연산 대해 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. 이 그래디언트 테이프는 `gradient()` 메서드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다.\n", - "예를 들면 다음과 같습니다:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "zZaCm3-9zVCi" - }, - "outputs": [], - "source": [ - "x = tf.constant(3.0)\n", - "with tf.GradientTape(persistent=True) as t:\n", - " t.watch(x)\n", - " y = x * x\n", - " z = y * y\n", - "dz_dx = t.gradient(z, x) # 108.0 (4*x^3 at x = 3)\n", - "dy_dx = t.gradient(y, x) # 6.0\n", - "del t # 테이프에 대한 참조를 삭제합니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "6kADybtQzYj4" - }, - "source": [ - "### 제어 흐름 기록\n", - "\n", - "연산이 실행되는 순서대로 테이프에 기록되기 때문에, 파이썬 제어 흐름(예를 들어 `if` `while`, `for`문 같은)이 자연스럽게 처리됩니다. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "9FViq92UX7P8" - }, - "outputs": [], - "source": [ - "def f(x, y):\n", - " output = 1.0\n", - " for i in range(y):\n", - " if i > 1 and i < 5:\n", - " output = tf.multiply(output, x)\n", - " return output\n", - "\n", - "def grad(x, y):\n", - " with tf.GradientTape() as t:\n", - " t.watch(x)\n", - " out = f(x, y)\n", - " return t.gradient(out, x) \n", - "\n", - "x = tf.convert_to_tensor(2.0)\n", - "\n", - "assert grad(x, 6).numpy() == 12.0\n", - "assert grad(x, 5).numpy() == 12.0\n", - "assert grad(x, 4).numpy() == 4.0\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "DK05KXrAAld3" - }, - "source": [ - "### 고계도(Higher-order) 그래디언트\n", - "\n", - "`GradientTape` 컨텍스트 매니저안에 있는 연산들은 자동미분을 위해 기록됩니다. 만약 그래디언트가 컨텍스트 안에서 계산되면 그 그래디언트 연산 또한 기록되어집니다. 그 결과 똑같은 API가 고계도 그래디언트에서도 잘 작동합니다. 예를 들면:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "cPQgthZ7ugRJ" - }, - "outputs": [], - "source": [ - "x = tf.Variable(1.0) # 1.0으로 초기화된 텐서플로 변수를 생성합니다.\n", - "\n", - "with tf.GradientTape() as t:\n", - " with tf.GradientTape() as t2:\n", - " y = x * x * x\n", - " # t 컨텍스트 매니저 안의 그래디언트를 계산합니다.\n", - " # 이것은 또한 그래디언트 연산 자체도 미분가능하다는것을 의미합니다. \n", - " dy_dx = t2.gradient(y, x)\n", - "d2y_dx2 = t.gradient(dy_dx, x)\n", - "\n", - "assert dy_dx.numpy() == 3.0\n", - "assert d2y_dx2.numpy() == 6.0" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "4U1KKzUpNl58" - }, - "source": [ - "## 다음 단계\n", - "\n", - "이번 튜토리얼에서는 텐서플로에서 그래디언트 계산법을 다루었습니다. 이를 통해 신경망(neural network)을 구축하고 훈련시키는데 필요한 많은 기본 요소를 배웠습니다." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "name": "automatic_differentiation.ipynb", - "private_outputs": true, - "provenance": [], - "toc_visible": true, - "version": "0.3.2" - }, - "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.7.1" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "t09eeeR5prIJ" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors." + ] + }, + { + "cell_type": "code", + "metadata": { + "cellView": "form", + "colab_type": "code", + "id": "GCCk8_dHpuNf", + "colab": {} + }, + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "xh8WkEwWpnm7" + }, + "source": [ + "# 자동 미분과 그래디언트 테이프" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "idv0bPeCp325" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " TensorFlow.org에서 보기\n", + " \n", + " 구글 코랩(Colab)에서 실행하기\n", + " \n", + " 깃허브(GitHub) 소스 보기\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q9_NaXPWxEd8", + "colab_type": "text" + }, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", + "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", + "이 번역에 개선할 부분이 있다면\n", + "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", + "문서 번역이나 리뷰에 참여하려면\n", + "[docs-ko@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs-ko)로\n", + "메일을 보내주시기 바랍니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "vDJ4XzMqodTy" + }, + "source": [ + "이전 튜토리얼에서는 텐서(tensor)와 텐서의 연산에 대해서 알아보았습니다. 이번 튜토리얼에서는 머신러닝 모델을 최적화할 수 있는 주요 기술 중 하나인 [자동 미분(automatic differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)에 대해 알아보겠습니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "GQJysDM__Qb0" + }, + "source": [ + "## 설정\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "OiMPZStlibBv", + "colab": {} + }, + "source": [ + "from __future__ import absolute_import, division, print_function, unicode_literals\n", + "\n", + "import tensorflow as tf\n", + "\n", + "tf.enable_eager_execution()" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "1CLWJl0QliB0" + }, + "source": [ + "## 그래디언트 테이프\n", + "\n", + "텐서플로는 자동 미분(주어진 입력 변수에 대한 연산의 그래디언트(gradient)를 계산하는 것)을 위한 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) API를 제공합니다. `tf.GradientTape`는 안에서 실행된 모든 연산을 테이프(tape)에 \"기록\"합니다. 그리고 [후진 방식 자동 미분(reverse mode differentiation)](https://en.wikipedia.org/wiki/Automatic_differentiation)을 사용하여 각각의 기록된 연산과 관련된 그래디언트와 테이프를 사용하여 기록된 연산의 그래디언트를 계산합니다. \n", + "\n", + "예를 들면:" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "bAFeIE8EuVIq", + "colab": {} + }, + "source": [ + "x = tf.ones((2, 2))\n", + " \n", + "with tf.GradientTape() as t:\n", + " t.watch(x)\n", + " y = tf.reduce_sum(x)\n", + " z = tf.multiply(y, y)\n", + "\n", + "# 입력 텐서 x에 대한 z의 도함수\n", + "dz_dx = t.gradient(z, x)\n", + "for i in [0, 1]:\n", + " for j in [0, 1]:\n", + " assert dz_dx[i][j].numpy() == 8.0" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "N4VlqKFzzGaC" + }, + "source": [ + "또한 `tf.GradientTape` 컨텍스트 안에서 기록되는 동안 계산된 중간 값에 대한 그래디언트도 구할 수 있습니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "7XaPRAwUyYms", + "colab": {} + }, + "source": [ + "x = tf.ones((2, 2))\n", + " \n", + "with tf.GradientTape() as t:\n", + " t.watch(x)\n", + " y = tf.reduce_sum(x)\n", + " z = tf.multiply(y, y)\n", + "\n", + "# 테이프 사용하여 중간 값 y에 대한 도함수를 계산합니다. \n", + "dz_dy = t.gradient(z, y)\n", + "assert dz_dy.numpy() == 8.0" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "ISkXuY7YzIcS" + }, + "source": [ + "기본적으로 GradientTape.gradient() 메서드가 호출되면 GradientTape에 포함된 리소스가 해제됩니다. 동일한 연산 대해 여러 그래디언트를 계산하려면, `지속성있는(persistent)` 그래디언트 테이프를 생성하면 됩니다. 이 그래디언트 테이프는 `gradient()` 메서드의 다중 호출을 허용합니다. 테이프 객체가 쓰레기 수집(garbage collection)될때 리소스는 해체됩니다.\n", + "예를 들면 다음과 같습니다:" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "zZaCm3-9zVCi", + "colab": {} + }, + "source": [ + "x = tf.constant(3.0)\n", + "with tf.GradientTape(persistent=True) as t:\n", + " t.watch(x)\n", + " y = x * x\n", + " z = y * y\n", + "dz_dx = t.gradient(z, x) # 108.0 (4*x^3 at x = 3)\n", + "dy_dx = t.gradient(y, x) # 6.0\n", + "del t # 테이프에 대한 참조를 삭제합니다." + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "6kADybtQzYj4" + }, + "source": [ + "### 제어 흐름 기록\n", + "\n", + "연산이 실행되는 순서대로 테이프에 기록되기 때문에, 파이썬 제어 흐름(예를 들어 `if` `while`, `for`문 같은)이 자연스럽게 처리됩니다. " + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "9FViq92UX7P8", + "colab": {} + }, + "source": [ + "def f(x, y):\n", + " output = 1.0\n", + " for i in range(y):\n", + " if i > 1 and i < 5:\n", + " output = tf.multiply(output, x)\n", + " return output\n", + "\n", + "def grad(x, y):\n", + " with tf.GradientTape() as t:\n", + " t.watch(x)\n", + " out = f(x, y)\n", + " return t.gradient(out, x) \n", + "\n", + "x = tf.convert_to_tensor(2.0)\n", + "\n", + "assert grad(x, 6).numpy() == 12.0\n", + "assert grad(x, 5).numpy() == 12.0\n", + "assert grad(x, 4).numpy() == 4.0\n" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "DK05KXrAAld3" + }, + "source": [ + "### 고계도(Higher-order) 그래디언트\n", + "\n", + "`GradientTape` 컨텍스트 매니저안에 있는 연산들은 자동미분을 위해 기록됩니다. 만약 그래디언트가 컨텍스트 안에서 계산되면 그 그래디언트 연산 또한 기록되어집니다. 그 결과 똑같은 API가 고계도 그래디언트에서도 잘 작동합니다. 예를 들면:" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "cPQgthZ7ugRJ", + "colab": {} + }, + "source": [ + "x = tf.Variable(1.0) # 1.0으로 초기화된 텐서플로 변수를 생성합니다.\n", + "\n", + "with tf.GradientTape() as t:\n", + " with tf.GradientTape() as t2:\n", + " y = x * x * x\n", + " # t 컨텍스트 매니저 안의 그래디언트를 계산합니다.\n", + " # 이것은 또한 그래디언트 연산 자체도 미분가능하다는것을 의미합니다. \n", + " dy_dx = t2.gradient(y, x)\n", + "d2y_dx2 = t.gradient(dy_dx, x)\n", + "\n", + "assert dy_dx.numpy() == 3.0\n", + "assert d2y_dx2.numpy() == 6.0" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "4U1KKzUpNl58" + }, + "source": [ + "## 다음 단계\n", + "\n", + "이번 튜토리얼에서는 텐서플로에서 그래디언트 계산법을 다루었습니다. 이를 통해 신경망(neural network)을 구축하고 훈련시키는데 필요한 많은 기본 요소를 배웠습니다." + ] + } + ] +} \ No newline at end of file diff --git a/site/ko/tutorials/eager/custom_layers.ipynb b/site/ko/tutorials/eager/custom_layers.ipynb index 5060a0dafe7..98614aacbfa 100644 --- a/site/ko/tutorials/eager/custom_layers.ipynb +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -1,378 +1,383 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "tDnwEv8FtJm7" - }, - "source": [ - "##### Copyright 2018 The TensorFlow Authors." - ] + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "custom_layers.ipynb", + "version": "0.3.2", + "provenance": [], + "private_outputs": true, + "collapsed_sections": [], + "toc_visible": true + }, + "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.7.1" + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "colab": {}, - "colab_type": "code", - "id": "JlknJBWQtKkI" - }, - "outputs": [], - "source": [ - "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", - "# you may not use this file except in compliance with the License.\n", - "# You may obtain a copy of the License at\n", - "#\n", - "# https://www.apache.org/licenses/LICENSE-2.0\n", - "#\n", - "# Unless required by applicable law or agreed to in writing, software\n", - "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", - "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", - "# See the License for the specific language governing permissions and\n", - "# limitations under the License." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "60RdWsg1tETW" - }, - "source": [ - "# 사용자 정의 층" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "BcJg7Enms86w" - }, - "source": [ - "\n", - " \n", - " \n", - " \n", - "
\n", - " TensorFlow.org에서 보기\n", - " \n", - " 구글 코랩(Colab)에서 실행하기\n", - " \n", - " 깃허브(GitHub) 소스 보기\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", - "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", - "이 번역에 개선할 부분이 있다면\n", - "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", - "문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을\n", - "작성하거나\n", - "[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로\n", - "메일을 보내주시기 바랍니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "UEu3q4jmpKVT" - }, - "source": [ - "신경망을 구축하기 위해서 고수준 API인 `tf.keras`를 사용하길 권합니다. 대부분의 텐서플로 API는 즉시 실행(eager execution)과 함께 사용할 수 있습니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "pwX7Fii1rwsJ" - }, - "outputs": [], - "source": [ - "from __future__ import absolute_import, division, print_function, unicode_literals\n", - "\n", - "import tensorflow as tf\n", - "\n", - "tf.enable_eager_execution()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "zSFfVVjkrrsI" - }, - "source": [ - "## 층: 유용한 연산자 집합\n", - "\n", - "머신러닝을 위한 코드를 작성하는 대부분의 경우에 개별적인 연산과 변수를 조작하는 것보다는 높은 수준의 추상화에서 작업할 것입니다.\n", - "\n", - "많은 머신러닝 모델은 비교적 단순한 층(layer)을 조합하고 쌓아서 표현가능합니다. 또한 텐서플로는 여러 표준형 층을 제공하므로 사용자 고유의 응용 프로그램에 관련된 층을 처음부터 작성하거나, 기존 층의 조합으로 쉽게 만들 수 있습니다.\n", - "\n", - "텐서플로는 [전체 케라스](https://keras.io) API를 tf.keras 패키지에 포함하고 있습니다. 케라스 층은 모델을 구축하는데 매우 유용합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "8PyXlPl-4TzQ" - }, - "outputs": [], - "source": [ - "# tf.keras.layers 패키지에서 층은 객체입니다. 층을 구성하려면 간단히 객체를 생성하십시오.\n", - "# 대부분의 layer는 첫번째 인수로 출력 차원(크기) 또는 채널을 취합니다.\n", - "layer = tf.keras.layers.Dense(100)\n", - "# 입력 차원의 수는 층을 처음 실행할 때 유추할 수 있기 때문에 종종 불필요합니다. \n", - "# 일부 복잡한 모델에서는 수동으로 입력 차원의 수를 제공하는것이 유용할 수 있습니다.\n", - "layer = tf.keras.layers.Dense(10, input_shape=(None, 5))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "Fn69xxPO5Psr" - }, - "source": [ - "미리 구성되어있는 층은 다음 [문서](https://www.tensorflow.org/api_docs/python/tf/keras/layers)에서 확인할 수 있습니다. Dense(완전 연결 층), Conv2D, LSTM, BatchNormalization, Dropout, 등을 포함하고 있습니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "E3XKNknP5Mhb" - }, - "outputs": [], - "source": [ - "# 층을 사용하려면, 간단하게 호출합니다.\n", - "layer(tf.zeros([10, 5]))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "Wt_Nsv-L5t2s" - }, - "outputs": [], - "source": [ - "# layer는 유용한 메서드를 많이 가지고 있습니다. 예를 들어, `layer.variables`를 사용하여 층안에 있는 모든 변수를 확인할 수 있으며, \n", - "# `layer.trainable_variables`를 사용하여 훈련가능한 변수를 확인할 수 있습니다. \n", - "# 완전 연결(fully-connected)층은 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", - "layer.variables" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "6ilvKjz8_4MQ" - }, - "outputs": [], - "source": [ - "# 또한 변수는 객체의 속성을 통해 편리하게 접근가능합니다. \n", - "layer.kernel, layer.bias" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "O0kDbE54-5VS" - }, - "source": [ - "## 사용자 정의 층 구현\n", - "사용자 정의 층을 구현하는 가장 좋은 방법은 tf.keras.Layer 클래스를 상속하고 다음과 같이 구현하는 것입니다.\n", - " * `__init__` 에서 층에 필요한 매개변수를 입력 받습니다..\n", - " * `build`, 입력 텐서의 크기를 알고 나머지를 초기화 할 수 있습니다.\n", - " * `call`, 정방향 연산(forward computation)을 진행 할 수 있습니다.\n", - "\n", - "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도 있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 층이 작동할 입력의 크기를 기준으로 나중에 변수를 만들 수 있다는 것입니다. 반면에, `__init__`에 변수를 생성하는 것은 변수 생성에 필요한 크기가 명시적으로 지정되어야 함을 의미합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "5Byl3n1k5kIy" - }, - "outputs": [], - "source": [ - "class MyDenseLayer(tf.keras.layers.Layer):\n", - " def __init__(self, num_outputs):\n", - " super(MyDenseLayer, self).__init__()\n", - " self.num_outputs = num_outputs\n", - " \n", - " def build(self, input_shape):\n", - " self.kernel = self.add_variable(\"kernel\", \n", - " shape=[int(input_shape[-1]), \n", - " self.num_outputs])\n", - " \n", - " def call(self, input):\n", - " return tf.matmul(input, self.kernel)\n", - " \n", - "layer = MyDenseLayer(10)\n", - "print(layer(tf.zeros([10, 5])))\n", - "print(layer.trainable_variables)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "tk8E2vY0-z4Z" - }, - "source": [ - "다른 독자가 표준형 층의 동작을 잘 알고 있기 때문에, 가능한 경우 표준형 층을 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers 또는 tf.contrib.layers에 없는 층을 사용하기 원하면 [깃허브](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀 리퀘스트(pull request)를 보내세요." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "Qhg4KlbKrs3G" - }, - "source": [ - "## 모델: 층 구성\n", - "\n", - "머신러닝 모델에서 대부분의 재미있는 많은 것들은 기존의 층을 조합하여 구현됩니다. 예를 들어, 레스넷(resnet)의 각 잔여 블록(residual block)은 합성곱(convolution), 배치 정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어 있습니다. \n", - "\n", - "다른층을 포함한 모델을 만들기 위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현한 코드입니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "N30DTXiRASlb" - }, - "outputs": [], - "source": [ - "class ResnetIdentityBlock(tf.keras.Model):\n", - " def __init__(self, kernel_size, filters):\n", - " super(ResnetIdentityBlock, self).__init__(name='')\n", - " filters1, filters2, filters3 = filters\n", - "\n", - " self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1))\n", - " self.bn2a = tf.keras.layers.BatchNormalization()\n", - "\n", - " self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same')\n", - " self.bn2b = tf.keras.layers.BatchNormalization()\n", - "\n", - " self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1))\n", - " self.bn2c = tf.keras.layers.BatchNormalization()\n", - "\n", - " def call(self, input_tensor, training=False):\n", - " x = self.conv2a(input_tensor)\n", - " x = self.bn2a(x, training=training)\n", - " x = tf.nn.relu(x)\n", - "\n", - " x = self.conv2b(x)\n", - " x = self.bn2b(x, training=training)\n", - " x = tf.nn.relu(x)\n", - "\n", - " x = self.conv2c(x)\n", - " x = self.bn2c(x, training=training)\n", - "\n", - " x += input_tensor\n", - " return tf.nn.relu(x)\n", - "\n", - " \n", - "block = ResnetIdentityBlock(1, [1, 2, 3])\n", - "print(block(tf.zeros([1, 2, 3, 3])))\n", - "print([x.name for x in block.trainable_variables])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "그러나 대부분의 경우에, 많은 층으로 구성된 모델은 간단하게 연이어 하나의 층으로 호출할 수 있습니다. 이는 tf.keras.Sequential 사용하여 간단한 코드로 구현 가능합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "L9frk7Ur4uvJ" - }, - "outputs": [], - "source": [ - " my_seq = tf.keras.Sequential([tf.keras.layers.Conv2D(1, (1, 1)),\n", - " tf.keras.layers.BatchNormalization(),\n", - " tf.keras.layers.Conv2D(2, 1, \n", - " padding='same'),\n", - " tf.keras.layers.BatchNormalization(),\n", - " tf.keras.layers.Conv2D(3, (1, 1)),\n", - " tf.keras.layers.BatchNormalization()])\n", - "my_seq(tf.zeros([1, 2, 3, 3]))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "c5YwYcnuK-wc" - }, - "source": [ - "# 다음 단계\n", - "\n", - "이제 이전 노트북으로 돌아가서 선형 회귀 예제에 층과 모델을 사용하여 좀 더 나은 구조를 적용할 수 있습니다." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "name": "custom_layers.ipynb", - "private_outputs": true, - "provenance": [], - "toc_visible": true, - "version": "0.3.2" - }, - "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.7.1" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "tDnwEv8FtJm7" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors." + ] + }, + { + "cell_type": "code", + "metadata": { + "cellView": "form", + "colab_type": "code", + "id": "JlknJBWQtKkI", + "colab": {} + }, + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "60RdWsg1tETW" + }, + "source": [ + "# 사용자 정의 층" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "BcJg7Enms86w" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " TensorFlow.org에서 보기\n", + " \n", + " 구글 코랩(Colab)에서 실행하기\n", + " \n", + " 깃허브(GitHub) 소스 보기\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "asCKfd--yH-6", + "colab_type": "text" + }, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", + "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", + "이 번역에 개선할 부분이 있다면\n", + "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", + "문서 번역이나 리뷰에 참여하려면\n", + "[docs-ko@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs-ko)로\n", + "메일을 보내주시기 바랍니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "UEu3q4jmpKVT" + }, + "source": [ + "신경망을 구축하기 위해서 고수준 API인 `tf.keras`를 사용하길 권합니다. 대부분의 텐서플로 API는 즉시 실행(eager execution)과 함께 사용할 수 있습니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "pwX7Fii1rwsJ", + "colab": {} + }, + "source": [ + "from __future__ import absolute_import, division, print_function, unicode_literals\n", + "\n", + "import tensorflow as tf\n", + "\n", + "tf.enable_eager_execution()" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "zSFfVVjkrrsI" + }, + "source": [ + "## 층: 유용한 연산자 집합\n", + "\n", + "머신러닝을 위한 코드를 작성하는 대부분의 경우에 개별적인 연산과 변수를 조작하는 것보다는 높은 수준의 추상화에서 작업할 것입니다.\n", + "\n", + "많은 머신러닝 모델은 비교적 단순한 층(layer)을 조합하고 쌓아서 표현가능합니다. 또한 텐서플로는 여러 표준형 층을 제공하므로 사용자 고유의 응용 프로그램에 관련된 층을 처음부터 작성하거나, 기존 층의 조합으로 쉽게 만들 수 있습니다.\n", + "\n", + "텐서플로는 [전체 케라스](https://keras.io) API를 tf.keras 패키지에 포함하고 있습니다. 케라스 층은 모델을 구축하는데 매우 유용합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "8PyXlPl-4TzQ", + "colab": {} + }, + "source": [ + "# tf.keras.layers 패키지에서 층은 객체입니다. 층을 구성하려면 간단히 객체를 생성하십시오.\n", + "# 대부분의 layer는 첫번째 인수로 출력 차원(크기) 또는 채널을 취합니다.\n", + "layer = tf.keras.layers.Dense(100)\n", + "# 입력 차원의 수는 층을 처음 실행할 때 유추할 수 있기 때문에 종종 불필요합니다. \n", + "# 일부 복잡한 모델에서는 수동으로 입력 차원의 수를 제공하는것이 유용할 수 있습니다.\n", + "layer = tf.keras.layers.Dense(10, input_shape=(None, 5))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Fn69xxPO5Psr" + }, + "source": [ + "미리 구성되어있는 층은 다음 [문서](https://www.tensorflow.org/api_docs/python/tf/keras/layers)에서 확인할 수 있습니다. Dense(완전 연결 층), Conv2D, LSTM, BatchNormalization, Dropout, 등을 포함하고 있습니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "E3XKNknP5Mhb", + "colab": {} + }, + "source": [ + "# 층을 사용하려면, 간단하게 호출합니다.\n", + "layer(tf.zeros([10, 5]))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "Wt_Nsv-L5t2s", + "colab": {} + }, + "source": [ + "# layer는 유용한 메서드를 많이 가지고 있습니다. 예를 들어, `layer.variables`를 사용하여 층안에 있는 모든 변수를 확인할 수 있으며, \n", + "# `layer.trainable_variables`를 사용하여 훈련가능한 변수를 확인할 수 있습니다. \n", + "# 완전 연결(fully-connected)층은 가중치(weight)와 편향(biases)을 위한 변수를 가집니다. \n", + "layer.variables" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "6ilvKjz8_4MQ", + "colab": {} + }, + "source": [ + "# 또한 변수는 객체의 속성을 통해 편리하게 접근가능합니다. \n", + "layer.kernel, layer.bias" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "O0kDbE54-5VS" + }, + "source": [ + "## 사용자 정의 층 구현\n", + "사용자 정의 층을 구현하는 가장 좋은 방법은 tf.keras.Layer 클래스를 상속하고 다음과 같이 구현하는 것입니다.\n", + " * `__init__` 에서 층에 필요한 매개변수를 입력 받습니다..\n", + " * `build`, 입력 텐서의 크기를 알고 나머지를 초기화 할 수 있습니다.\n", + " * `call`, 정방향 연산(forward computation)을 진행 할 수 있습니다.\n", + "\n", + "변수를 생성하기 위해 `build`가 호출되길 기다릴 필요가 없다는 것에 주목하세요. 또한 변수를 `__init__`에 생성할 수도 있습니다. 그러나 `build`에 변수를 생성하는 유리한 점은 층이 작동할 입력의 크기를 기준으로 나중에 변수를 만들 수 있다는 것입니다. 반면에, `__init__`에 변수를 생성하는 것은 변수 생성에 필요한 크기가 명시적으로 지정되어야 함을 의미합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "5Byl3n1k5kIy", + "colab": {} + }, + "source": [ + "class MyDenseLayer(tf.keras.layers.Layer):\n", + " def __init__(self, num_outputs):\n", + " super(MyDenseLayer, self).__init__()\n", + " self.num_outputs = num_outputs\n", + " \n", + " def build(self, input_shape):\n", + " self.kernel = self.add_variable(\"kernel\", \n", + " shape=[int(input_shape[-1]), \n", + " self.num_outputs])\n", + " \n", + " def call(self, input):\n", + " return tf.matmul(input, self.kernel)\n", + " \n", + "layer = MyDenseLayer(10)\n", + "print(layer(tf.zeros([10, 5])))\n", + "print(layer.trainable_variables)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "tk8E2vY0-z4Z" + }, + "source": [ + "다른 독자가 표준형 층의 동작을 잘 알고 있기 때문에, 가능한 경우 표준형 층을 사용하는것이 전체 코드를 읽고 유지하는데 더 쉽습니다. 만약 tf.keras.layers 또는 tf.contrib.layers에 없는 층을 사용하기 원하면 [깃허브](http://github.com/tensorflow/tensorflow/issues/new)에 이슈화하거나, 풀 리퀘스트(pull request)를 보내세요." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Qhg4KlbKrs3G" + }, + "source": [ + "## 모델: 층 구성\n", + "\n", + "머신러닝 모델에서 대부분의 재미있는 많은 것들은 기존의 층을 조합하여 구현됩니다. 예를 들어, 레스넷(resnet)의 각 잔여 블록(residual block)은 합성곱(convolution), 배치 정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어 있습니다. \n", + "\n", + "다른층을 포함한 모델을 만들기 위해 사용하는 메인 클래스는 tf.keras.Model입니다. 다음은 tf.keras.Model을 상속(inheritance)하여 구현한 코드입니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "N30DTXiRASlb", + "colab": {} + }, + "source": [ + "class ResnetIdentityBlock(tf.keras.Model):\n", + " def __init__(self, kernel_size, filters):\n", + " super(ResnetIdentityBlock, self).__init__(name='')\n", + " filters1, filters2, filters3 = filters\n", + "\n", + " self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1))\n", + " self.bn2a = tf.keras.layers.BatchNormalization()\n", + "\n", + " self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same')\n", + " self.bn2b = tf.keras.layers.BatchNormalization()\n", + "\n", + " self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1))\n", + " self.bn2c = tf.keras.layers.BatchNormalization()\n", + "\n", + " def call(self, input_tensor, training=False):\n", + " x = self.conv2a(input_tensor)\n", + " x = self.bn2a(x, training=training)\n", + " x = tf.nn.relu(x)\n", + "\n", + " x = self.conv2b(x)\n", + " x = self.bn2b(x, training=training)\n", + " x = tf.nn.relu(x)\n", + "\n", + " x = self.conv2c(x)\n", + " x = self.bn2c(x, training=training)\n", + "\n", + " x += input_tensor\n", + " return tf.nn.relu(x)\n", + "\n", + " \n", + "block = ResnetIdentityBlock(1, [1, 2, 3])\n", + "print(block(tf.zeros([1, 2, 3, 3])))\n", + "print([x.name for x in block.trainable_variables])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yIbK5EiJyH_W", + "colab_type": "text" + }, + "source": [ + "그러나 대부분의 경우에, 많은 층으로 구성된 모델은 간단하게 연이어 하나의 층으로 호출할 수 있습니다. 이는 tf.keras.Sequential 사용하여 간단한 코드로 구현 가능합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "L9frk7Ur4uvJ", + "colab": {} + }, + "source": [ + " my_seq = tf.keras.Sequential([tf.keras.layers.Conv2D(1, (1, 1)),\n", + " tf.keras.layers.BatchNormalization(),\n", + " tf.keras.layers.Conv2D(2, 1, \n", + " padding='same'),\n", + " tf.keras.layers.BatchNormalization(),\n", + " tf.keras.layers.Conv2D(3, (1, 1)),\n", + " tf.keras.layers.BatchNormalization()])\n", + "my_seq(tf.zeros([1, 2, 3, 3]))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "c5YwYcnuK-wc" + }, + "source": [ + "# 다음 단계\n", + "\n", + "이제 이전 노트북으로 돌아가서 선형 회귀 예제에 층과 모델을 사용하여 좀 더 나은 구조를 적용할 수 있습니다." + ] + } + ] +} \ No newline at end of file diff --git a/site/ko/tutorials/eager/custom_training.ipynb b/site/ko/tutorials/eager/custom_training.ipynb index 8431c372bcf..9fe7243b2f5 100644 --- a/site/ko/tutorials/eager/custom_training.ipynb +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -1,462 +1,470 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "5rmpybwysXGV" - }, - "source": [ - "##### Copyright 2018 The TensorFlow Authors." - ] + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "custom_training.ipynb", + "version": "0.3.2", + "provenance": [], + "private_outputs": true, + "collapsed_sections": [], + "toc_visible": true + }, + "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.7.1" + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "colab": {}, - "colab_type": "code", - "id": "m8y3rGtQsYP2" - }, - "outputs": [], - "source": [ - "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", - "# you may not use this file except in compliance with the License.\n", - "# You may obtain a copy of the License at\n", - "#\n", - "# https://www.apache.org/licenses/LICENSE-2.0\n", - "#\n", - "# Unless required by applicable law or agreed to in writing, software\n", - "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", - "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", - "# See the License for the specific language governing permissions and\n", - "# limitations under the License." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "hrXv0rU9sIma" - }, - "source": [ - "# 사용자 정의 학습: 기초" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "7S0BwJ_8sLu7" - }, - "source": [ - "\n", - " \n", - " \n", - " \n", - "
\n", - " TensorFlow.org에서 보기\n", - " \n", - " 구글 코랩(Colab)에서 실행하기\n", - " \n", - " 깃허브(GitHub) 소스 보기\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", - "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", - "이 번역에 개선할 부분이 있다면\n", - "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", - "문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을\n", - "작성하거나\n", - "[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로\n", - "메일을 보내주시기 바랍니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "k2o3TTG4TFpt" - }, - "source": [ - "이전 튜토리얼에서는 머신러닝을 위한 기본 구성 요소인 자동 미분(automatic differentiation)을 위한 텐서플로 API를 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 텐서플로의 기본 요소를 사용하여 간단한 머신러닝을 수행해보겠습니다. \n", - "\n", - "텐서플로는 반복되는 코드를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 `tf.keras`를 포함하고 있습니다. 신경망을 다룰 때 이러한 고수준의 API을 강하게 추천합니다. 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위해 기본적인 요소만으로 신경망 훈련시켜 보겠습니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "3LXMVuV0VhDr" - }, - "source": [ - "## 설정" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "PJ64L90aVir3" - }, - "outputs": [], - "source": [ - "from __future__ import absolute_import, division, print_function, unicode_literals\n", - "\n", - "import tensorflow as tf\n", - "\n", - "tf.enable_eager_execution()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "eMAWbDJFVmMk" - }, - "source": [ - "## 변수\n", - "\n", - "텐서플로의 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝 모델은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다르게(희망하건대 더 낮은 손실로 가는 방향으로)동작해야 합니다. 이 연산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 명령형 프로그래밍 언어인 파이썬을 사용 할 수 있습니다. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "VkJwtLS_Jbn8" - }, - "outputs": [], - "source": [ - "# 파이썬 구문 사용\n", - "x = tf.zeros([10, 10])\n", - "x += 2 # 이것은 x = x + 2와 같으며, x의 초기값을 변경하지 않습니다.\n", - "print(x)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "wfneTXy7JcUz" - }, - "source": [ - "텐서플로는 상태를 변경할 수 있는 연산자가 내장되어 있으며, 이러한 연산자는 상태를 표현하기 위한 저수준 파이썬 표현보다 사용하기가 더 좋습니다. 예를 들어, 모델에서 가중치를 나타내기 위해서 텐서플로 변수를 사용하는 것이 편하고 효율적입니다. \n", - "\n", - "텐서플로 변수는 값을 저장하는 객체로 텐서플로 연산에 사용될 때 저장된 이 값을 읽어올 것입니다. `tf.assign_sub`, `tf.scatter_update` 등은 텐서플로 변수에 저장되있는 값을 조작하는 연산자입니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "itxmrMil6DQi" - }, - "outputs": [], - "source": [ - "v = tf.Variable(1.0)\n", - "assert v.numpy() == 1.0\n", - "\n", - "# 값을 재배열합니다.\n", - "v.assign(3.0)\n", - "assert v.numpy() == 3.0\n", - "\n", - "# tf.square()와 같은 텐서플로 연산에 `v`를 사용하고 재할당합니다. \n", - "v.assign(tf.square(v))\n", - "assert v.numpy() == 9.0" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "-paSaeq1JzwC" - }, - "source": [ - "변수를 사용한 연산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 기본적으로 희소 텐서(sparse tensor)를 사용하여 업데이트됩니다. 이는 연산과 메모리에 더욱 효율적입니다. \n", - "\n", - "또한 변수를 사용하는 것은 코드를 읽는 독자에게 상태가 변경될 수 있다는 것을 알려주는 손쉬운 방법입니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "BMiFcDzE7Qu3" - }, - "source": [ - "## 예: 선형 모델 훈련\n", - "\n", - "지금까지 몇 가지 개념을 설명했습니다. 간단한 모델을 구축하고 학습시키기 위해 ---`Tensor`, `GradientTape`, `Variable` --- 등을 사용하였고, 이는 일반적으로 다음의 과정을 포함합니다.\n", - "\n", - "1. 모델 정의\n", - "2. 손실 함수 정의\n", - "3. 훈련 데이터 가져오기\n", - "4. 훈련 데이터에서 실행, 데이터에 최적화하기 위해 \"옵티마이저(optimizer)\"를 사용한 변수 조정\n", - "\n", - "이번 튜토리얼에서는 선형 모델의 간단한 예제를 살펴보겠습니다. `f(x) = x * W + b`, 모델은 `W` 와 `b` 두 변수를 가지고 있는 선형모델이며, 잘 학습된 모델이 `W = 3.0` and `b = 2.0`의 값을 갖도록 합성 데이터를 만들겠습니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "gFzH64Jn9PIm" - }, - "source": [ - "### 모델 정의\n", - "\n", - "변수와 연산을 캡슐화하기 위한 간단한 클래스를 정의해봅시다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "_WRu7Pze7wk8" - }, - "outputs": [], - "source": [ - "class Model(object):\n", - " def __init__(self):\n", - " # 변수를 (5.0, 0.0)으로 초기화 합니다.\n", - " # 실제로는 임의의 값으로 초기화 되어야합니다.\n", - " self.W = tf.Variable(5.0)\n", - " self.b = tf.Variable(0.0)\n", - " \n", - " def __call__(self, x):\n", - " return self.W * x + self.b\n", - " \n", - "model = Model()\n", - "\n", - "assert model(3.0).numpy() == 15.0" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "xa6j_yXa-j79" - }, - "source": [ - "### 손실 함수 정의\n", - "\n", - "손실 함수는 주어진 입력에 대한 모델의 출력이 원하는 출력과 얼마나 잘 일치하는지를 측정합니다. 평균 제곱 오차(mean square error)를 적용한 손실 함수를 사용하겠습니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "Y0ysUFGY924U" - }, - "outputs": [], - "source": [ - "def loss(predicted_y, desired_y):\n", - " return tf.reduce_mean(tf.square(predicted_y - desired_y))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "qutT_fkl_CBc" - }, - "source": [ - "### 훈련 데이터 가져오기\n", - "\n", - "약간의 잡음과 훈련 데이터를 합칩니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "gxPTb-kt_N5m" - }, - "outputs": [], - "source": [ - "TRUE_W = 3.0\n", - "TRUE_b = 2.0\n", - "NUM_EXAMPLES = 1000\n", - "\n", - "inputs = tf.random_normal(shape=[NUM_EXAMPLES])\n", - "noise = tf.random_normal(shape=[NUM_EXAMPLES])\n", - "outputs = inputs * TRUE_W + TRUE_b + noise" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "-50nq-wPBsAW" - }, - "source": [ - "모델을 훈련시키기 전에, 모델의 현재 상태를 시각화합시다. 모델의 예측을 빨간색으로, 훈련 데이터를 파란색으로 구성합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "_eb83LtrB4nt" - }, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "plt.scatter(inputs, outputs, c='b')\n", - "plt.scatter(inputs, model(inputs), c='r')\n", - "plt.show()\n", - "\n", - "print('현재 손실: '),\n", - "print(loss(model(inputs), outputs).numpy())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "sSDP-yeq_4jE" - }, - "source": [ - "### 훈련 루프 정의\n", - "\n", - "이제 네트워크와 훈련 데이터가 준비되었습니다. 모델의 변수(`W` 와 `b`)를 업데이트하기 위해 훈련 데이터를 사용하여 훈련시켜 보죠. 그리고 [경사 하강법(gradient descent)](https://en.wikipedia.org/wiki/Gradient_descent)을 사용하여 손실을 감소시킵니다. 경사 하강법에는 여러가지 방법이 있으며, `tf.train.Optimizer` 에 구현되어있습니다. 이러한 구현을 사용하는것을 강력히 추천드립니다. 그러나 이번 튜토리얼에서는 기본적인 방법을 사용하겠습니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "MBIACgdnA55X" - }, - "outputs": [], - "source": [ - "def train(model, inputs, outputs, learning_rate):\n", - " with tf.GradientTape() as t:\n", - " current_loss = loss(model(inputs), outputs)\n", - " dW, db = t.gradient(current_loss, [model.W, model.b])\n", - " model.W.assign_sub(learning_rate * dW)\n", - " model.b.assign_sub(learning_rate * db)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "RwWPaJryD2aN" - }, - "source": [ - "마지막으로, 훈련 데이터를 반복적으로 실행하고, `W` 와 `b`의 변화 과정을 확인합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "XdfkR223D9dW" - }, - "outputs": [], - "source": [ - "model = Model()\n", - "\n", - "# 도식화를 위해 W값과 b값의 변화를 저장합니다.\n", - "Ws, bs = [], []\n", - "epochs = range(10)\n", - "for epoch in epochs:\n", - " Ws.append(model.W.numpy())\n", - " bs.append(model.b.numpy())\n", - " current_loss = loss(model(inputs), outputs)\n", - "\n", - " train(model, inputs, outputs, learning_rate=0.1)\n", - " print('에포크 %2d: W=%1.2f b=%1.2f, 손실=%2.5f' %\n", - " (epoch, Ws[-1], bs[-1], current_loss))\n", - "\n", - "# 저장된 값들을 도식화합니다.\n", - "plt.plot(epochs, Ws, 'r',\n", - " epochs, bs, 'b')\n", - "plt.plot([TRUE_W] * len(epochs), 'r--',\n", - " [TRUE_b] * len(epochs), 'b--')\n", - "plt.legend(['W', 'b', 'true W', 'true_b'])\n", - "plt.show()\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "vPnIVuaSJwWz" - }, - "source": [ - "## 다음 단계\n", - "\n", - "이번 튜토리얼에서는 변수를 다루었으며, 지금까지 논의된 텐서플로의 기본 요소를 사용하여 간단한 선형 모델을 구축하고 훈련시켰습니다.\n", - "\n", - "이론적으로, 텐서플로를 머신러닝 연구에 사용하기 위해 알아야 할 것이 매우 많습니다. 실제로 신경망에 있어 `tf.keras`와 같은 고수준 API는 고수준 구성 요소(\"층\"으로 불리는)를 제공하고, 저장 및 복원을 위한 유틸리티, 손실 함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "name": "Custom training: basics", - "private_outputs": true, - "provenance": [], - "toc_visible": true, - "version": "0.3.2" - }, - "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.7.1" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "5rmpybwysXGV" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors." + ] + }, + { + "cell_type": "code", + "metadata": { + "cellView": "form", + "colab_type": "code", + "id": "m8y3rGtQsYP2", + "colab": {} + }, + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "hrXv0rU9sIma" + }, + "source": [ + "# 사용자 정의 학습: 기초" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "7S0BwJ_8sLu7" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " TensorFlow.org에서 보기\n", + " \n", + " 구글 코랩(Colab)에서 실행하기\n", + " \n", + " 깃허브(GitHub) 소스 보기\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tt0udTybxxwG", + "colab_type": "text" + }, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", + "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", + "이 번역에 개선할 부분이 있다면\n", + "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", + "문서 번역이나 리뷰에 참여하려면\n", + "[docs-ko@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs-ko)로\n", + "메일을 보내주시기 바랍니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "k2o3TTG4TFpt" + }, + "source": [ + "이전 튜토리얼에서는 머신러닝을 위한 기본 구성 요소인 자동 미분(automatic differentiation)을 위한 텐서플로 API를 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 텐서플로의 기본 요소를 사용하여 간단한 머신러닝을 수행해보겠습니다. \n", + "\n", + "텐서플로는 반복되는 코드를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 `tf.keras`를 포함하고 있습니다. 신경망을 다룰 때 이러한 고수준의 API을 강하게 추천합니다. 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위해 기본적인 요소만으로 신경망 훈련시켜 보겠습니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3LXMVuV0VhDr" + }, + "source": [ + "## 설정" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "PJ64L90aVir3", + "colab": {} + }, + "source": [ + "from __future__ import absolute_import, division, print_function, unicode_literals\n", + "\n", + "import tensorflow as tf\n", + "\n", + "tf.enable_eager_execution()" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "eMAWbDJFVmMk" + }, + "source": [ + "## 변수\n", + "\n", + "텐서플로의 텐서(Tensor)는 상태가 없고, 변경이 불가능한(immutable stateless) 객체입니다. 그러나 머신러닝 모델은 상태가 변경될(stateful) 필요가 있습니다. 예를 들어, 모델 학습에서 예측을 계산하기 위한 동일한 코드는 시간이 지남에 따라 다르게(희망하건대 더 낮은 손실로 가는 방향으로)동작해야 합니다. 이 연산 과정을 통해 변화되어야 하는 상태를 표현하기 위해 명령형 프로그래밍 언어인 파이썬을 사용 할 수 있습니다. " + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "VkJwtLS_Jbn8", + "colab": {} + }, + "source": [ + "# 파이썬 구문 사용\n", + "x = tf.zeros([10, 10])\n", + "x += 2 # 이것은 x = x + 2와 같으며, x의 초기값을 변경하지 않습니다.\n", + "print(x)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "wfneTXy7JcUz" + }, + "source": [ + "텐서플로는 상태를 변경할 수 있는 연산자가 내장되어 있으며, 이러한 연산자는 상태를 표현하기 위한 저수준 파이썬 표현보다 사용하기가 더 좋습니다. 예를 들어, 모델에서 가중치를 나타내기 위해서 텐서플로 변수를 사용하는 것이 편하고 효율적입니다. \n", + "\n", + "텐서플로 변수는 값을 저장하는 객체로 텐서플로 연산에 사용될 때 저장된 이 값을 읽어올 것입니다. `tf.assign_sub`, `tf.scatter_update` 등은 텐서플로 변수에 저장되있는 값을 조작하는 연산자입니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "itxmrMil6DQi", + "colab": {} + }, + "source": [ + "v = tf.Variable(1.0)\n", + "assert v.numpy() == 1.0\n", + "\n", + "# 값을 재배열합니다.\n", + "v.assign(3.0)\n", + "assert v.numpy() == 3.0\n", + "\n", + "# tf.square()와 같은 텐서플로 연산에 `v`를 사용하고 재할당합니다. \n", + "v.assign(tf.square(v))\n", + "assert v.numpy() == 9.0" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "-paSaeq1JzwC" + }, + "source": [ + "변수를 사용한 연산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 기본적으로 희소 텐서(sparse tensor)를 사용하여 업데이트됩니다. 이는 연산과 메모리에 더욱 효율적입니다. \n", + "\n", + "또한 변수를 사용하는 것은 코드를 읽는 독자에게 상태가 변경될 수 있다는 것을 알려주는 손쉬운 방법입니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "BMiFcDzE7Qu3" + }, + "source": [ + "## 예: 선형 모델 훈련\n", + "\n", + "지금까지 몇 가지 개념을 설명했습니다. 간단한 모델을 구축하고 학습시키기 위해 ---`Tensor`, `GradientTape`, `Variable` --- 등을 사용하였고, 이는 일반적으로 다음의 과정을 포함합니다.\n", + "\n", + "1. 모델 정의\n", + "2. 손실 함수 정의\n", + "3. 훈련 데이터 가져오기\n", + "4. 훈련 데이터에서 실행, 데이터에 최적화하기 위해 \"옵티마이저(optimizer)\"를 사용한 변수 조정\n", + "\n", + "이번 튜토리얼에서는 선형 모델의 간단한 예제를 살펴보겠습니다. `f(x) = x * W + b`, 모델은 `W` 와 `b` 두 변수를 가지고 있는 선형모델이며, 잘 학습된 모델이 `W = 3.0` and `b = 2.0`의 값을 갖도록 합성 데이터를 만들겠습니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "gFzH64Jn9PIm" + }, + "source": [ + "### 모델 정의\n", + "\n", + "변수와 연산을 캡슐화하기 위한 간단한 클래스를 정의해봅시다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "_WRu7Pze7wk8", + "colab": {} + }, + "source": [ + "class Model(object):\n", + " def __init__(self):\n", + " # 변수를 (5.0, 0.0)으로 초기화 합니다.\n", + " # 실제로는 임의의 값으로 초기화 되어야합니다.\n", + " self.W = tf.Variable(5.0)\n", + " self.b = tf.Variable(0.0)\n", + " \n", + " def __call__(self, x):\n", + " return self.W * x + self.b\n", + " \n", + "model = Model()\n", + "\n", + "assert model(3.0).numpy() == 15.0" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "xa6j_yXa-j79" + }, + "source": [ + "### 손실 함수 정의\n", + "\n", + "손실 함수는 주어진 입력에 대한 모델의 출력이 원하는 출력과 얼마나 잘 일치하는지를 측정합니다. 평균 제곱 오차(mean square error)를 적용한 손실 함수를 사용하겠습니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "Y0ysUFGY924U", + "colab": {} + }, + "source": [ + "def loss(predicted_y, desired_y):\n", + " return tf.reduce_mean(tf.square(predicted_y - desired_y))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "qutT_fkl_CBc" + }, + "source": [ + "### 훈련 데이터 가져오기\n", + "\n", + "약간의 잡음과 훈련 데이터를 합칩니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "gxPTb-kt_N5m", + "colab": {} + }, + "source": [ + "TRUE_W = 3.0\n", + "TRUE_b = 2.0\n", + "NUM_EXAMPLES = 1000\n", + "\n", + "inputs = tf.random_normal(shape=[NUM_EXAMPLES])\n", + "noise = tf.random_normal(shape=[NUM_EXAMPLES])\n", + "outputs = inputs * TRUE_W + TRUE_b + noise" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "-50nq-wPBsAW" + }, + "source": [ + "모델을 훈련시키기 전에, 모델의 현재 상태를 시각화합시다. 모델의 예측을 빨간색으로, 훈련 데이터를 파란색으로 구성합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "_eb83LtrB4nt", + "colab": {} + }, + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "plt.scatter(inputs, outputs, c='b')\n", + "plt.scatter(inputs, model(inputs), c='r')\n", + "plt.show()\n", + "\n", + "print('현재 손실: '),\n", + "print(loss(model(inputs), outputs).numpy())" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "sSDP-yeq_4jE" + }, + "source": [ + "### 훈련 루프 정의\n", + "\n", + "이제 네트워크와 훈련 데이터가 준비되었습니다. 모델의 변수(`W` 와 `b`)를 업데이트하기 위해 훈련 데이터를 사용하여 훈련시켜 보죠. 그리고 [경사 하강법(gradient descent)](https://en.wikipedia.org/wiki/Gradient_descent)을 사용하여 손실을 감소시킵니다. 경사 하강법에는 여러가지 방법이 있으며, `tf.train.Optimizer` 에 구현되어있습니다. 이러한 구현을 사용하는것을 강력히 추천드립니다. 그러나 이번 튜토리얼에서는 기본적인 방법을 사용하겠습니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "MBIACgdnA55X", + "colab": {} + }, + "source": [ + "def train(model, inputs, outputs, learning_rate):\n", + " with tf.GradientTape() as t:\n", + " current_loss = loss(model(inputs), outputs)\n", + " dW, db = t.gradient(current_loss, [model.W, model.b])\n", + " model.W.assign_sub(learning_rate * dW)\n", + " model.b.assign_sub(learning_rate * db)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "RwWPaJryD2aN" + }, + "source": [ + "마지막으로, 훈련 데이터를 반복적으로 실행하고, `W` 와 `b`의 변화 과정을 확인합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "XdfkR223D9dW", + "colab": {} + }, + "source": [ + "model = Model()\n", + "\n", + "# 도식화를 위해 W값과 b값의 변화를 저장합니다.\n", + "Ws, bs = [], []\n", + "epochs = range(10)\n", + "for epoch in epochs:\n", + " Ws.append(model.W.numpy())\n", + " bs.append(model.b.numpy())\n", + " current_loss = loss(model(inputs), outputs)\n", + "\n", + " train(model, inputs, outputs, learning_rate=0.1)\n", + " print('에포크 %2d: W=%1.2f b=%1.2f, 손실=%2.5f' %\n", + " (epoch, Ws[-1], bs[-1], current_loss))\n", + "\n", + "# 저장된 값들을 도식화합니다.\n", + "plt.plot(epochs, Ws, 'r',\n", + " epochs, bs, 'b')\n", + "plt.plot([TRUE_W] * len(epochs), 'r--',\n", + " [TRUE_b] * len(epochs), 'b--')\n", + "plt.legend(['W', 'b', 'true W', 'true_b'])\n", + "plt.show()\n", + " " + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "vPnIVuaSJwWz" + }, + "source": [ + "## 다음 단계\n", + "\n", + "이번 튜토리얼에서는 변수를 다루었으며, 지금까지 논의된 텐서플로의 기본 요소를 사용하여 간단한 선형 모델을 구축하고 훈련시켰습니다.\n", + "\n", + "이론적으로, 텐서플로를 머신러닝 연구에 사용하기 위해 알아야 할 것이 매우 많습니다. 실제로 신경망에 있어 `tf.keras`와 같은 고수준 API는 고수준 구성 요소(\"층\"으로 불리는)를 제공하고, 저장 및 복원을 위한 유틸리티, 손실 함수 모음, 최적화 전략 모음 등을 제공하기 때문에 더욱 편리합니다. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6uk4j3tSxxwq", + "colab_type": "code", + "colab": {} + }, + "source": [ + "" + ], + "execution_count": 0, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb index 8f42dd20700..a92ea88a33d 100644 --- a/site/ko/tutorials/eager/custom_training_walkthrough.ipynb +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -1,1118 +1,1120 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "rwxGnsA92emp" - }, - "source": [ - "##### Copyright 2018 The TensorFlow Authors." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "colab": {}, - "colab_type": "code", - "id": "CPII1rGR2rF9" - }, - "outputs": [], - "source": [ - "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", - "# you may not use this file except in compliance with the License.\n", - "# You may obtain a copy of the License at\n", - "#\n", - "# https://www.apache.org/licenses/LICENSE-2.0\n", - "#\n", - "# Unless required by applicable law or agreed to in writing, software\n", - "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", - "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", - "# See the License for the specific language governing permissions and\n", - "# limitations under the License." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "JtEZ1pCPn--z" - }, - "source": [ - "# 사용자 정의 학습: 자세히 둘러보기" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "GV1F7tVTN3Dn" - }, - "source": [ - "\n", - " \n", - " \n", - " \n", - "
\n", - " TensorFlow.org에서 보기\n", - " \n", - " 구글 코랩(Colab)에서 실행하기\n", - " \n", - " 깃허브(GitHub) 소스 보기\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", - "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", - "이 번역에 개선할 부분이 있다면\n", - "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", - "문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을\n", - "작성하거나\n", - "[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로\n", - "메일을 보내주시기 바랍니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "LDrzLFXE8T1l" - }, - "source": [ - "이번 튜토리얼은 붓꽃의 품종을 분류하기 위한 머신러닝 모델을 구축할 것입니다. 다음을 위해 즉시 실행[(eager execution)](https://www.tensorflow.org/guide/eager)을 사용합니다.\n", - "1. 모델 구축\n", - "2. 모델 훈련\n", - "3. 예측을 위한 모델 사용\n", - "\n", - "## 텐서플로 프로그래밍\n", - "\n", - "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로의 개념을 사용합니다.\n", - "\n", - "* [즉시 실행(eager execution)](https://www.tensorflow.org/guide/eager) 개발 환경,\n", - "* [데이터셋 API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 가져오기,\n", - "* [케라스 API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 층(layer) 구축 .\n", - "\n", - "이번 튜토리얼은 다른 텐서플로 프로그램과 유사하게 구성되어있습니다.\n", - "\n", - "1. 데이터 가져오기 및 분석.\n", - "2. 모델 타입 선정.\n", - "3. 모델 훈련.\n", - "4. 모델 효과 평가.\n", - "5. 예측을 위한 훈련된 모델 사용." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "yNr7H-AIoLOR" - }, - "source": [ - "## 프로그램 설정" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "1J3AuPBT9gyR" - }, - "source": [ - "### 임포트 및 즉시 실행 구성\n", - "\n", - "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화합니다. 즉시 실행은 텐서플로 연산이 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게 합니다. 만약 파이썬 대화형 창이나 상호작용 콘솔을 사용하시면 더욱 익숙할 겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용 가능합니다.\n", - "\n", - "즉시 실행이 활성화될 때, 동일한 프로그램내에서 비활성화 할 수 없습니다. 더 많은 세부사항은 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 참조하세요." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "g4Wzg69bnwK2" - }, - "outputs": [], - "source": [ - "from __future__ import absolute_import, division, print_function, unicode_literals\n", - "\n", - "import os\n", - "import matplotlib.pyplot as plt\n", - "\n", - "import tensorflow as tf\n", - "\n", - "tf.enable_eager_execution()\n", - "\n", - "print(\"텐서플로 버전: {}\".format(tf.__version__))\n", - "print(\"즉시 실행: {}\".format(tf.executing_eagerly()))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "Zx7wc0LuuxaJ" - }, - "source": [ - "## 붓꽃 분류 문제\n", - "\n", - "당신이 식물학자라고 상상하고, 주어진 붓꽃을 자동적으로 분류하는 방법을 찾고 있다고 가정합시다. 머신러닝은 통계적으로 꽃을 분류할 수 있는 다양한 알고리즘을 제공합니다. 예를 들어, 정교한 머신러닝 프로그램은 사진을 통해 꽃을 분류할 수 있습니다. 이번 튜토리얼의 목적은 좀 더 겸손하게, 측정된 [꽃받침](https://en.wikipedia.org/wiki/Sepal)과 [꽃잎](https://en.wikipedia.org/wiki/Petal)의 길이와 폭을 토대로 붓꽃을 분류하는 것입니다.\n", - "\n", - "이 붓꽃은 약 300종입니다. 하지만 이번 튜토리얼에서는 오직 3가지 품종을 기준으로 분류할 것입니다. \n", - "\n", - "* Iris setosa\n", - "* Iris virginica\n", - "* Iris versicolor\n", - "\n", - "\n", - " \n", - " \n", - "
\n", - " \"Petal\n", - "
\n", - " 그림 1. Iris setosa (by Radomil, CC BY-SA 3.0), Iris versicolor, (by Dlanglois, CC BY-SA 3.0), and Iris virginica (by Frank Mayfield, CC BY-SA 2.0).
 \n", - "
\n", - "\n", - "다행히도 다른 사람들이 먼저 꽃받침과 꽃잎의 길이와 폭이 측정된 [120개의 붓꽃 데이터](https://en.wikipedia.org/wiki/Iris_flower_data_set)를 만들어 놓았습니다. 이것은 머신러닝 분류 문제에 있어 초보자에게 유명한 고전 데이터셋입니다. " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "3Px6KAg0Jowz" - }, - "source": [ - "## 훈련 데이터 가져오기 및 파싱\n", - "\n", - "데이터를 불러오고 파이썬 프로그램이 사용할 수 있는 구조로 전환합니다.\n", - "\n", - "### 데이터셋 다운로드\n", - "\n", - "[tf.keras.utils.get_file](https://www.tensorflow.org/api_docs/python/tf/keras/utils/get_file) 함수를 사용하여 데이터셋을 다운로드합니다. 이 함수는 다운로드된 파일의 경로를 반환합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "J6c7uEU9rjRM" - }, - "outputs": [], - "source": [ - "train_dataset_url = \"https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv\"\n", - "\n", - "train_dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(train_dataset_url),\n", - " origin=train_dataset_url)\n", - "\n", - "print(\"데이터셋이 복사된 위치: {}\".format(train_dataset_fp))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "qnX1-aLors4S" - }, - "source": [ - "### 데이터 탐색\n", - "\n", - "이 데이터셋(`iris_training.csv`)은 콤마 ','로 구분된 CSV 파일입니다. `head -n5` 명령을 사용하여 처음 5개 항목을 확인합니다. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "FQvb_JYdrpPm" - }, - "outputs": [], - "source": [ - "!head -n5 {train_dataset_fp}" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "kQhzD6P-uBoq" - }, - "source": [ - "처음 5개의 데이터로부터 다음을 주목하세요.\n", - "\n", - "1. 첫 번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", - " * 총 120개의 샘플이 있으며, 각 샘플들은 4개의 특성(feature), 3개의 레이블(label)을 가지고 있습니다.\n", - "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[샘플](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", - " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 샘플의 특징을 나타냅니다. 이 필드들는 붓꽃의 측정값을 부동소수점으로 나타냅니다.\n", - " * 마지막 컬럼(column)은 *[레이블(label)](https://developers.google.com/machine-learning/glossary/#label)*입니다.: 레이블은 예측하고자 하는 값을 나타냅니다. 이 데이터셋에서는 꽃의 이름과 관련된 정수값 0, 1, 2를 나타냅니다.\n", - "\n", - "코드로 표현하면 다음과 같습니다.:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "9Edhevw7exl6" - }, - "outputs": [], - "source": [ - "# CSV 파일안에서 컬럼의 순서\n", - "column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']\n", - "\n", - "feature_names = column_names[:-1]\n", - "label_name = column_names[-1]\n", - "\n", - "print(\"특성: {}\".format(feature_names))\n", - "print(\"레이블: {}\".format(label_name))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "CCtwLoJhhDNc" - }, - "source": [ - "각각의 레이블은 \"setosa\"와 같은 문자형 이름과 연관되어있습니다. 하지만 머신러닝은 전형적으로 숫자형 값에 의존합니다. 레이블을 다음과 같이 맵핑(mapping) 합니다. \n", - "\n", - "* `0`: Iris setosa\n", - "* `1`: Iris versicolor\n", - "* `2`: Iris virginica\n", - "\n", - "특성과 레이블에 관한 더 많은 정보를 위해서는 [머신러닝 특강의 전문용어 부분](https://developers.google.com/machine-learning/crash-course/framing/ml-terminology)을 참조하세요." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "sVNlJlUOhkoX" - }, - "outputs": [], - "source": [ - "class_names = ['Iris setosa', 'Iris versicolor', 'Iris virginica']" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "dqPkQExM2Pwt" - }, - "source": [ - "### `tf.data.Dataset` 생성\n", - "\n", - "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 적재할 때 발생하는 다양한 경우를 다룰 수 있습니다. 이는 훈련에 필요한 형태로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 [데이터셋 빠른 실행 가이드](https://www.tensorflow.org/get_started/datasets_quickstart)를 참조하세요. \n", - "\n", - "\n", - "데이터셋이 CSV 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련 모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 [배치 사이즈(batch_size)](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "WsxHnz1ebJ2S" - }, - "outputs": [], - "source": [ - "batch_size = 32\n", - "\n", - "train_dataset = tf.contrib.data.make_csv_dataset(\n", - " train_dataset_fp,\n", - " batch_size, \n", - " column_names=column_names,\n", - " label_name=label_name,\n", - " num_epochs=1)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "gB_RSn62c-3G" - }, - "source": [ - "`make_csv_dataset` 함수는 `(features, label)` 쌍으로 구성된 `tf.data.Dataset`을 반환합니다. `features`는 딕셔너리 객체인: `{'feature_name': value}`로 주어집니다.\n", - "또한 즉시 실행 활성화로 이 `Dataset`은 반복가능합니다. 다음은 특성(feature)을 살펴봅시다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "iDuG94H-C122" - }, - "outputs": [], - "source": [ - "features, labels = next(iter(train_dataset))\n", - "\n", - "features" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "E63mArnQaAGz" - }, - "source": [ - "유사한 특성의 값은 같이 그룹 되어있거나, *배치* 돼있다는 사실에 주목하세요. 각 샘플 행의 필드는 해당 특성 배열에 추가됩니다. `batch_size`를 조절하여 이 특성 배열에 저장된 샘플의 수를 설정하세요.\n", - "\n", - "또한 배치(batch)로부터 약간의 특성을 도식화하여 군집돼있는 데이터를 확인할 수 있습니다. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "me5Wn-9FcyyO" - }, - "outputs": [], - "source": [ - "plt.scatter(features['petal_length'].numpy(),\n", - " features['sepal_length'].numpy(),\n", - " c=labels.numpy(),\n", - " cmap='viridis')\n", - "\n", - "plt.xlabel(\"petal length\")\n", - "plt.ylabel(\"sepal length\");" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "YlxpSyHlhT6M" - }, - "source": [ - "모델 구축 단계를 단순화하기 위해, 특성 딕셔너리를 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", - "\n", - "이 함수는 텐서의 리스트(list)로부터 값을 취하고 특정한 차원으로 결합된 텐서를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메서드(method)를 사용합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "jm932WINcaGU" - }, - "outputs": [], - "source": [ - "def pack_features_vector(features, labels):\n", - " \"\"\"Pack the features into a single array.\"\"\"\n", - " features = tf.stack(list(features.values()), axis=1)\n", - " return features, labels" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "V1Vuph_eDl8x" - }, - "source": [ - "그 후 각 `(features,label)`쌍의 특성을 훈련 데이터셋에 쌓기위해 [tf.data.Dataset.map](https://www.tensorflow.org/api_docs/python/tf/data/dataset/map) 메서드를 사용합니다. " - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "ZbDkzGZIkpXf" - }, - "outputs": [], - "source": [ - "train_dataset = train_dataset.map(pack_features_vector)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "NLy0Q1xCldVO" - }, - "source": [ - "데이터셋의 특성 요소는 이제 형태가 `(batch_size, num_features)`인 배열입니다. 첫 5개행의 샘플을 살펴봅시다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "kex9ibEek6Tr" - }, - "outputs": [], - "source": [ - "features, labels = next(iter(train_dataset))\n", - "\n", - "print(features[:5])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "LsaVrtNM3Tx5" - }, - "source": [ - "## 모델 타입 선정\n", - "\n", - "### 왜 모델을 사용해야하는가?\n", - "\n", - " *[모델](https://developers.google.com/machine-learning/crash-course/glossary#model)*은 특성(feature)과 레이블(label) 과의 관계입니다. 붓꽃 분류 문제에서 모델은 측정된 꽃받침과 꽃잎 사이의 관계를 정의하고 붓꽃의 품종을 예측합니다. 몇 가지 간단한 모델은 몇 줄의 대수학으로 표현할 수 있으나, 복잡한 머신러닝 모델은 요약하기 힘든 굉장히 많은 수의 매개변수를 가지고 있습니다.\n", - "\n", - "머신러닝을 사용하지 않고 4가지의 특성 사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을 정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 사용자를 위한 모델을 결정합니다. 만약 충분히 좋은 샘플을 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 사용자를 위한 특성 간의 관계를 이해하고 제공합니다. \n", - "\n", - "### 모델 선정\n", - "\n", - "이제 학습을 위한 모델의 종류를 선정해야합니다. 여러 종류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*으로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[밀집(dense) 또는 완전 연결 신경망(fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전 연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전 연결 신경망입니다. \n", - "\n", - "\n", - " \n", - " \n", - "
\n", - " \n", - "
\n", - " 그림 2. A neural network with features, hidden layers, and predictions.
 \n", - "
\n", - "\n", - "그림 2의 모델이 훈련된 다음 레이블 되어있지 않은 데이터를 제공했을때, 모델은 주어진 데이터의 3가지(주어진 레이블의 개수) 예측을 출력합니다. 이러한 예측은 *[추론(inference)](https://developers.google.com/machine-learning/crash-course/glossary#inference)*이라고 불립니다. 이 샘플에서 출력의 합은 1.0입니다. 그림 2에서 예측은 *Iris setosa* `0.02`, *Iris versicolor* `0.95`, *Iris virginica*에 `0.03`로 주어집니다. 이는 모델이 95%의 확률로 주어진 데이터를 *Iris versicolor*로 예측한다는 것을 의미합니다. " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "W23DIMVPQEBt" - }, - "source": [ - "### 케라스를 사용한 모델 생성\n", - "\n", - "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 층을 생성하기 위한 풍부한 라이브러리를 제공합니다. 케라스가 구성 요소를 연결하기 위한 복잡함을 모두 처리해 주기 때문에 모델을 구축하고 실험하는 것이 쉽습니다.\n", - "\n", - "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 여러 층을 연이어 쌓은 모델입니다. 이 구조는 층의 인스턴스를 취하며, 아래의 경우 각 층당 10개의 노드(node)를 가지는 2개의 [Dense(완전 연결 층)](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)과 3개의 예측(레이블의 수) 노드를 가지는 출력 층으로 구성되어있습니다. 첫 번째 층의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "2fZ6oL2ig3ZK" - }, - "outputs": [], - "source": [ - "model = tf.keras.Sequential([\n", - " tf.keras.layers.Dense(10, activation=tf.nn.relu, input_shape=(4,)), # input shape required\n", - " tf.keras.layers.Dense(10, activation=tf.nn.relu),\n", - " tf.keras.layers.Dense(3)\n", - "])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "FHcbEzMpxbHL" - }, - "source": [ - "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 층에서 출력의 크기를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 하나의 층과 동일하다고 생각할 수 있습니다. 사용 가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", - "\n", - "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 의해 좌우됩니다. 머신러닝의 여러 측면과 마찬가지로, 최적의 신경망 타입을 결정하는 것은 많은 경험과 지식이 필요합니다. 경험을 토대로 보면 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "2wFKnhWCpDSS" - }, - "source": [ - "### 모델 사용\n", - "\n", - "이 모델이 특성의 배치에 대해 수행하는 작업을 간단히 살펴봅시다. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "xe6SQ5NrpB-I" - }, - "outputs": [], - "source": [ - "predictions = model(features)\n", - "predictions[:5]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "wxyXOhwVr5S3" - }, - "source": [ - "각 샘플은 각 클래스에 대한 [로짓(logit)](https://developers.google.com/machine-learning/crash-course/glossary#logits)을 반환합니다. \n", - "\n", - "이 로짓(logit)을 각 클래스에 대한 확률로 변환하기 위하서 [소프트맥스(softmax)](https://developers.google.com/machine-learning/crash-course/glossary#softmax) 함수를 사용하겠습니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "_tRwHZmTNTX2" - }, - "outputs": [], - "source": [ - "tf.nn.softmax(predictions[:5])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "uRZmchElo481" - }, - "source": [ - "`tf.argmax`는 예측된 값 중 가장 큰 확률(원하는 클래스)을 반환합니다. 하지만 모델이 아직 훈련되지 않았으므로 이는 좋은 예측이 아닙니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "-Jzm_GoErz8B" - }, - "outputs": [], - "source": [ - "print(\"예측: {}\".format(tf.argmax(predictions, axis=1)))\n", - "print(\" 레이블: {}\".format(labels))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "Vzq2E5J2QMtw" - }, - "source": [ - "## 모델 훈련하기\n", - "\n", - "*[훈련 단계](https://developers.google.com/machine-learning/crash-course/glossary#training)*는 모델이 점진적으로 최적화되거나 데이터셋을 학습하는 머신러닝의 과정입니다. 훈련의 목적은 미지의 데이터를 예측하기 위해, 훈련 데이터셋의 구조에 대해서 충분히 학습하는 것입니다. 만약 모델이 훈련 데이터셋에 대해서 과하게 학습된다면 오직 훈련 데이터셋에 대해서 작동할 것이며, 일반화되기 힘들 것입니다. 이러한 문제를 *[과대적합(overfitting)](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)* 이라고 합니다. 이는 마치 문제를 이해하고 해결한다기보다는 답을 기억하는 것이라고 생각할 수 있습니다. \n", - "\n", - "붓꽃 분류 문제는 *[지도 학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시 중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도 학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고 있지 않습니다. 대신에 모델은 특성 간의 패턴을 찾습니다. " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "RaKp8aEjKX6B" - }, - "source": [ - "### 손실 함수와 그래디언트 함수 정의하기\n", - "\n", - "훈련과 평가단계에서 모델의 *[손실(loss)](https://developers.google.com/machine-learning/crash-course/glossary#loss)*을 계산해야 합니다. 손실은 모델의 예측이 원하는 레이블과 얼마나 일치하는지, 또한 모델이 잘 작동하는지에 대한 척도로 사용됩니다. 이 값을 최소화하고, 최적화 해야합니다.\n", - "\n", - "모델의 손실은 [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) 함수를 사용해 계산할 것입니다. 이 함수는 모델의 클래스(레이블)과 예측된 값(로짓)을 입력받아 샘플의 평균 손실을 반환합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "tMAT4DcMPwI-" - }, - "outputs": [], - "source": [ - "def loss(model, x, y):\n", - " y_ = model(x)\n", - " return tf.losses.sparse_softmax_cross_entropy(labels=y, logits=y_)\n", - "\n", - "\n", - "l = loss(model, features, labels)\n", - "print(\"손실 테스트: {}\".format(l))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "3IcPqA24QM6B" - }, - "source": [ - "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)*를 계산하기 위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 확인하세요. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "x57HcKWhKkei" - }, - "outputs": [], - "source": [ - "def grad(model, inputs, targets):\n", - " with tf.GradientTape() as tape:\n", - " loss_value = loss(model, inputs, targets)\n", - " return loss_value, tape.gradient(loss_value, model.trainable_variables)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "lOxFimtlKruu" - }, - "source": [ - "### 옵티마이저 생성 \n", - "\n", - "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 손실 함수를 최소화하기 위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실 함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 이 함수의 최저점을 찾고자 합니다. 그래디언트는 가장 가파른 상승 방향을 가리키며 따라서 반대 방향으로 이동하는 여행을 합니다. 각 배치마다의 손실과 기울기를 반복적으로 계산하여 훈련과정 동안 모델을 조정합니다. 점진적으로, 모델은 손실을 최소화하기 위해 가중치(weight)와 편향(bias)의 최적의 조합을 찾아냅니다. 손실이 낮을수록 더 좋은 모델의 예측을 기대할 수 있습니다.\n", - "\n", - "\n", - " \n", - " \n", - "
\n", - " \"Optimization\n", - "
\n", - " 그림 3. 3차원 공간에 대한 최적화 알고리즘 시각화.
(Source: Stanford class CS231n, MIT License, Image credit: Alec Radford)\n", - "
\n", - "\n", - "텐서플로는 훈련을 위해 사용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 경사 하강법(stochastic gradient descent, SGD)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현한 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. `learning_rate`은 경사하강 과정의 크기를 나타내는 매개변수이며, 더 나은 결과를 위해 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "XkUd6UiZa_dF" - }, - "source": [ - "옵티마이저(optimizer)와 `global_step`을 설정합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "8xxi2NNGKwG_" - }, - "outputs": [], - "source": [ - "optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)\n", - "\n", - "global_step = tf.contrib.eager.Variable(0)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "pJVRZ0hP52ZB" - }, - "source": [ - "이 값들을 단일 최적화 단계를 계산하기 위해 사용합니다. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "rxRNTFVe56RG" - }, - "outputs": [], - "source": [ - "loss_value, grads = grad(model, features, labels)\n", - "\n", - "print(\"단계: {}, 초기 손실: {}\".format(global_step.numpy(),\n", - " loss_value.numpy()))\n", - "\n", - "optimizer.apply_gradients(zip(grads, model.trainable_variables), global_step)\n", - "\n", - "print(\"단계: {}, 손실: {}\".format(global_step.numpy(),\n", - " loss(model, features, labels).numpy()))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "7Y2VSELvwAvW" - }, - "source": [ - "### 훈련 루프\n", - "\n", - "모든 사항이 갖춰졌으므로 모델을 훈련할 준비가 되었습니다! 훈련 루프는 더 좋은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 아래의 훈련 단계를 작성한 것입니다. \n", - "\n", - "1. 각 *에포크(epoch)* 반복. 에포크는 데이터셋을 통과시키는 횟수입니다. \n", - "2. 에포크 내에서, *특성* (`x`)와 *레이블* (`y`)가 포함된 훈련 `데이터셋`에 있는 샘플을 반복합니다.\n", - "3. 샘플의 특성을 사용하여 결과를 예측 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기 위해 사용합니다. \n", - "4. 모델의 변수를 업데이트하기 위해 `옵티마이저`를 사용합니다. \n", - "5. 시각화를 위해 몇가지 값들을 저장합니다.\n", - "6. 각 에포크를 반복합니다.\n", - "\n", - "`num_epochs` 변수는 데이터셋의 반복 횟수입니다. 직관과는 반대로, 모델을 길게 학습하는 것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는 것은 많은 경험과 직관을 필요로 합니다. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "AIgulGRUhpto" - }, - "outputs": [], - "source": [ - "## Note: 이 셀을 다시 실행하면 동일한 모델의 변수가 사용됩니다.\n", - "\n", - "from tensorflow import contrib\n", - "tfe = contrib.eager\n", - "\n", - "# 도식화를 위해 결과를 저장합니다.\n", - "train_loss_results = []\n", - "train_accuracy_results = []\n", - "\n", - "num_epochs = 201\n", - "\n", - "for epoch in range(num_epochs):\n", - " epoch_loss_avg = tfe.metrics.Mean()\n", - " epoch_accuracy = tfe.metrics.Accuracy()\n", - "\n", - " # 훈련 루프 - 32개의 배치를 사용합니다.\n", - " for x, y in train_dataset:\n", - " # 모델을 최적화합니다.\n", - " loss_value, grads = grad(model, x, y)\n", - " optimizer.apply_gradients(zip(grads, model.trainable_variables),\n", - " global_step)\n", - "\n", - " # 진행 상황을 추적합니다.\n", - " epoch_loss_avg(loss_value) # 현재 배치 손실을 추가합니다.\n", - " # 예측된 레이블과 실제 레이블 비교합니다.\n", - " epoch_accuracy(tf.argmax(model(x), axis=1, output_type=tf.int32), y)\n", - "\n", - " # epoch 종료\n", - " train_loss_results.append(epoch_loss_avg.result())\n", - " train_accuracy_results.append(epoch_accuracy.result())\n", - " \n", - " if epoch % 50 == 0:\n", - " print(\"에포크 {:03d}: 손실: {:.3f}, 정확도: {:.3%}\".format(epoch, \n", - " epoch_loss_avg.result(), \n", - " epoch_accuracy.result()))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "2FQHVUnm_rjw" - }, - "source": [ - "### 시간에 따른 손실함수 시각화" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "j3wdbmtLVTyr" - }, - "source": [ - "모델의 훈련 과정을 출력하는 것도 도움이 되지만, 훈련 과정을 직접 보는 것이 더 도움이 되곤합니다. [텐서보드(tensorboard)](https://www.tensorflow.org/guide/summaries_and_tensorboard)는 텐서플로에 패키지 되어있는 굉장히 유용한 시각화 툴입니다. 하지만 `matplotlib` 모듈을 사용하여 일반적인 도표를 출력할 수 있습니다.\n", - "\n", - "이 도표를 해석하는 것은 여러 경험이 필요하지만, 결국 모델을 최적화하기 위해 *손실*이 내려가고 *정확도*가 올라가는 것을 원합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "agjvNd2iUGFn" - }, - "outputs": [], - "source": [ - "fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))\n", - "fig.suptitle('Training Metrics')\n", - "\n", - "axes[0].set_ylabel(\"loss\", fontsize=14)\n", - "axes[0].plot(train_loss_results)\n", - "\n", - "axes[1].set_ylabel(\"Accuracy\", fontsize=14)\n", - "axes[1].set_xlabel(\"epoch\", fontsize=14)\n", - "axes[1].plot(train_accuracy_results);" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "Zg8GoMZhLpGH" - }, - "source": [ - "## 모델 유효성 평가\n", - "\n", - "이제 모델은 훈련되었습니다. 모델의 성능에 대한 몇가지 통계를 얻을 수 있습니다. \n", - "\n", - "*평가(Evaluating)*는 모델이 예측을 얼마나 효과적으로 수행하는지 결정하는 것을 의미합니다. 붓꽃 분류 모델의 유효성을 결정하기 위해, 몇가지 꽃잎과 꽃받침 데이터를 통과시키고 어떠한 품종을 예측하는지 확인합니다. 그 후 실제 품종과 비교합니다. 예를 들어, 절반의 데이터를 올바르게 예측한 모델의 *[정확도](https://developers.google.com/machine-learning/glossary/#accuracy)* 는 `0.5`입니다. 그림 4는 조금 더 효과적인 모델입니다. 5개의 예측 중 4개를 올바르게 예측하여 80% 정확도를 냅니다.\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
샘플 특성레이블모델 예측
5.93.04.31.511
6.93.15.42.122
5.13.31.70.500
6.0 3.4 4.5 1.6 12
5.52.54.01.311
\n", - " 그림 4. 80% 정확도 붓꽃 분류기.
 \n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "z-EvK7hGL0d8" - }, - "source": [ - "### 테스트 데이터 세트 설정\n", - "\n", - "모델을 평가하는 것은 모델을 훈련하는 것과 유사합니다. 가장 큰 차이는 훈련 데이터가 아닌 *[테스트 데이터 세트](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* 를 사용했다는 것입니다. 공정하게 모델의 유효성을 평가하기 위해, 모델을 평가하기 위한 샘플은 반드시 훈련 데이터와 달라야합니다. \n", - "\n", - "테스트 데이터 세트를 설정하는 것은 훈련 데이터 세트를 설정하는 것과 유사합니다. CSV 파일을 다운로드하고 값을 파싱합니다. 그 후 셔플은 적용하지 않습니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "Ps3_9dJ3Lodk" - }, - "outputs": [], - "source": [ - "test_url = \"https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv\"\n", - "\n", - "test_fp = tf.keras.utils.get_file(fname=os.path.basename(test_url),\n", - " origin=test_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "SRMWCu30bnxH" - }, - "outputs": [], - "source": [ - "test_dataset = tf.contrib.data.make_csv_dataset(\n", - " test_fp,\n", - " batch_size, \n", - " column_names=column_names,\n", - " label_name='species',\n", - " num_epochs=1,\n", - " shuffle=False)\n", - "\n", - "test_dataset = test_dataset.map(pack_features_vector)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "HFuOKXJdMAdm" - }, - "source": [ - "### 테스트 데이터 세트를 사용한 모델 평가\n", - "\n", - "훈련 단계와는 다르게 모델은 테스트 데이터에 대해서 오직 한 번의 [에포크](https://developers.google.com/machine-learning/glossary/#epoch)를 진행합니다. 다음의 코드 셀은 테스트 셋에 있는 샘플에 대해 실행하고 실제 레이블과 비교합니다. 이는 전체 테스트 데이터 세트에 대한 정확도를 측정하는데 사용됩니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "Tw03-MK1cYId" - }, - "outputs": [], - "source": [ - "test_accuracy = tfe.metrics.Accuracy()\n", - "\n", - "for (x, y) in test_dataset:\n", - " logits = model(x)\n", - " prediction = tf.argmax(logits, axis=1, output_type=tf.int32)\n", - " test_accuracy(prediction, y)\n", - "\n", - "print(\"테스트 세트 정확도: {:.3%}\".format(test_accuracy.result()))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "HcKEZMtCOeK-" - }, - "source": [ - "마지막 배치에서 모델이 올바르게 예측한 것을 확인할 수 있습니다. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "uNwt2eMeOane" - }, - "outputs": [], - "source": [ - "tf.stack([y,prediction],axis=1)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "7Li2r1tYvW7S" - }, - "source": [ - "## 훈련된 모델로 예측하기\n", - "\n", - "이제 붓꽃을 분류하기 위해 완벽하지는 않지만 어느 정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)를 예측해봅시다.\n", - "\n", - "실제로는 레이블 되지 않은 샘플들은 여러 소스(앱, CSV 파일, 직접 제공 등)로부터 제공될 수 있습니다. 지금은 레이블을 예측하기 위해 수동으로 3개의 레이블 되지 않은 샘플을 제공하겠습니다. 레이블은 다음과 같은 붓꽃 이름으로 매핑되어있습니다.\n", - "* `0`: Iris setosa\n", - "* `1`: Iris versicolor\n", - "* `2`: Iris virginica" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "kesTS5Lzv-M2" - }, - "outputs": [], - "source": [ - "predict_dataset = tf.convert_to_tensor([\n", - " [5.1, 3.3, 1.7, 0.5,],\n", - " [5.9, 3.0, 4.2, 1.5,],\n", - " [6.9, 3.1, 5.4, 2.1]\n", - "])\n", - "\n", - "predictions = model(predict_dataset)\n", - "\n", - "for i, logits in enumerate(predictions):\n", - " class_idx = tf.argmax(logits).numpy()\n", - " p = tf.nn.softmax(logits)[class_idx]\n", - " name = class_names[class_idx]\n", - " print(\"예 {} 예측: {} ({:4.1f}%)\".format(i, name, 100*p))" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "name": "custom_training_walkthrough", - "private_outputs": true, - "provenance": [], - "toc_visible": true, - "version": "0.3.2" - }, - "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.7.1" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "custom_training_walkthrough", + "version": "0.3.2", + "provenance": [], + "private_outputs": true, + "collapsed_sections": [], + "toc_visible": true + }, + "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.7.1" + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rwxGnsA92emp" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors." + ] + }, + { + "cell_type": "code", + "metadata": { + "cellView": "form", + "colab_type": "code", + "id": "CPII1rGR2rF9", + "colab": {} + }, + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "JtEZ1pCPn--z" + }, + "source": [ + "# 사용자 정의 학습: 자세히 둘러보기" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "GV1F7tVTN3Dn" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " TensorFlow.org에서 보기\n", + " \n", + " 구글 코랩(Colab)에서 실행하기\n", + " \n", + " 깃허브(GitHub) 소스 보기\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "64VL9OukxoUc", + "colab_type": "text" + }, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", + "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", + "이 번역에 개선할 부분이 있다면\n", + "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", + "문서 번역이나 리뷰에 참여하려면\n", + "[docs-ko@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs-ko)로\n", + "메일을 보내주시기 바랍니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "LDrzLFXE8T1l" + }, + "source": [ + "이번 튜토리얼은 붓꽃의 품종을 분류하기 위한 머신러닝 모델을 구축할 것입니다. 다음을 위해 즉시 실행[(eager execution)](https://www.tensorflow.org/guide/eager)을 사용합니다.\n", + "1. 모델 구축\n", + "2. 모델 훈련\n", + "3. 예측을 위한 모델 사용\n", + "\n", + "## 텐서플로 프로그래밍\n", + "\n", + "이번 튜토리얼에서는 다음과 같은 고수준 텐서플로의 개념을 사용합니다.\n", + "\n", + "* [즉시 실행(eager execution)](https://www.tensorflow.org/guide/eager) 개발 환경,\n", + "* [데이터셋 API](https://www.tensorflow.org/guide/datasets)를 활용한 데이터 가져오기,\n", + "* [케라스 API](https://keras.io/getting-started/sequential-model-guide/)를 활용한 모델과 층(layer) 구축 .\n", + "\n", + "이번 튜토리얼은 다른 텐서플로 프로그램과 유사하게 구성되어있습니다.\n", + "\n", + "1. 데이터 가져오기 및 분석.\n", + "2. 모델 타입 선정.\n", + "3. 모델 훈련.\n", + "4. 모델 효과 평가.\n", + "5. 예측을 위한 훈련된 모델 사용." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "yNr7H-AIoLOR" + }, + "source": [ + "## 프로그램 설정" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "1J3AuPBT9gyR" + }, + "source": [ + "### 임포트 및 즉시 실행 구성\n", + "\n", + "텐서플로를 포함하여 필요한 파이썬 모듈을 임포트하고, 즉시 실행을 활성화합니다. 즉시 실행은 텐서플로 연산이 나중에 실행되는 [계산 그래프(computational graph)](https://www.tensorflow.org/guide/graphs)를 만드는 대신에 연산을 즉시 평가하고 구체적인 값을 반환하게 합니다. 만약 파이썬 대화형 창이나 상호작용 콘솔을 사용하시면 더욱 익숙할 겁니다. 즉시 실행은 [Tensorlow >=1.8](https://www.tensorflow.org/install/) 부터 사용 가능합니다.\n", + "\n", + "즉시 실행이 활성화될 때, 동일한 프로그램내에서 비활성화 할 수 없습니다. 더 많은 세부사항은 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 참조하세요." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "g4Wzg69bnwK2", + "colab": {} + }, + "source": [ + "from __future__ import absolute_import, division, print_function, unicode_literals\n", + "\n", + "import os\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import tensorflow as tf\n", + "\n", + "tf.enable_eager_execution()\n", + "\n", + "print(\"텐서플로 버전: {}\".format(tf.__version__))\n", + "print(\"즉시 실행: {}\".format(tf.executing_eagerly()))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Zx7wc0LuuxaJ" + }, + "source": [ + "## 붓꽃 분류 문제\n", + "\n", + "당신이 식물학자라고 상상하고, 주어진 붓꽃을 자동적으로 분류하는 방법을 찾고 있다고 가정합시다. 머신러닝은 통계적으로 꽃을 분류할 수 있는 다양한 알고리즘을 제공합니다. 예를 들어, 정교한 머신러닝 프로그램은 사진을 통해 꽃을 분류할 수 있습니다. 이번 튜토리얼의 목적은 좀 더 겸손하게, 측정된 [꽃받침](https://en.wikipedia.org/wiki/Sepal)과 [꽃잎](https://en.wikipedia.org/wiki/Petal)의 길이와 폭을 토대로 붓꽃을 분류하는 것입니다.\n", + "\n", + "이 붓꽃은 약 300종입니다. 하지만 이번 튜토리얼에서는 오직 3가지 품종을 기준으로 분류할 것입니다. \n", + "\n", + "* Iris setosa\n", + "* Iris virginica\n", + "* Iris versicolor\n", + "\n", + "\n", + " \n", + " \n", + "
\n", + " \"Petal\n", + "
\n", + " 그림 1. Iris setosa (by Radomil, CC BY-SA 3.0), Iris versicolor, (by Dlanglois, CC BY-SA 3.0), and Iris virginica (by Frank Mayfield, CC BY-SA 2.0).
 \n", + "
\n", + "\n", + "다행히도 다른 사람들이 먼저 꽃받침과 꽃잎의 길이와 폭이 측정된 [120개의 붓꽃 데이터](https://en.wikipedia.org/wiki/Iris_flower_data_set)를 만들어 놓았습니다. 이것은 머신러닝 분류 문제에 있어 초보자에게 유명한 고전 데이터셋입니다. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3Px6KAg0Jowz" + }, + "source": [ + "## 훈련 데이터 가져오기 및 파싱\n", + "\n", + "데이터를 불러오고 파이썬 프로그램이 사용할 수 있는 구조로 전환합니다.\n", + "\n", + "### 데이터셋 다운로드\n", + "\n", + "[tf.keras.utils.get_file](https://www.tensorflow.org/api_docs/python/tf/keras/utils/get_file) 함수를 사용하여 데이터셋을 다운로드합니다. 이 함수는 다운로드된 파일의 경로를 반환합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "J6c7uEU9rjRM", + "colab": {} + }, + "source": [ + "train_dataset_url = \"https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv\"\n", + "\n", + "train_dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(train_dataset_url),\n", + " origin=train_dataset_url)\n", + "\n", + "print(\"데이터셋이 복사된 위치: {}\".format(train_dataset_fp))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "qnX1-aLors4S" + }, + "source": [ + "### 데이터 탐색\n", + "\n", + "이 데이터셋(`iris_training.csv`)은 콤마 ','로 구분된 CSV 파일입니다. `head -n5` 명령을 사용하여 처음 5개 항목을 확인합니다. " + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "FQvb_JYdrpPm", + "colab": {} + }, + "source": [ + "!head -n5 {train_dataset_fp}" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "kQhzD6P-uBoq" + }, + "source": [ + "처음 5개의 데이터로부터 다음을 주목하세요.\n", + "\n", + "1. 첫 번째 줄은 다음과 같은 정보를 포함하고 있는 헤더(header)입니다. \n", + " * 총 120개의 샘플이 있으며, 각 샘플들은 4개의 특성(feature), 3개의 레이블(label)을 가지고 있습니다.\n", + "2. 후속행은 데이터 레코드입니다. 한 줄당 한가지 *[샘플](https://developers.google.com/machine-learning/glossary/#example)*입니다.\n", + " * 처음 4개의 필드는 *[특성](https://developers.google.com/machine-learning/glossary/#feature)*입니다.: 이것들은 샘플의 특징을 나타냅니다. 이 필드들는 붓꽃의 측정값을 부동소수점으로 나타냅니다.\n", + " * 마지막 컬럼(column)은 *[레이블(label)](https://developers.google.com/machine-learning/glossary/#label)*입니다.: 레이블은 예측하고자 하는 값을 나타냅니다. 이 데이터셋에서는 꽃의 이름과 관련된 정수값 0, 1, 2를 나타냅니다.\n", + "\n", + "코드로 표현하면 다음과 같습니다.:" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "9Edhevw7exl6", + "colab": {} + }, + "source": [ + "# CSV 파일안에서 컬럼의 순서\n", + "column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']\n", + "\n", + "feature_names = column_names[:-1]\n", + "label_name = column_names[-1]\n", + "\n", + "print(\"특성: {}\".format(feature_names))\n", + "print(\"레이블: {}\".format(label_name))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "CCtwLoJhhDNc" + }, + "source": [ + "각각의 레이블은 \"setosa\"와 같은 문자형 이름과 연관되어있습니다. 하지만 머신러닝은 전형적으로 숫자형 값에 의존합니다. 레이블을 다음과 같이 맵핑(mapping) 합니다. \n", + "\n", + "* `0`: Iris setosa\n", + "* `1`: Iris versicolor\n", + "* `2`: Iris virginica\n", + "\n", + "특성과 레이블에 관한 더 많은 정보를 위해서는 [머신러닝 특강의 전문용어 부분](https://developers.google.com/machine-learning/crash-course/framing/ml-terminology)을 참조하세요." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "sVNlJlUOhkoX", + "colab": {} + }, + "source": [ + "class_names = ['Iris setosa', 'Iris versicolor', 'Iris virginica']" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "dqPkQExM2Pwt" + }, + "source": [ + "### `tf.data.Dataset` 생성\n", + "\n", + "텐서플로의 [Dataset API](https://www.tensorflow.org/guide/datasets)는 데이터를 적재할 때 발생하는 다양한 경우를 다룰 수 있습니다. 이는 훈련에 필요한 형태로 데이터를 읽고 변환하는 고수준 API입니다. 더 많은 정보를 위해서는 [데이터셋 빠른 실행 가이드](https://www.tensorflow.org/get_started/datasets_quickstart)를 참조하세요. \n", + "\n", + "\n", + "데이터셋이 CSV 파일이므로, 적절한 형태로 데이터를 구분하기위해 [make_csv_dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/make_csv_dataset) 함수를 사용하겠습니다. 이 함수는 훈련 모델을 위한 데이터를 생성하므로, 초기값은 셔플(`shuffle=True, shuffle_buffer_size=10000`)과 무한반복(`num_epochs=None`)으로 설정되어있습니다. 또한 [배치 사이즈(batch_size)](https://developers.google.com/machine-learning/glossary/#batch_size)를 설정해줍니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "WsxHnz1ebJ2S", + "colab": {} + }, + "source": [ + "batch_size = 32\n", + "\n", + "train_dataset = tf.contrib.data.make_csv_dataset(\n", + " train_dataset_fp,\n", + " batch_size, \n", + " column_names=column_names,\n", + " label_name=label_name,\n", + " num_epochs=1)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "gB_RSn62c-3G" + }, + "source": [ + "`make_csv_dataset` 함수는 `(features, label)` 쌍으로 구성된 `tf.data.Dataset`을 반환합니다. `features`는 딕셔너리 객체인: `{'feature_name': value}`로 주어집니다.\n", + "또한 즉시 실행 활성화로 이 `Dataset`은 반복가능합니다. 다음은 특성(feature)을 살펴봅시다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "iDuG94H-C122", + "colab": {} + }, + "source": [ + "features, labels = next(iter(train_dataset))\n", + "\n", + "features" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "E63mArnQaAGz" + }, + "source": [ + "유사한 특성의 값은 같이 그룹 되어있거나, *배치* 돼있다는 사실에 주목하세요. 각 샘플 행의 필드는 해당 특성 배열에 추가됩니다. `batch_size`를 조절하여 이 특성 배열에 저장된 샘플의 수를 설정하세요.\n", + "\n", + "또한 배치(batch)로부터 약간의 특성을 도식화하여 군집돼있는 데이터를 확인할 수 있습니다. " + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "me5Wn-9FcyyO", + "colab": {} + }, + "source": [ + "plt.scatter(features['petal_length'].numpy(),\n", + " features['sepal_length'].numpy(),\n", + " c=labels.numpy(),\n", + " cmap='viridis')\n", + "\n", + "plt.xlabel(\"petal length\")\n", + "plt.ylabel(\"sepal length\");" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "YlxpSyHlhT6M" + }, + "source": [ + "모델 구축 단계를 단순화하기 위해, 특성 딕셔너리를 `(batch_size, num_features)`의 형태를 가지는 단일 배열로 다시 구성하는 함수를 생성합니다.\n", + "\n", + "이 함수는 텐서의 리스트(list)로부터 값을 취하고 특정한 차원으로 결합된 텐서를 생성하는 [tf.stack](https://www.tensorflow.org/api_docs/python/tf/stack) 메서드(method)를 사용합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "jm932WINcaGU", + "colab": {} + }, + "source": [ + "def pack_features_vector(features, labels):\n", + " \"\"\"Pack the features into a single array.\"\"\"\n", + " features = tf.stack(list(features.values()), axis=1)\n", + " return features, labels" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "V1Vuph_eDl8x" + }, + "source": [ + "그 후 각 `(features,label)`쌍의 특성을 훈련 데이터셋에 쌓기위해 [tf.data.Dataset.map](https://www.tensorflow.org/api_docs/python/tf/data/dataset/map) 메서드를 사용합니다. " + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "ZbDkzGZIkpXf", + "colab": {} + }, + "source": [ + "train_dataset = train_dataset.map(pack_features_vector)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "NLy0Q1xCldVO" + }, + "source": [ + "데이터셋의 특성 요소는 이제 형태가 `(batch_size, num_features)`인 배열입니다. 첫 5개행의 샘플을 살펴봅시다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "kex9ibEek6Tr", + "colab": {} + }, + "source": [ + "features, labels = next(iter(train_dataset))\n", + "\n", + "print(features[:5])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "LsaVrtNM3Tx5" + }, + "source": [ + "## 모델 타입 선정\n", + "\n", + "### 왜 모델을 사용해야하는가?\n", + "\n", + " *[모델](https://developers.google.com/machine-learning/crash-course/glossary#model)*은 특성(feature)과 레이블(label) 과의 관계입니다. 붓꽃 분류 문제에서 모델은 측정된 꽃받침과 꽃잎 사이의 관계를 정의하고 붓꽃의 품종을 예측합니다. 몇 가지 간단한 모델은 몇 줄의 대수학으로 표현할 수 있으나, 복잡한 머신러닝 모델은 요약하기 힘든 굉장히 많은 수의 매개변수를 가지고 있습니다.\n", + "\n", + "머신러닝을 사용하지 않고 4가지의 특성 사이의 관계를 결정하고 붓꽃을 품종을 예측하실 수 있으신가요? 즉, 특정 품종의 꽃받침과 꽃잎과의 관계를 정의할 수 있을 정도로 데이터셋을 분석했다면, 전통적인 프로그래밍 기술(예를 들어 굉장히 많은 조건문)을 사용하여 모델은 만들 수 있으신가요? 더 복잡한 데이터셋에서 이는 불가능에 가까울 수 있습니다. 잘 구성된 머신러닝은 사용자를 위한 모델을 결정합니다. 만약 충분히 좋은 샘플을 잘 구성된 머신러닝 모델에 제공한다면, 프로그램은 사용자를 위한 특성 간의 관계를 이해하고 제공합니다. \n", + "\n", + "### 모델 선정\n", + "\n", + "이제 학습을 위한 모델의 종류를 선정해야합니다. 여러 종류의 모델이 있고, 이를 선택하는 것은 많은 경험이 필요합니다. 이번 튜토리얼에서는 붓꽃 분류 문제를 해결하기위해 *[신경망(neural network)](https://developers.google.com/machine-learning/glossary/#neural_network)* 모델을 사용하겠습니다. 신경망 모델은 특성과 레이블 사이의 복잡한 관계를 찾을 수 있습니다. 신경망은 하나 또는 그 이상의 *[은닉층(hidden layer)](https://developers.google.com/machine-learning/glossary/#hidden_layer)*으로 구성된 그래프입니다. 각각의 은닉층은 하나 이상의 *[뉴런(neuron)](https://developers.google.com/machine-learning/glossary/#neuron)*으로 구성되어있습니다. 몇가지 신경망의 범주가 있으며, 이번 튜토리얼에서는 *[밀집(dense) 또는 완전 연결 신경망(fully-connected neural network)](https://developers.google.com/machine-learning/glossary/#fully_connected_layer)*를 사용합니다: 완전 연결 신경망(fully-connected neural network)은 하나의 뉴런에 이전층의 모든 뉴런의 입력을 받는 신경망입니다. 예를 들어, `그림 2`는 입력층, 2개의 은닉층, 그리고 출력층으로 구성된 완전 연결 신경망입니다. \n", + "\n", + "\n", + " \n", + " \n", + "
\n", + " \n", + "
\n", + " 그림 2. A neural network with features, hidden layers, and predictions.
 \n", + "
\n", + "\n", + "그림 2의 모델이 훈련된 다음 레이블 되어있지 않은 데이터를 제공했을때, 모델은 주어진 데이터의 3가지(주어진 레이블의 개수) 예측을 출력합니다. 이러한 예측은 *[추론(inference)](https://developers.google.com/machine-learning/crash-course/glossary#inference)*이라고 불립니다. 이 샘플에서 출력의 합은 1.0입니다. 그림 2에서 예측은 *Iris setosa* `0.02`, *Iris versicolor* `0.95`, *Iris virginica*에 `0.03`로 주어집니다. 이는 모델이 95%의 확률로 주어진 데이터를 *Iris versicolor*로 예측한다는 것을 의미합니다. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "W23DIMVPQEBt" + }, + "source": [ + "### 케라스를 사용한 모델 생성\n", + "\n", + "텐서플로의 [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) API는 모델과 층을 생성하기 위한 풍부한 라이브러리를 제공합니다. 케라스가 구성 요소를 연결하기 위한 복잡함을 모두 처리해 주기 때문에 모델을 구축하고 실험하는 것이 쉽습니다.\n", + "\n", + "[tf.keras.Sequential](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)은 여러 층을 연이어 쌓은 모델입니다. 이 구조는 층의 인스턴스를 취하며, 아래의 경우 각 층당 10개의 노드(node)를 가지는 2개의 [Dense(완전 연결 층)](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)과 3개의 예측(레이블의 수) 노드를 가지는 출력 층으로 구성되어있습니다. 첫 번째 층의 `input_shape` 매개변수는 데이터셋의 특성의 수와 관계있습니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "2fZ6oL2ig3ZK", + "colab": {} + }, + "source": [ + "model = tf.keras.Sequential([\n", + " tf.keras.layers.Dense(10, activation=tf.nn.relu, input_shape=(4,)), # input shape required\n", + " tf.keras.layers.Dense(10, activation=tf.nn.relu),\n", + " tf.keras.layers.Dense(3)\n", + "])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "FHcbEzMpxbHL" + }, + "source": [ + "*[활성화 함수(activation function)](https://developers.google.com/machine-learning/crash-course/glossary#activation_function)*는 각 층에서 출력의 크기를 결정합니다. 이러한 비선형성은 중요하며, 활성화 함수가 없는 모델은 하나의 층과 동일하다고 생각할 수 있습니다. 사용 가능한 [활성화 함수](https://www.tensorflow.org/api_docs/python/tf/keras/activations)는 많지만, [ReLU](https://developers.google.com/machine-learning/crash-course/glossary#ReLU)가 은닉층에 주로 사용됩니다. \n", + "\n", + "이상적인 은닉층과 뉴런의 개수는 문제와 데이터셋에 의해 좌우됩니다. 머신러닝의 여러 측면과 마찬가지로, 최적의 신경망 타입을 결정하는 것은 많은 경험과 지식이 필요합니다. 경험을 토대로 보면 은닉층과 뉴런의 증가는 전형적으로 강력한 모델을 생성하므로, 모델을 효과적으로 훈련시키기 위해서 더 많은 데이터를 필요로 합니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "2wFKnhWCpDSS" + }, + "source": [ + "### 모델 사용\n", + "\n", + "이 모델이 특성의 배치에 대해 수행하는 작업을 간단히 살펴봅시다. " + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "xe6SQ5NrpB-I", + "colab": {} + }, + "source": [ + "predictions = model(features)\n", + "predictions[:5]" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "wxyXOhwVr5S3" + }, + "source": [ + "각 샘플은 각 클래스에 대한 [로짓(logit)](https://developers.google.com/machine-learning/crash-course/glossary#logits)을 반환합니다. \n", + "\n", + "이 로짓(logit)을 각 클래스에 대한 확률로 변환하기 위하서 [소프트맥스(softmax)](https://developers.google.com/machine-learning/crash-course/glossary#softmax) 함수를 사용하겠습니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "_tRwHZmTNTX2", + "colab": {} + }, + "source": [ + "tf.nn.softmax(predictions[:5])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "uRZmchElo481" + }, + "source": [ + "`tf.argmax`는 예측된 값 중 가장 큰 확률(원하는 클래스)을 반환합니다. 하지만 모델이 아직 훈련되지 않았으므로 이는 좋은 예측이 아닙니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "-Jzm_GoErz8B", + "colab": {} + }, + "source": [ + "print(\"예측: {}\".format(tf.argmax(predictions, axis=1)))\n", + "print(\" 레이블: {}\".format(labels))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Vzq2E5J2QMtw" + }, + "source": [ + "## 모델 훈련하기\n", + "\n", + "*[훈련 단계](https://developers.google.com/machine-learning/crash-course/glossary#training)*는 모델이 점진적으로 최적화되거나 데이터셋을 학습하는 머신러닝의 과정입니다. 훈련의 목적은 미지의 데이터를 예측하기 위해, 훈련 데이터셋의 구조에 대해서 충분히 학습하는 것입니다. 만약 모델이 훈련 데이터셋에 대해서 과하게 학습된다면 오직 훈련 데이터셋에 대해서 작동할 것이며, 일반화되기 힘들 것입니다. 이러한 문제를 *[과대적합(overfitting)](https://developers.google.com/machine-learning/crash-course/glossary#overfitting)* 이라고 합니다. 이는 마치 문제를 이해하고 해결한다기보다는 답을 기억하는 것이라고 생각할 수 있습니다. \n", + "\n", + "붓꽃 분류 문제는 *[지도 학습(supervised machine learning)](https://developers.google.com/machine-learning/glossary/#supervised_machine_learning)*의 예시 중 하나입니다.: 지도학습은 모델이 레이블을 포함한 훈련 데이터로부터 학습됩니다. *[비지도 학습(unsupervised machine learning)](https://developers.google.com/machine-learning/glossary/#unsupervised_machine_learning)*에서는 훈련 데이터가 레이블을 포함하고 있지 않습니다. 대신에 모델은 특성 간의 패턴을 찾습니다. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "RaKp8aEjKX6B" + }, + "source": [ + "### 손실 함수와 그래디언트 함수 정의하기\n", + "\n", + "훈련과 평가단계에서 모델의 *[손실(loss)](https://developers.google.com/machine-learning/crash-course/glossary#loss)*을 계산해야 합니다. 손실은 모델의 예측이 원하는 레이블과 얼마나 일치하는지, 또한 모델이 잘 작동하는지에 대한 척도로 사용됩니다. 이 값을 최소화하고, 최적화 해야합니다.\n", + "\n", + "모델의 손실은 [tf.keras.losses.categorical_crossentropy](https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy) 함수를 사용해 계산할 것입니다. 이 함수는 모델의 클래스(레이블)과 예측된 값(로짓)을 입력받아 샘플의 평균 손실을 반환합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "tMAT4DcMPwI-", + "colab": {} + }, + "source": [ + "def loss(model, x, y):\n", + " y_ = model(x)\n", + " return tf.losses.sparse_softmax_cross_entropy(labels=y, logits=y_)\n", + "\n", + "\n", + "l = loss(model, features, labels)\n", + "print(\"손실 테스트: {}\".format(l))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3IcPqA24QM6B" + }, + "source": [ + "모델을 최적화하기 위해 사용되는 *[그래디언트(gradient)](https://developers.google.com/machine-learning/crash-course/glossary#gradient)*를 계산하기 위해 [tf.GradientTape](https://www.tensorflow.org/api_docs/python/tf/GradientTape) 컨텍스트를 사용합니다. 더 자세한 정보는 [즉시 실행 가이드](https://www.tensorflow.org/guide/eager)를 확인하세요. " + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "x57HcKWhKkei", + "colab": {} + }, + "source": [ + "def grad(model, inputs, targets):\n", + " with tf.GradientTape() as tape:\n", + " loss_value = loss(model, inputs, targets)\n", + " return loss_value, tape.gradient(loss_value, model.trainable_variables)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "lOxFimtlKruu" + }, + "source": [ + "### 옵티마이저 생성 \n", + "\n", + "*[옵티마이저(optimizer)](https://developers.google.com/machine-learning/crash-course/glossary#optimizer)*는 손실 함수를 최소화하기 위해 계산된 그래디언트를 모델의 변수에 적용합니다. 손실 함수를 구부러진 곡선의 표면(그림 3)으로 생각할 수 있으며, 이 함수의 최저점을 찾고자 합니다. 그래디언트는 가장 가파른 상승 방향을 가리키며 따라서 반대 방향으로 이동하는 여행을 합니다. 각 배치마다의 손실과 기울기를 반복적으로 계산하여 훈련과정 동안 모델을 조정합니다. 점진적으로, 모델은 손실을 최소화하기 위해 가중치(weight)와 편향(bias)의 최적의 조합을 찾아냅니다. 손실이 낮을수록 더 좋은 모델의 예측을 기대할 수 있습니다.\n", + "\n", + "\n", + " \n", + " \n", + "
\n", + " \"Optimization\n", + "
\n", + " 그림 3. 3차원 공간에 대한 최적화 알고리즘 시각화.
(Source: Stanford class CS231n, MIT License, Image credit: Alec Radford)\n", + "
\n", + "\n", + "텐서플로는 훈련을 위해 사용 가능한 여러종류의 [최적화 알고리즘](https://www.tensorflow.org/api_guides/python/train)을 가지고 있습니다. 이번 모델에서는 *[확률적 경사 하강법(stochastic gradient descent, SGD)](https://developers.google.com/machine-learning/crash-course/glossary#gradient_descent)* 을 구현한 [tf.train.GradientDescentOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/GradientDescentOptimizer)를 사용하겠습니다. `learning_rate`은 경사하강 과정의 크기를 나타내는 매개변수이며, 더 나은 결과를 위해 조절가능한 *하이퍼파라미터(hyperparameter)* 입니다. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "XkUd6UiZa_dF" + }, + "source": [ + "옵티마이저(optimizer)와 `global_step`을 설정합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "8xxi2NNGKwG_", + "colab": {} + }, + "source": [ + "optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)\n", + "\n", + "global_step = tf.contrib.eager.Variable(0)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "pJVRZ0hP52ZB" + }, + "source": [ + "이 값들을 단일 최적화 단계를 계산하기 위해 사용합니다. " + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "rxRNTFVe56RG", + "colab": {} + }, + "source": [ + "loss_value, grads = grad(model, features, labels)\n", + "\n", + "print(\"단계: {}, 초기 손실: {}\".format(global_step.numpy(),\n", + " loss_value.numpy()))\n", + "\n", + "optimizer.apply_gradients(zip(grads, model.trainable_variables), global_step)\n", + "\n", + "print(\"단계: {}, 손실: {}\".format(global_step.numpy(),\n", + " loss(model, features, labels).numpy()))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "7Y2VSELvwAvW" + }, + "source": [ + "### 훈련 루프\n", + "\n", + "모든 사항이 갖춰졌으므로 모델을 훈련할 준비가 되었습니다! 훈련 루프는 더 좋은 예측을 위해 데이터셋을 모델로 제공합니다. 다음의 코드 블럭은 아래의 훈련 단계를 작성한 것입니다. \n", + "\n", + "1. 각 *에포크(epoch)* 반복. 에포크는 데이터셋을 통과시키는 횟수입니다. \n", + "2. 에포크 내에서, *특성* (`x`)와 *레이블* (`y`)가 포함된 훈련 `데이터셋`에 있는 샘플을 반복합니다.\n", + "3. 샘플의 특성을 사용하여 결과를 예측 하고 레이블과 비교합니다. 예측의 부정확도를 측정하고 모델의 손실과 그래디언트를 계산하기 위해 사용합니다. \n", + "4. 모델의 변수를 업데이트하기 위해 `옵티마이저`를 사용합니다. \n", + "5. 시각화를 위해 몇가지 값들을 저장합니다.\n", + "6. 각 에포크를 반복합니다.\n", + "\n", + "`num_epochs` 변수는 데이터셋의 반복 횟수입니다. 직관과는 반대로, 모델을 길게 학습하는 것이 더 나은 모델이 될 것이라고 보장하지 못합니다. `num_epochs`는 조정가능한 *[하이퍼파라미터(hyperparameter)](https://developers.google.com/machine-learning/glossary/#hyperparameter)* 입니다. 적절한 횟수를 선택하는 것은 많은 경험과 직관을 필요로 합니다. " + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "AIgulGRUhpto", + "colab": {} + }, + "source": [ + "## Note: 이 셀을 다시 실행하면 동일한 모델의 변수가 사용됩니다.\n", + "\n", + "from tensorflow import contrib\n", + "tfe = contrib.eager\n", + "\n", + "# 도식화를 위해 결과를 저장합니다.\n", + "train_loss_results = []\n", + "train_accuracy_results = []\n", + "\n", + "num_epochs = 201\n", + "\n", + "for epoch in range(num_epochs):\n", + " epoch_loss_avg = tfe.metrics.Mean()\n", + " epoch_accuracy = tfe.metrics.Accuracy()\n", + "\n", + " # 훈련 루프 - 32개의 배치를 사용합니다.\n", + " for x, y in train_dataset:\n", + " # 모델을 최적화합니다.\n", + " loss_value, grads = grad(model, x, y)\n", + " optimizer.apply_gradients(zip(grads, model.trainable_variables),\n", + " global_step)\n", + "\n", + " # 진행 상황을 추적합니다.\n", + " epoch_loss_avg(loss_value) # 현재 배치 손실을 추가합니다.\n", + " # 예측된 레이블과 실제 레이블 비교합니다.\n", + " epoch_accuracy(tf.argmax(model(x), axis=1, output_type=tf.int32), y)\n", + "\n", + " # epoch 종료\n", + " train_loss_results.append(epoch_loss_avg.result())\n", + " train_accuracy_results.append(epoch_accuracy.result())\n", + " \n", + " if epoch % 50 == 0:\n", + " print(\"에포크 {:03d}: 손실: {:.3f}, 정확도: {:.3%}\".format(epoch, \n", + " epoch_loss_avg.result(), \n", + " epoch_accuracy.result()))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "2FQHVUnm_rjw" + }, + "source": [ + "### 시간에 따른 손실함수 시각화" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "j3wdbmtLVTyr" + }, + "source": [ + "모델의 훈련 과정을 출력하는 것도 도움이 되지만, 훈련 과정을 직접 보는 것이 더 도움이 되곤합니다. [텐서보드(tensorboard)](https://www.tensorflow.org/guide/summaries_and_tensorboard)는 텐서플로에 패키지 되어있는 굉장히 유용한 시각화 툴입니다. 하지만 `matplotlib` 모듈을 사용하여 일반적인 도표를 출력할 수 있습니다.\n", + "\n", + "이 도표를 해석하는 것은 여러 경험이 필요하지만, 결국 모델을 최적화하기 위해 *손실*이 내려가고 *정확도*가 올라가는 것을 원합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "agjvNd2iUGFn", + "colab": {} + }, + "source": [ + "fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))\n", + "fig.suptitle('Training Metrics')\n", + "\n", + "axes[0].set_ylabel(\"loss\", fontsize=14)\n", + "axes[0].plot(train_loss_results)\n", + "\n", + "axes[1].set_ylabel(\"Accuracy\", fontsize=14)\n", + "axes[1].set_xlabel(\"epoch\", fontsize=14)\n", + "axes[1].plot(train_accuracy_results);" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Zg8GoMZhLpGH" + }, + "source": [ + "## 모델 유효성 평가\n", + "\n", + "이제 모델은 훈련되었습니다. 모델의 성능에 대한 몇가지 통계를 얻을 수 있습니다. \n", + "\n", + "*평가(Evaluating)*는 모델이 예측을 얼마나 효과적으로 수행하는지 결정하는 것을 의미합니다. 붓꽃 분류 모델의 유효성을 결정하기 위해, 몇가지 꽃잎과 꽃받침 데이터를 통과시키고 어떠한 품종을 예측하는지 확인합니다. 그 후 실제 품종과 비교합니다. 예를 들어, 절반의 데이터를 올바르게 예측한 모델의 *[정확도](https://developers.google.com/machine-learning/glossary/#accuracy)* 는 `0.5`입니다. 그림 4는 조금 더 효과적인 모델입니다. 5개의 예측 중 4개를 올바르게 예측하여 80% 정확도를 냅니다.\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
샘플 특성레이블모델 예측
5.93.04.31.511
6.93.15.42.122
5.13.31.70.500
6.0 3.4 4.5 1.6 12
5.52.54.01.311
\n", + " 그림 4. 80% 정확도 붓꽃 분류기.
 \n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "z-EvK7hGL0d8" + }, + "source": [ + "### 테스트 데이터 세트 설정\n", + "\n", + "모델을 평가하는 것은 모델을 훈련하는 것과 유사합니다. 가장 큰 차이는 훈련 데이터가 아닌 *[테스트 데이터 세트](https://developers.google.com/machine-learning/crash-course/glossary#test_set)* 를 사용했다는 것입니다. 공정하게 모델의 유효성을 평가하기 위해, 모델을 평가하기 위한 샘플은 반드시 훈련 데이터와 달라야합니다. \n", + "\n", + "테스트 데이터 세트를 설정하는 것은 훈련 데이터 세트를 설정하는 것과 유사합니다. CSV 파일을 다운로드하고 값을 파싱합니다. 그 후 셔플은 적용하지 않습니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "Ps3_9dJ3Lodk", + "colab": {} + }, + "source": [ + "test_url = \"https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv\"\n", + "\n", + "test_fp = tf.keras.utils.get_file(fname=os.path.basename(test_url),\n", + " origin=test_url)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "SRMWCu30bnxH", + "colab": {} + }, + "source": [ + "test_dataset = tf.contrib.data.make_csv_dataset(\n", + " test_fp,\n", + " batch_size, \n", + " column_names=column_names,\n", + " label_name='species',\n", + " num_epochs=1,\n", + " shuffle=False)\n", + "\n", + "test_dataset = test_dataset.map(pack_features_vector)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "HFuOKXJdMAdm" + }, + "source": [ + "### 테스트 데이터 세트를 사용한 모델 평가\n", + "\n", + "훈련 단계와는 다르게 모델은 테스트 데이터에 대해서 오직 한 번의 [에포크](https://developers.google.com/machine-learning/glossary/#epoch)를 진행합니다. 다음의 코드 셀은 테스트 셋에 있는 샘플에 대해 실행하고 실제 레이블과 비교합니다. 이는 전체 테스트 데이터 세트에 대한 정확도를 측정하는데 사용됩니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "Tw03-MK1cYId", + "colab": {} + }, + "source": [ + "test_accuracy = tfe.metrics.Accuracy()\n", + "\n", + "for (x, y) in test_dataset:\n", + " logits = model(x)\n", + " prediction = tf.argmax(logits, axis=1, output_type=tf.int32)\n", + " test_accuracy(prediction, y)\n", + "\n", + "print(\"테스트 세트 정확도: {:.3%}\".format(test_accuracy.result()))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "HcKEZMtCOeK-" + }, + "source": [ + "마지막 배치에서 모델이 올바르게 예측한 것을 확인할 수 있습니다. " + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "uNwt2eMeOane", + "colab": {} + }, + "source": [ + "tf.stack([y,prediction],axis=1)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "7Li2r1tYvW7S" + }, + "source": [ + "## 훈련된 모델로 예측하기\n", + "\n", + "이제 붓꽃을 분류하기 위해 완벽하지는 않지만 어느 정도 검증된 모델을 가지고 있습니다. 훈련된 모델을 사용하여 [레이블 되지 않은 데이터](https://developers.google.com/machine-learning/glossary/#unlabeled_example)를 예측해봅시다.\n", + "\n", + "실제로는 레이블 되지 않은 샘플들은 여러 소스(앱, CSV 파일, 직접 제공 등)로부터 제공될 수 있습니다. 지금은 레이블을 예측하기 위해 수동으로 3개의 레이블 되지 않은 샘플을 제공하겠습니다. 레이블은 다음과 같은 붓꽃 이름으로 매핑되어있습니다.\n", + "* `0`: Iris setosa\n", + "* `1`: Iris versicolor\n", + "* `2`: Iris virginica" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "kesTS5Lzv-M2", + "colab": {} + }, + "source": [ + "predict_dataset = tf.convert_to_tensor([\n", + " [5.1, 3.3, 1.7, 0.5,],\n", + " [5.9, 3.0, 4.2, 1.5,],\n", + " [6.9, 3.1, 5.4, 2.1]\n", + "])\n", + "\n", + "predictions = model(predict_dataset)\n", + "\n", + "for i, logits in enumerate(predictions):\n", + " class_idx = tf.argmax(logits).numpy()\n", + " p = tf.nn.softmax(logits)[class_idx]\n", + " name = class_names[class_idx]\n", + " print(\"예 {} 예측: {} ({:4.1f}%)\".format(i, name, 100*p))" + ], + "execution_count": 0, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/site/ko/tutorials/eager/eager_basics.ipynb b/site/ko/tutorials/eager/eager_basics.ipynb index f70825fafd5..cdac5909049 100644 --- a/site/ko/tutorials/eager/eager_basics.ipynb +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -1,492 +1,483 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "iPpI7RaYoZuE" - }, - "source": [ - "##### Copyright 2018 The TensorFlow Authors." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "colab": {}, - "colab_type": "code", - "id": "hro2InpHobKk" - }, - "outputs": [], - "source": [ - "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", - "# you may not use this file except in compliance with the License.\n", - "# You may obtain a copy of the License at\n", - "#\n", - "# https://www.apache.org/licenses/LICENSE-2.0\n", - "#\n", - "# Unless required by applicable law or agreed to in writing, software\n", - "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", - "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", - "# See the License for the specific language governing permissions and\n", - "# limitations under the License." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "U9i2Dsh-ziXr" - }, - "source": [ - "# 즉시 실행 기초" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "Hndw-YcxoOJK" - }, - "source": [ - "\n", - " \n", - " \n", - " \n", - "
\n", - " TensorFlow.org에서 보기\n", - " \n", - " 구글 코랩(Colab)에서 실행하기\n", - " \n", - " 깃허브(GitHub) 소스 보기\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", - "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", - "이 번역에 개선할 부분이 있다면\n", - "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", - "문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을\n", - "작성하거나\n", - "[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로\n", - "메일을 보내주시기 바랍니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "6sILUVbHoSgH" - }, - "source": [ - "이 노트북은 텐서플로를 사용하기 위한 입문 튜토리얼입니다. 다음 내용을 다룹니다 : \n", - "\n", - "* 필요한 패키지 임포트\n", - "* 텐서(Tensor) 생성 및 사용\n", - "* GPU 가속기 사용\n", - "* 데이터 세트" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "z1JcS5iBXMRO" - }, - "source": [ - "## 텐서플로 임포트\n", - "\n", - "시작하기 위해서 텐서플로 모듈을 임포트하고 즉시 실행(eager execution)을 활성화합니다. 즉시 실행 활성화로 텐서플로를 조금 더 대화형 프론트엔드(frontend)에 가깝게 만들어 줍니다. 세부사항은 나중에 이야기할 것입니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "code", - "colab": {}, - "colab_type": "code", - "id": "RlIWhyeLoYnG" - }, - "outputs": [], - "source": [ - "from __future__ import absolute_import, division, print_function\n", - "\n", - "import tensorflow as tf\n", - "\n", - "tf.enable_eager_execution()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "H9UySOPLXdaw" - }, - "source": [ - "## 텐서\n", - "\n", - "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 크기를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기 메모리에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 이용하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자는 자동적으로 순수 파이썬 타입을 변환합니다. 예를 들어:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "code", - "colab": {}, - "colab_type": "code", - "id": "ngUe237Wt48W" - }, - "outputs": [], - "source": [ - "print(tf.add(1, 2))\n", - "print(tf.add([1, 2], [3, 4]))\n", - "print(tf.square(5))\n", - "print(tf.reduce_sum([1, 2, 3]))\n", - "print(tf.encode_base64(\"hello world\"))\n", - "\n", - "# 연산자의 오버로딩(overloding) 또한 지원합니다.\n", - "print(tf.square(2) + tf.square(3))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "IDY4WsYRhP81" - }, - "source": [ - "각각의 텐서는 크기와 데이터 타입을 가지고 있습니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "srYWH1MdJNG7" - }, - "outputs": [], - "source": [ - "x = tf.matmul([[1]], [[2, 3]])\n", - "print(x.shape)\n", - "print(x.dtype)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "eBPw8e8vrsom" - }, - "source": [ - "넘파이 배열과 텐서플로 텐서의 가장 확연한 차이는 다음과 같습니다:\n", - "\n", - "1. `텐서`는 가속기 메모리(GPU, TPU와 같은)에서 사용할 수 있습니다.\n", - "2. `텐서`는 불변성(immutable)을 가집니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "Dwi1tdW3JBw6" - }, - "source": [ - "### 넘파이 호환성\n", - "\n", - "텐서와 넘파이 배열 사이의 변환은 다소 간단합니다.\n", - "\n", - "* 텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 변환합니다.\n", - "* 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 변환합니다.\n", - "\n", - "텐서는 `.numpy()` 메서드(method)를 호출하여 넘파이 배열로 변환할 수 있습니다.\n", - "가능한 경우, 텐서와 배열은 메모리 표현을 공유하기 때문에 이러한 변환은 일반적으로 간단(저렴)합니다. 그러나 텐서는 GPU 메모리에 저장될 수 있고, 넘파이 배열은 항상 호스트 메모리에 저장되므로, 이러한 변환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 필요합니다." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "lCUWzso6mbqR" - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "ndarray = np.ones([3, 3])\n", - "\n", - "print(\"텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 변환합니다.\")\n", - "tensor = tf.multiply(ndarray, 42)\n", - "print(tensor)\n", - "\n", - "\n", - "print(\"그리고 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 변환합니다.\")\n", - "print(np.add(tensor, 1))\n", - "\n", - "print(\".numpy() 메서드는 텐서를 넘파이 배열로 변환합니다.\")\n", - "print(tensor.numpy())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "PBNP8yTRfu_X" - }, - "source": [ - "## GPU 가속기\n", - "\n", - "대부분의 텐서플로 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 텐서를 CPU 와 GPU에 복사합니다.) 연산에 의해 생성된 텐서는 전형적으로 연산이 실행된 장치의 메모리에 의해 실행됩니다. 예를 들어:" - ] + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "eager_basics.ipynb", + "version": "0.3.2", + "provenance": [], + "private_outputs": true, + "collapsed_sections": [], + "toc_visible": true + }, + "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.7.1" + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + } }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "cellView": "code", - "colab": {}, - "colab_type": "code", - "id": "3Twf_Rw-gQFM" - }, - "outputs": [ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "iPpI7RaYoZuE" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors." + ] + }, + { + "cell_type": "code", + "metadata": { + "cellView": "form", + "colab_type": "code", + "id": "hro2InpHobKk", + "colab": {} + }, + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "U9i2Dsh-ziXr" + }, + "source": [ + "# 즉시 실행 기초" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Hndw-YcxoOJK" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " TensorFlow.org에서 보기\n", + " \n", + " 구글 코랩(Colab)에서 실행하기\n", + " \n", + " 깃허브(GitHub) 소스 보기\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D3iRBJ-xxfU3", + "colab_type": "text" + }, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도\n", + "불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다.\n", + "이 번역에 개선할 부분이 있다면\n", + "[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다.\n", + "문서 번역이나 리뷰에 참여하려면\n", + "[docs-ko@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs-ko)로\n", + "메일을 보내주시기 바랍니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "6sILUVbHoSgH" + }, + "source": [ + "이 노트북은 텐서플로를 사용하기 위한 입문 튜토리얼입니다. 다음 내용을 다룹니다 : \n", + "\n", + "* 필요한 패키지 임포트\n", + "* 텐서(Tensor) 생성 및 사용\n", + "* GPU 가속기 사용\n", + "* 데이터 세트" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "z1JcS5iBXMRO" + }, + "source": [ + "## 텐서플로 임포트\n", + "\n", + "시작하기 위해서 텐서플로 모듈을 임포트하고 즉시 실행(eager execution)을 활성화합니다. 즉시 실행 활성화로 텐서플로를 조금 더 대화형 프론트엔드(frontend)에 가깝게 만들어 줍니다. 세부사항은 나중에 이야기할 것입니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "cellView": "code", + "colab_type": "code", + "id": "RlIWhyeLoYnG", + "colab": {} + }, + "source": [ + "from __future__ import absolute_import, division, print_function\n", + "\n", + "import tensorflow as tf\n", + "\n", + "tf.enable_eager_execution()" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "H9UySOPLXdaw" + }, + "source": [ + "## 텐서\n", + "\n", + "텐서는 다차원 배열입니다. 넘파이(NumPy) `ndarray` 객체와 비슷하며, `Tensor` 객체는 데이터 타입과 크기를 가지고 있습니다. 또한 텐서는 GPU 같은 가속기 메모리에 상주할 수 있습니다. 텐서플로는 텐서를 생성하고 이용하는 풍부한 연산 라이브러리([tf.add](https://www.tensorflow.org/api_docs/python/tf/add), [tf.matmul](https://www.tensorflow.org/api_docs/python/tf/matmul), [tf.linalg.inv](https://www.tensorflow.org/api_docs/python/tf/linalg/inv) etc.)를 제공합니다. 이러한 연산자는 자동적으로 순수 파이썬 타입을 변환합니다. 예를 들어:\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "cellView": "code", + "colab_type": "code", + "id": "ngUe237Wt48W", + "colab": {} + }, + "source": [ + "print(tf.add(1, 2))\n", + "print(tf.add([1, 2], [3, 4]))\n", + "print(tf.square(5))\n", + "print(tf.reduce_sum([1, 2, 3]))\n", + "print(tf.encode_base64(\"hello world\"))\n", + "\n", + "# 연산자의 오버로딩(overloding) 또한 지원합니다.\n", + "print(tf.square(2) + tf.square(3))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "IDY4WsYRhP81" + }, + "source": [ + "각각의 텐서는 크기와 데이터 타입을 가지고 있습니다." + ] + }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "GPU를 사용가능한가 : \n", - "False\n", - "텐서가 GPU #0에 있는가 : \n", - "False\n" - ] + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "srYWH1MdJNG7", + "colab": {} + }, + "source": [ + "x = tf.matmul([[1]], [[2, 3]])\n", + "print(x.shape)\n", + "print(x.dtype)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "eBPw8e8vrsom" + }, + "source": [ + "넘파이 배열과 텐서플로 텐서의 가장 확연한 차이는 다음과 같습니다:\n", + "\n", + "1. `텐서`는 가속기 메모리(GPU, TPU와 같은)에서 사용할 수 있습니다.\n", + "2. `텐서`는 불변성(immutable)을 가집니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Dwi1tdW3JBw6" + }, + "source": [ + "### 넘파이 호환성\n", + "\n", + "텐서와 넘파이 배열 사이의 변환은 다소 간단합니다.\n", + "\n", + "* 텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 변환합니다.\n", + "* 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 변환합니다.\n", + "\n", + "텐서는 `.numpy()` 메서드(method)를 호출하여 넘파이 배열로 변환할 수 있습니다.\n", + "가능한 경우, 텐서와 배열은 메모리 표현을 공유하기 때문에 이러한 변환은 일반적으로 간단(저렴)합니다. 그러나 텐서는 GPU 메모리에 저장될 수 있고, 넘파이 배열은 항상 호스트 메모리에 저장되므로, 이러한 변환이 항상 가능한 것은 아닙니다. 따라서 GPU에서 호스트 메모리로의 복사가 필요합니다." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "lCUWzso6mbqR", + "colab": {} + }, + "source": [ + "import numpy as np\n", + "\n", + "ndarray = np.ones([3, 3])\n", + "\n", + "print(\"텐서플로 연산은 자동적으로 넘파이 배열을 텐서로 변환합니다.\")\n", + "tensor = tf.multiply(ndarray, 42)\n", + "print(tensor)\n", + "\n", + "\n", + "print(\"그리고 넘파이 연산은 자동적으로 텐서를 넘파이 배열로 변환합니다.\")\n", + "print(np.add(tensor, 1))\n", + "\n", + "print(\".numpy() 메서드는 텐서를 넘파이 배열로 변환합니다.\")\n", + "print(tensor.numpy())" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "PBNP8yTRfu_X" + }, + "source": [ + "## GPU 가속기\n", + "\n", + "대부분의 텐서플로 연산은 GPU를 사용하여 가속화할 수 있습니다. 어떠한 주석(annotation)도 없이, 텐서플로는 연산을 위해 자동적으로 CPU 또는 GPU를 사용할 것인지를 정합니다(그리고 필요시 텐서를 CPU 와 GPU에 복사합니다.) 연산에 의해 생성된 텐서는 전형적으로 연산이 실행된 장치의 메모리에 의해 실행됩니다. 예를 들어:" + ] + }, + { + "cell_type": "code", + "metadata": { + "cellView": "code", + "colab_type": "code", + "id": "3Twf_Rw-gQFM", + "colab": {} + }, + "source": [ + "x = tf.random_uniform([3, 3])\n", + "\n", + "print(\"GPU 사용이 가능한가 : \"),\n", + "print(tf.test.is_gpu_available())\n", + "\n", + "print(\"텐서가 GPU #0에 있는가 : \"),\n", + "print(x.device.endswith('GPU:0'))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "vpgYzgVXW2Ud" + }, + "source": [ + "### 장치 이름\n", + "\n", + "`Tensor.device`는 텐서를 구성하고 있는 호스트 장치의 풀네임을 제공합니다. 이러한 이름은 프로그램이 실행중인 호스트의 네트워크 주소 및 해당 호스트 내의 장치와 같은 많은 세부 정보를 인코딩하며, 이것은 텐서플로 프로그램의 분산 실행에 필요합니다. 텐서가 호스트의 `N`번째 GPU에 놓여지면 문자열은 `GPU:`으로 끝납니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "ZWZQCimzuqyP" + }, + "source": [ + "### 명시적 장치 배치\n", + "\n", + "텐서플로에서 \"배치(replacement)\"라는 용어는 개별 연산을 실행하기 위해 장치에 할당(배치) 하는 것입니다. 앞서 언급했듯이, 명시적 지침이 없을 경우 텐서플로는 연산을 실행하기 위한 장치를 자동으로 결정하고, 필요시 텐서를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. \n", + "예를 들어:" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "RjkNZTuauy-Q", + "colab": {} + }, + "source": [ + "import time\n", + "\n", + "def time_matmul(x):\n", + " start = time.time()\n", + " for loop in range(10):\n", + " tf.matmul(x, x)\n", + "\n", + " result = time.time()-start\n", + " \n", + " print(\"10 loops: {:0.2f}ms\".format(1000*result))\n", + "\n", + "\n", + "# CPU에서 강제실행합니다.\n", + "print(\"On CPU:\")\n", + "with tf.device(\"CPU:0\"):\n", + " x = tf.random_uniform([1000, 1000])\n", + " assert x.device.endswith(\"CPU:0\")\n", + " time_matmul(x)\n", + "\n", + "# GPU #0가 이용가능시 GPU #0에서 강제실행합니다.\n", + "if tf.test.is_gpu_available():\n", + " with tf.device(\"GPU:0\"): # 또는 GPU:1, GPU:2\n", + " x = tf.random_uniform([1000, 1000])\n", + " assert x.device.endswith(\"GPU:0\")\n", + " time_matmul(x)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "o1K4dlhhHtQj" + }, + "source": [ + "## 데이터셋\n", + "\n", + "이번 섹션에서는 모델에 데이터를 제공하기 위한 파이프라인을 구축하기 위해 [`tf.data.Dataset` API](https://www.tensorflow.org/guide/datasets)를 시연해볼 것입니다. 이는 다음을 포함합니다.\n", + "\n", + "* 데이터셋 생성.\n", + "* 즉시 실행 활성화를 통한 데이터셋 반복\n", + "\n", + "모델을 훈련시키고 평가 루프를 제공할 간단하고 재사용 가능한 모듈로부터, 복잡한 입력 파이프라인을 구축하기위해 데이터셋 API를 사용하기를 권장합니다. \n", + "\n", + "만약 텐서플로 그래프에 익숙하다면 알겠지만, 데이터셋 객체를 생성하기 위한 API는 즉시 실행이 활성화 되어도 동일하게 유지됩니다. 하지만 데이터셋의 요소를 반복하는 프로세스가 약간 더 간단해집니다.\n", + "또한 `tf.data.Dataset` 객체를 통하여 파이썬 반복문을 사용할 수 있으며, 명시적으로 `tf.data.Iterator` 객체를 생성할 필요가 없습니다.\n", + "그 결과, [텐서플로 가이드](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시 실행이 활성화될 때에는 신경 쓰지 않아도 됩니다. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "zI0fmOynH-Ne" + }, + "source": [ + "### 소스 Dataset 생성\n", + "\n", + "굉장히 유용한 함수중 하나인 [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices)와 같은 팩토리(factory) 함수 중 하나를 사용하거나 파일로부터 읽어들이는 객체인 [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) 또는 [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset)를 사용하여 소스 dataset을 생성하세요. 더 많은 정보를 위해서 [텐서플로 가이드](https://www.tensorflow.org/guide/datasets#reading_input_data)를 참조하세요." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "F04fVOHQIBiG", + "colab": {} + }, + "source": [ + "ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6])\n", + "\n", + "# CSV 파일을 생성합니다.\n", + "import tempfile\n", + "_, filename = tempfile.mkstemp()\n", + "\n", + "with open(filename, 'w') as f:\n", + " f.write(\"\"\"Line 1\n", + "Line 2\n", + "Line 3\n", + " \"\"\")\n", + "\n", + "ds_file = tf.data.TextLineDataset(filename)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "vbxIhC-5IPdf" + }, + "source": [ + "### 변환 적용\n", + "\n", + "[`맵(map)`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`배치(batch)`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`셔플(shuffle)`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle)과 같은 변환 함수를 사용하여 데이터셋의 레코드에 적용하세요. 세부사항은 [tf.data.Dataset을 위한 API 문서](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)을 참조하세요." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "uXSDZWE-ISsd", + "colab": {} + }, + "source": [ + "ds_tensors = ds_tensors.map(tf.square).shuffle(2).batch(2)\n", + "\n", + "ds_file = ds_file.batch(2)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "A8X1GNfoIZKJ" + }, + "source": [ + "### 반복\n", + "\n", + "즉시 실행이 활성화되면 `Dataset` 객체는 반복이 가능합니다. 만약 텐서플로 그래프에서 데이터셋을 사용하는게 익숙하다면, `Dataset.make_one_shot_iterator()` 또는 `get_next()`와 같은 객체를 호출할 필요가 없는다는 것에 주목하세요." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "ws-WKRk5Ic6-", + "colab": {} + }, + "source": [ + "print('ds_tensors 요소:')\n", + "for x in ds_tensors:\n", + " print(x)\n", + "\n", + "print('\\nds_file 요소:')\n", + "for x in ds_file:\n", + " print(x)" + ], + "execution_count": 0, + "outputs": [] } - ], - "source": [ - "x = tf.random_uniform([3, 3])\n", - "\n", - "print(\"GPU 사용이 가능한가 : \"),\n", - "print(tf.test.is_gpu_available())\n", - "\n", - "print(\"텐서가 GPU #0에 있는가 : \"),\n", - "print(x.device.endswith('GPU:0'))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "vpgYzgVXW2Ud" - }, - "source": [ - "### 장치 이름\n", - "\n", - "`Tensor.device`는 텐서를 구성하고 있는 호스트 장치의 풀네임을 제공합니다. 이러한 이름은 프로그램이 실행중인 호스트의 네트워크 주소 및 해당 호스트 내의 장치와 같은 많은 세부 정보를 인코딩하며, 이것은 텐서플로 프로그램의 분산 실행에 필요합니다. 텐서가 호스트의 `N`번째 GPU에 놓여지면 문자열은 `GPU:`으로 끝납니다." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "ZWZQCimzuqyP" - }, - "source": [ - "### 명시적 장치 배치\n", - "\n", - "텐서플로에서 \"배치(replacement)\"라는 용어는 개별 연산을 실행하기 위해 장치에 할당(배치) 하는 것입니다. 앞서 언급했듯이, 명시적 지침이 없을 경우 텐서플로는 연산을 실행하기 위한 장치를 자동으로 결정하고, 필요시 텐서를 장치에 복사합니다. 그러나 텐서플로 연산은 `tf.device`을 사용하여 특정한 장치에 명시적으로 배치할 수 있습니다. \n", - "예를 들어:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "RjkNZTuauy-Q" - }, - "outputs": [], - "source": [ - "import time\n", - "\n", - "def time_matmul(x):\n", - " start = time.time()\n", - " for loop in range(10):\n", - " tf.matmul(x, x)\n", - "\n", - " result = time.time()-start\n", - " \n", - " print(\"10 loops: {:0.2f}ms\".format(1000*result))\n", - "\n", - "\n", - "# CPU에서 강제실행합니다.\n", - "print(\"On CPU:\")\n", - "with tf.device(\"CPU:0\"):\n", - " x = tf.random_uniform([1000, 1000])\n", - " assert x.device.endswith(\"CPU:0\")\n", - " time_matmul(x)\n", - "\n", - "# GPU #0가 이용가능시 GPU #0에서 강제실행합니다.\n", - "if tf.test.is_gpu_available():\n", - " with tf.device(\"GPU:0\"): # 또는 GPU:1, GPU:2\n", - " x = tf.random_uniform([1000, 1000])\n", - " assert x.device.endswith(\"GPU:0\")\n", - " time_matmul(x)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "o1K4dlhhHtQj" - }, - "source": [ - "## 데이터셋\n", - "\n", - "이번 섹션에서는 모델에 데이터를 제공하기 위한 파이프라인을 구축하기 위해 [`tf.data.Dataset` API](https://www.tensorflow.org/guide/datasets)를 시연해볼 것입니다. 이는 다음을 포함합니다.\n", - "\n", - "* 데이터셋 생성.\n", - "* 즉시 실행 활성화를 통한 데이터셋 반복\n", - "\n", - "모델을 훈련시키고 평가 루프를 제공할 간단하고 재사용 가능한 모듈로부터, 복잡한 입력 파이프라인을 구축하기위해 데이터셋 API를 사용하기를 권장합니다. \n", - "\n", - "만약 텐서플로 그래프에 익숙하다면 알겠지만, 데이터셋 객체를 생성하기 위한 API는 즉시 실행이 활성화 되어도 동일하게 유지됩니다. 하지만 데이터셋의 요소를 반복하는 프로세스가 약간 더 간단해집니다.\n", - "또한 `tf.data.Dataset` 객체를 통하여 파이썬 반복문을 사용할 수 있으며, 명시적으로 `tf.data.Iterator` 객체를 생성할 필요가 없습니다.\n", - "그 결과, [텐서플로 가이드](https://www.tensorflow.org/guide/datasets)의 반복자(iterator)에 관한 논의는 즉시 실행이 활성화될 때에는 신경 쓰지 않아도 됩니다. " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "zI0fmOynH-Ne" - }, - "source": [ - "### 소스 Dataset 생성\n", - "\n", - "굉장히 유용한 함수중 하나인 [`Dataset.from_tensors`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensors), [`Dataset.from_tensor_slices`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_tensor_slices)와 같은 팩토리(factory) 함수 중 하나를 사용하거나 파일로부터 읽어들이는 객체인 [`TextLineDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TextLineDataset) 또는 [`TFRecordDataset`](https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset)를 사용하여 소스 dataset을 생성하세요. 더 많은 정보를 위해서 [텐서플로 가이드](https://www.tensorflow.org/guide/datasets#reading_input_data)를 참조하세요." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "F04fVOHQIBiG" - }, - "outputs": [], - "source": [ - "ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6])\n", - "\n", - "# CSV 파일을 생성합니다.\n", - "import tempfile\n", - "_, filename = tempfile.mkstemp()\n", - "\n", - "with open(filename, 'w') as f:\n", - " f.write(\"\"\"Line 1\n", - "Line 2\n", - "Line 3\n", - " \"\"\")\n", - "\n", - "ds_file = tf.data.TextLineDataset(filename)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "vbxIhC-5IPdf" - }, - "source": [ - "### 변환 적용\n", - "\n", - "[`맵(map)`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map), [`배치(batch)`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#batch), [`셔플(shuffle)`](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#shuffle)과 같은 변환 함수를 사용하여 데이터셋의 레코드에 적용하세요. 세부사항은 [tf.data.Dataset을 위한 API 문서](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)을 참조하세요." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "uXSDZWE-ISsd" - }, - "outputs": [], - "source": [ - "ds_tensors = ds_tensors.map(tf.square).shuffle(2).batch(2)\n", - "\n", - "ds_file = ds_file.batch(2)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "A8X1GNfoIZKJ" - }, - "source": [ - "### 반복\n", - "\n", - "즉시 실행이 활성화되면 `Dataset` 객체는 반복이 가능합니다. 만약 텐서플로 그래프에서 데이터셋을 사용하는게 익숙하다면, `Dataset.make_one_shot_iterator()` 또는 `get_next()`와 같은 객체를 호출할 필요가 없는다는 것에 주목하세요." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "ws-WKRk5Ic6-" - }, - "outputs": [], - "source": [ - "print('ds_tensors 요소:')\n", - "for x in ds_tensors:\n", - " print(x)\n", - "\n", - "print('\\nds_file 요소:')\n", - "for x in ds_file:\n", - " print(x)" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "name": "eager_basics.ipynb", - "private_outputs": true, - "provenance": [], - "toc_visible": true, - "version": "0.3.2" - }, - "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.7.1" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + ] +} \ No newline at end of file diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md index 114fc16091b..6ed0038c81a 100644 --- a/site/ko/tutorials/eager/index.md +++ b/site/ko/tutorials/eager/index.md @@ -1,12 +1,10 @@ # 연구 및 실험 -이 문서들은 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도 -불구하고 [공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다. -이 번역에 개선할 부분이 있다면 -[tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다. -문서 번역이나 리뷰에 지원하려면 [이 양식](https://bit.ly/tf-translate)을 -작성하거나 -[docs@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)로 +Note: 이 문서들은 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도 불구하고 +[공식 영문 문서](https://www.tensorflow.org/?hl=en)의 내용과 일치하지 않을 수 있습니다. 이 번역에 개선할 부분이 +있다면 [tensorflow/docs](https://github.com/tensorflow/docs) 깃헙 저장소로 풀 리퀘스트를 보내주시기 +바랍니다. 문서 번역이나 리뷰에 참여하려면 +[docs-ko@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs-ko)로 메일을 보내주시기 바랍니다. 즉시 실행(Eager execution)은 고급 연산을 위한 실행에 의해 정의되는 명령형 인터페이스를 제공합니다. @@ -18,4 +16,3 @@ 3. [사용자 정의 학습 : 기초](custom_training.ipynb) 4. [사용자 정의 층](custom_layers.ipynb) 5. [사용자 정의 학습 : 자세히 둘러보기](custom_training_walkthrough.ipynb) - From fd3ba6a879f73831b2ccee8aa0f10f3cedcd6b2d Mon Sep 17 00:00:00 2001 From: Billy Lamberta Date: Fri, 3 May 2019 10:48:27 -0700 Subject: [PATCH 19/19] Update en custom_trainging filename --- site/en/tutorials/eager/custom_training.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/en/tutorials/eager/custom_training.ipynb b/site/en/tutorials/eager/custom_training.ipynb index 805ae3b2dcb..d47a426140a 100644 --- a/site/en/tutorials/eager/custom_training.ipynb +++ b/site/en/tutorials/eager/custom_training.ipynb @@ -415,7 +415,7 @@ "metadata": { "colab": { "collapsed_sections": [], - "name": "Custom training: basics", + "name": "custom_training.ipynb", "private_outputs": true, "provenance": [], "toc_visible": true,