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, diff --git a/site/ko/tutorials/eager/automatic_differentiation.ipynb b/site/ko/tutorials/eager/automatic_differentiation.ipynb new file mode 100644 index 00000000000..cdb4c100205 --- /dev/null +++ b/site/ko/tutorials/eager/automatic_differentiation.ipynb @@ -0,0 +1,341 @@ +{ + "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" + } + }, + "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 new file mode 100644 index 00000000000..98614aacbfa --- /dev/null +++ b/site/ko/tutorials/eager/custom_layers.ipynb @@ -0,0 +1,383 @@ +{ + "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" + } + }, + "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 new file mode 100644 index 00000000000..9fe7243b2f5 --- /dev/null +++ b/site/ko/tutorials/eager/custom_training.ipynb @@ -0,0 +1,470 @@ +{ + "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" + } + }, + "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 new file mode 100644 index 00000000000..a92ea88a33d --- /dev/null +++ b/site/ko/tutorials/eager/custom_training_walkthrough.ipynb @@ -0,0 +1,1120 @@ +{ + "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 new file mode 100644 index 00000000000..cdac5909049 --- /dev/null +++ b/site/ko/tutorials/eager/eager_basics.ipynb @@ -0,0 +1,483 @@ +{ + "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" + } + }, + "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": [ + "각각의 텐서는 크기와 데이터 타입을 가지고 있습니다." + ] + }, + { + "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": [] + } + ] +} \ No newline at end of file diff --git a/site/ko/tutorials/eager/index.md b/site/ko/tutorials/eager/index.md new file mode 100644 index 00000000000..6ed0038c81a --- /dev/null +++ b/site/ko/tutorials/eager/index.md @@ -0,0 +1,18 @@ +# 연구 및 실험 + +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)은 고급 연산을 위한 실행에 의해 정의되는 명령형 인터페이스를 제공합니다. +사용자 정의 층, 정방향 전파, 자동 미분을 사용한 훈련 루프를 작성하세요. 이 노트북으로 보고 난 후에 다음 문서를 읽어보세요. +[즉시 실행 가이드](../../guide/eager). + +1. [즉시 실행](eager_basics.ipynb) +2. [자동 미분과 그래디언트 테이프](automatic_differentiation.ipynb) +3. [사용자 정의 학습 : 기초](custom_training.ipynb) +4. [사용자 정의 층](custom_layers.ipynb) +5. [사용자 정의 학습 : 자세히 둘러보기](custom_training_walkthrough.ipynb)