{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPython 3.6.5\n", "IPython 6.4.0\n", "\n", "numpy 1.14.3\n", "sklearn 0.19.1\n", "scipy 1.1.0\n", "matplotlib 2.2.2\n", "tensorflow 1.8.0\n" ] } ], "source": [ "%load_ext watermark\n", "%watermark -v -p numpy,sklearn,scipy,matplotlib,tensorflow" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**12장 – 분산 텐서플로**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "_이 노트북은 11장에 있는 모든 샘플 코드와 연습문제 해답을 가지고 있습니다._" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 설정" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "파이썬 2와 3을 모두 지원합니다. 공통 모듈을 임포트하고 맷플롯립 그림이 노트북 안에 포함되도록 설정하고 생성한 그림을 저장하기 위한 함수를 준비합니다:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# 파이썬 2와 파이썬 3 지원\n", "from __future__ import division, print_function, unicode_literals\n", "\n", "# 공통\n", "import numpy as np\n", "import os\n", "\n", "# 일관된 출력을 위해 유사난수 초기화\n", "def reset_graph(seed=42):\n", " tf.reset_default_graph()\n", " tf.set_random_seed(seed)\n", " np.random.seed(seed)\n", "\n", "# 맷플롯립 설정\n", "%matplotlib inline\n", "import matplotlib\n", "import matplotlib.pyplot as plt\n", "plt.rcParams['axes.labelsize'] = 14\n", "plt.rcParams['xtick.labelsize'] = 12\n", "plt.rcParams['ytick.labelsize'] = 12\n", "\n", "# 그림을 저장할 폴더\n", "PROJECT_ROOT_DIR = \".\"\n", "CHAPTER_ID = \"distributed\"\n", "\n", "def save_fig(fig_id, tight_layout=True):\n", " path = os.path.join(PROJECT_ROOT_DIR, \"images\", CHAPTER_ID, fig_id + \".png\")\n", " if tight_layout:\n", " plt.tight_layout()\n", " plt.savefig(path, format='png', dpi=300)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 로컬 서버" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import tensorflow as tf" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "c = tf.constant(\"Hello distributed TensorFlow!\")\n", "server = tf.train.Server.create_local_server()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'Hello distributed TensorFlow!'\n" ] } ], "source": [ "with tf.Session(server.target) as sess:\n", " print(sess.run(c))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 클러스터" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "cluster_spec = tf.train.ClusterSpec({\n", " \"ps\": [\n", " \"127.0.0.1:2221\", # /job:ps/task:0\n", " \"127.0.0.1:2222\", # /job:ps/task:1\n", " ],\n", " \"worker\": [\n", " \"127.0.0.1:2223\", # /job:worker/task:0\n", " \"127.0.0.1:2224\", # /job:worker/task:1\n", " \"127.0.0.1:2225\", # /job:worker/task:2\n", " ]})" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "task_ps0 = tf.train.Server(cluster_spec, job_name=\"ps\", task_index=0)\n", "task_ps1 = tf.train.Server(cluster_spec, job_name=\"ps\", task_index=1)\n", "task_worker0 = tf.train.Server(cluster_spec, job_name=\"worker\", task_index=0)\n", "task_worker1 = tf.train.Server(cluster_spec, job_name=\"worker\", task_index=1)\n", "task_worker2 = tf.train.Server(cluster_spec, job_name=\"worker\", task_index=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 여러 디바이스와 서버에 연산을 할당하기" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "reset_graph()\n", "\n", "with tf.device(\"/job:ps\"):\n", " a = tf.Variable(1.0, name=\"a\")\n", "\n", "with tf.device(\"/job:worker\"):\n", " b = a + 2\n", "\n", "with tf.device(\"/job:worker/task:1\"):\n", " c = a + b" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4.0\n" ] } ], "source": [ "with tf.Session(\"grpc://127.0.0.1:2221\") as sess:\n", " sess.run(a.initializer)\n", " print(c.eval())" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "reset_graph()\n", "\n", "with tf.device(tf.train.replica_device_setter(\n", " ps_tasks=2,\n", " ps_device=\"/job:ps\",\n", " worker_device=\"/job:worker\")):\n", " v1 = tf.Variable(1.0, name=\"v1\") # /job:ps/task:0 (defaults to /cpu:0) 에 할당\n", " v2 = tf.Variable(2.0, name=\"v2\") # /job:ps/task:1 (defaults to /cpu:0) 에 할당\n", " v3 = tf.Variable(3.0, name=\"v3\") # /job:ps/task:0 (defaults to /cpu:0) 에 할당\n", " s = v1 + v2 # /job:worker (defaults to task:0/cpu:0) 에 할당\n", " with tf.device(\"/task:1\"):\n", " p1 = 2 * s # /job:worker/task:1 (defaults to /cpu:0) 에 할당\n", " with tf.device(\"/cpu:0\"):\n", " p2 = 3 * s # /job:worker/task:1/cpu:0 에 할당\n", "\n", "config = tf.ConfigProto()\n", "config.log_device_placement = True\n", "\n", "with tf.Session(\"grpc://127.0.0.1:2221\", config=config) as sess:\n", " v1.initializer.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 리더 (Reader) - 예전 방법" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1.0, 6, 44]\n" ] } ], "source": [ "reset_graph()\n", "\n", "default1 = tf.constant([5.])\n", "default2 = tf.constant([6])\n", "default3 = tf.constant([7])\n", "dec = tf.decode_csv(tf.constant(\"1.,,44\"),\n", " record_defaults=[default1, default2, default3])\n", "with tf.Session() as sess:\n", " print(sess.run(dec))" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "더 이상 읽을 파일이 없습니다\n", "[array([[ 4., 5.],\n", " [ 1., -1.]], dtype=float32), array([1, 0], dtype=int32)]\n", "[array([[7., 8.]], dtype=float32), array([0], dtype=int32)]\n", "더 이상 훈련 샘플이 없습니다\n" ] } ], "source": [ "reset_graph()\n", "\n", "test_csv = open(\"my_test.csv\", \"w\")\n", "test_csv.write(\"x1, x2 , target\\n\")\n", "test_csv.write(\"1.,, 0\\n\")\n", "test_csv.write(\"4., 5. , 1\\n\")\n", "test_csv.write(\"7., 8. , 0\\n\")\n", "test_csv.close()\n", "\n", "filename_queue = tf.FIFOQueue(capacity=10, dtypes=[tf.string], shapes=[()])\n", "filename = tf.placeholder(tf.string)\n", "enqueue_filename = filename_queue.enqueue([filename])\n", "close_filename_queue = filename_queue.close()\n", "\n", "reader = tf.TextLineReader(skip_header_lines=1)\n", "key, value = reader.read(filename_queue)\n", "\n", "x1, x2, target = tf.decode_csv(value, record_defaults=[[-1.], [-1.], [-1]])\n", "features = tf.stack([x1, x2])\n", "\n", "instance_queue = tf.RandomShuffleQueue(\n", " capacity=10, min_after_dequeue=2,\n", " dtypes=[tf.float32, tf.int32], shapes=[[2],[]],\n", " name=\"instance_q\", shared_name=\"shared_instance_q\")\n", "enqueue_instance = instance_queue.enqueue([features, target])\n", "close_instance_queue = instance_queue.close()\n", "\n", "minibatch_instances, minibatch_targets = instance_queue.dequeue_up_to(2)\n", "\n", "with tf.Session() as sess:\n", " sess.run(enqueue_filename, feed_dict={filename: \"my_test.csv\"})\n", " sess.run(close_filename_queue)\n", " try:\n", " while True:\n", " sess.run(enqueue_instance)\n", " except tf.errors.OutOfRangeError as ex:\n", " print(\"더 이상 읽을 파일이 없습니다\")\n", " sess.run(close_instance_queue)\n", " try:\n", " while True:\n", " print(sess.run([minibatch_instances, minibatch_targets]))\n", " except tf.errors.OutOfRangeError as ex:\n", " print(\"더 이상 훈련 샘플이 없습니다\")" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "#coord = tf.train.Coordinator()\n", "#threads = tf.train.start_queue_runners(coord=coord)\n", "#filename_queue = tf.train.string_input_producer([\"test.csv\"])\n", "#coord.request_stop()\n", "#coord.join(threads)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# QueueRunner와 Coordinator" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[array([[ 7., 8.],\n", " [ 1., -1.]], dtype=float32), array([0, 0], dtype=int32)]\n", "[array([[4., 5.]], dtype=float32), array([1], dtype=int32)]\n", "더 이상 훈련 샘플이 없습니다\n" ] } ], "source": [ "reset_graph()\n", "\n", "filename_queue = tf.FIFOQueue(capacity=10, dtypes=[tf.string], shapes=[()])\n", "filename = tf.placeholder(tf.string)\n", "enqueue_filename = filename_queue.enqueue([filename])\n", "close_filename_queue = filename_queue.close()\n", "\n", "reader = tf.TextLineReader(skip_header_lines=1)\n", "key, value = reader.read(filename_queue)\n", "\n", "x1, x2, target = tf.decode_csv(value, record_defaults=[[-1.], [-1.], [-1]])\n", "features = tf.stack([x1, x2])\n", "\n", "instance_queue = tf.RandomShuffleQueue(\n", " capacity=10, min_after_dequeue=2,\n", " dtypes=[tf.float32, tf.int32], shapes=[[2],[]],\n", " name=\"instance_q\", shared_name=\"shared_instance_q\")\n", "enqueue_instance = instance_queue.enqueue([features, target])\n", "close_instance_queue = instance_queue.close()\n", "\n", "minibatch_instances, minibatch_targets = instance_queue.dequeue_up_to(2)\n", "\n", "n_threads = 5\n", "queue_runner = tf.train.QueueRunner(instance_queue, [enqueue_instance] * n_threads)\n", "coord = tf.train.Coordinator()\n", "\n", "with tf.Session() as sess:\n", " sess.run(enqueue_filename, feed_dict={filename: \"my_test.csv\"})\n", " sess.run(close_filename_queue)\n", " enqueue_threads = queue_runner.create_threads(sess, coord=coord, start=True)\n", " try:\n", " while True:\n", " print(sess.run([minibatch_instances, minibatch_targets]))\n", " except tf.errors.OutOfRangeError as ex:\n", " print(\"더 이상 훈련 샘플이 없습니다\")" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[array([[ 4., 5.],\n", " [ 1., -1.]], dtype=float32), array([1, 0], dtype=int32)]\n", "[array([[7., 8.]], dtype=float32), array([0], dtype=int32)]\n", "더 이상 훈련 샘플이 없습니다\n" ] } ], "source": [ "reset_graph()\n", "\n", "def read_and_push_instance(filename_queue, instance_queue):\n", " reader = tf.TextLineReader(skip_header_lines=1)\n", " key, value = reader.read(filename_queue)\n", " x1, x2, target = tf.decode_csv(value, record_defaults=[[-1.], [-1.], [-1]])\n", " features = tf.stack([x1, x2])\n", " enqueue_instance = instance_queue.enqueue([features, target])\n", " return enqueue_instance\n", "\n", "filename_queue = tf.FIFOQueue(capacity=10, dtypes=[tf.string], shapes=[()])\n", "filename = tf.placeholder(tf.string)\n", "enqueue_filename = filename_queue.enqueue([filename])\n", "close_filename_queue = filename_queue.close()\n", "\n", "instance_queue = tf.RandomShuffleQueue(\n", " capacity=10, min_after_dequeue=2,\n", " dtypes=[tf.float32, tf.int32], shapes=[[2],[]],\n", " name=\"instance_q\", shared_name=\"shared_instance_q\")\n", "\n", "minibatch_instances, minibatch_targets = instance_queue.dequeue_up_to(2)\n", "\n", "read_and_enqueue_ops = [read_and_push_instance(filename_queue, instance_queue) for i in range(5)]\n", "queue_runner = tf.train.QueueRunner(instance_queue, read_and_enqueue_ops)\n", "\n", "with tf.Session() as sess:\n", " sess.run(enqueue_filename, feed_dict={filename: \"my_test.csv\"})\n", " sess.run(close_filename_queue)\n", " coord = tf.train.Coordinator()\n", " enqueue_threads = queue_runner.create_threads(sess, coord=coord, start=True)\n", " try:\n", " while True:\n", " print(sess.run([minibatch_instances, minibatch_targets]))\n", " except tf.errors.OutOfRangeError as ex:\n", " print(\"더 이상 훈련 샘플이 없습니다\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 타임아웃 지정하기" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.0\n", "6.0\n", "3.0\n", "4.0\n", "dequeue 타임 아웃\n" ] } ], "source": [ "reset_graph()\n", "\n", "q = tf.FIFOQueue(capacity=10, dtypes=[tf.float32], shapes=[()])\n", "v = tf.placeholder(tf.float32)\n", "enqueue = q.enqueue([v])\n", "dequeue = q.dequeue()\n", "output = dequeue + 1\n", "\n", "config = tf.ConfigProto()\n", "config.operation_timeout_in_ms = 1000\n", "\n", "with tf.Session(config=config) as sess:\n", " sess.run(enqueue, feed_dict={v: 1.0})\n", " sess.run(enqueue, feed_dict={v: 2.0})\n", " sess.run(enqueue, feed_dict={v: 3.0})\n", " print(sess.run(output))\n", " print(sess.run(output, feed_dict={dequeue: 5}))\n", " print(sess.run(output))\n", " print(sess.run(output))\n", " try:\n", " print(sess.run(output))\n", " except tf.errors.DeadlineExceededError as ex:\n", " print(\"dequeue 타임 아웃\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Data API" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "텐서플로 1.4에서 소개된 Data API를 사용하면 손쉽게 데이터를 효율적으로 읽을 수 있습니다." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "tf.reset_default_graph()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "0에서 9까지 정수를 세 번 반복한 간단한 데이터셋을 일곱 개씩 배치로 만들어 시작해 보죠:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "dataset = tf.data.Dataset.from_tensor_slices(np.arange(10))\n", "dataset = dataset.repeat(3).batch(7)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "첫 번째 줄은 0에서 9까지 정수를 담은 데이터셋을 만듭니다. 두 번째 줄은 이 데이터셋의 원소를 세 번 반복하고 일곱 개씩 담은 새로운 데이터셋을 만듭니다. 위에서 볼 수 있듯이 원본 데이터셋에서 여러 변환 메서드를 연결하여 호출하여 적용했습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "그다음, 데이터셋을 한 번 순회하는 원-샷-이터레이터(one-shot-iterator)를 만들고, 다음 원소를 지칭하는 텐서를 얻기 위해 `get_next()` 메서드를 호출합니다." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "iterator = dataset.make_one_shot_iterator()\n", "next_element = iterator.get_next()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`next_element`를 반복적으로 평가해서 데이터셋을 순회해 보죠. 원소가 별로 없기 때문에 `OutOfRangeError`가 발생합니다:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0 1 2 3 4 5 6]\n", "[7 8 9 0 1 2 3]\n", "[4 5 6 7 8 9 0]\n", "[1 2 3 4 5 6 7]\n", "[8 9]\n", "완료\n" ] } ], "source": [ "with tf.Session() as sess:\n", " try:\n", " while True:\n", " print(next_element.eval())\n", " except tf.errors.OutOfRangeError:\n", " print(\"완료\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "좋네요! 잘 작동합니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "늘 그렇듯이 텐서는 그래프를 실행(`sess.run()`)할 때마다 한 번만 평가된다는 것을 기억하세요. `next_element`에 의존하는 텐서를 여러개 평가하더라도 한 번만 평가됩니다. 또한 `next_element`를 동시에 두 번 실행해도 마찬가지입니다:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[array([0, 1, 2, 3, 4, 5, 6]), array([0, 1, 2, 3, 4, 5, 6])]\n", "[array([7, 8, 9, 0, 1, 2, 3]), array([7, 8, 9, 0, 1, 2, 3])]\n", "[array([4, 5, 6, 7, 8, 9, 0]), array([4, 5, 6, 7, 8, 9, 0])]\n", "[array([1, 2, 3, 4, 5, 6, 7]), array([1, 2, 3, 4, 5, 6, 7])]\n", "[array([8, 9]), array([8, 9])]\n", "완료\n" ] } ], "source": [ "with tf.Session() as sess:\n", " try:\n", " while True:\n", " print(sess.run([next_element, next_element]))\n", " except tf.errors.OutOfRangeError:\n", " print(\"완료\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`interleave()` 메서드는 강력하지만 처음에는 이해하기 좀 어렵습니다. 예제를 통해 이해하는 것이 가장 좋습니다:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "tf.reset_default_graph()" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "dataset = tf.data.Dataset.from_tensor_slices(np.arange(10))\n", "dataset = dataset.repeat(3).batch(7)\n", "dataset = dataset.interleave(\n", " lambda v: tf.data.Dataset.from_tensor_slices(v),\n", " cycle_length=3,\n", " block_length=2)\n", "iterator = dataset.make_one_shot_iterator()\n", "next_element = iterator.get_next()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0,1,7,8,4,5,2,3,9,0,6,7,4,5,1,2,8,9,6,3,0,1,2,8,9,3,4,5,6,7,완료\n" ] } ], "source": [ "with tf.Session() as sess:\n", " try:\n", " while True:\n", " print(next_element.eval(), end=\",\")\n", " except tf.errors.OutOfRangeError:\n", " print(\"완료\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`cycle_length=3`이므로 새로운 데이터셋은 이전 데이터셋에서 세 개의 원소를 추출합니다. 즉 `[0,1,2,3,4,5,6]`, `[7,8,9,0,1,2,3]`, `[4,5,6,7,8,9,0]` 입니다. 그다음 원소마다 하나의 데이터셋을 만들기 위해 람다(lambda) 함수를 호출합니다. `Dataset.from_tensor_slices()`를 사용했기 때문에 각 데이터셋은 차례대로 원소를 반환합니다. 다음 이 세 개의 데이터셋에서 각각 두 개의 아이템(`block_length=2`이므로)을 추출합니다. 세 개의 데이터셋의 아이템이 모두 소진될 때까지 반복됩니다. 즉 0,1 (첫 번째에서), 7,8 (두 번째에서), 4,5 (세 번째에서), 2,3 (첫 번째에서), 9,0 (두 번째에서) 등과 같은 식으로 8,9 (세 번째에서), 6 (첫 번째에서), 3 (두 번째에서), 0 (세 번째에서)까지 진행됩니다. 그다음에 원본 데이터셋에서 다음 번 세 개의 원소를 추출하려고 합니다. 하지만 두 개만 남아 있습니다. `[1,2,3,4,5,6,7]`와 `[8,9]` 입니다. 다시 이 원소로부터 데이터셋을 만들고 이 데이텃세의 아이템이 모두 소진될 때까지 두 개의 아이템을 추출합니다. 1,2 (첫 번째에서), 8,9 (두 번째에서), 3,4 (첫 번째에서), 5,6 (첫 번째에서), 7 (첫 번째에서)가 됩니다. 배열의 길이가 다르기 때문에 마지막에는 교대로 배치되지 않았습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 리더 (Reader) - 새로운 방법" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`from_tensor_slices()`나 `from_tensor()`를 기반으로 한 원본 데이터셋을 사용하는 대신 리더 데이터셋을 사용할 수 있습니다. 복잡한 일들을 대부분 대신 처리해 줍니다(예를 들면, 스레드):" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "tf.reset_default_graph()" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "filenames = [\"my_test.csv\"]" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "dataset = tf.data.TextLineDataset(filenames)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "각 줄을 어떻게 디코드해야 하는지는 알려 주어야 합니다:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "def decode_csv_line(line):\n", " x1, x2, y = tf.decode_csv(\n", " line, record_defaults=[[-1.], [-1.], [-1.]])\n", " X = tf.stack([x1, x2])\n", " return X, y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "그다음, 이 디코딩 함수를 `map()`을 사용하여 데이터셋에 있는 각 원소에 적용할 수 있습니다:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "dataset = dataset.skip(1).map(decode_csv_line)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "마지막으로 원-샷-이터레이터를 만들어 보죠:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "it = dataset.make_one_shot_iterator()\n", "X, y = it.get_next()" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 1. -1.] 0.0\n", "[4. 5.] 1.0\n", "[7. 8.] 0.0\n", "완료\n" ] } ], "source": [ "with tf.Session() as sess:\n", " try:\n", " while True:\n", " X_val, y_val = sess.run([X, y])\n", " print(X_val, y_val)\n", " except tf.errors.OutOfRangeError as ex:\n", " print(\"완료\")" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "# 연습문제 해답" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Coming soon**" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" }, "nav_menu": {}, "toc": { "navigate_menu": true, "number_sections": true, "sideBar": true, "threshold": 6, "toc_cell": false, "toc_section_display": "block", "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 1 }