890 lines
25 KiB
Plaintext
890 lines
25 KiB
Plaintext
{
|
||
"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
|
||
}
|