diff --git a/examples/debug_with_dashboard.ipynb b/examples/debug_with_dashboard.ipynb new file mode 100644 index 0000000..148e793 --- /dev/null +++ b/examples/debug_with_dashboard.ipynb @@ -0,0 +1,972 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Dashboard Overview\n", + "\n", + "This notebook walks though some examples to show the functinoality of ray dashboard. \n", + "\n", + "There are two views:\n", + "1. Machine View, which groups actors by nodes. Information about occupied and total memory, resources, node ip address, logs, errors, etc. will be displayed. \n", + "2. Logical View, which gorups actors by the hierachical structure. Actor `A` is the parent of actor `B` if `A` creates `B`. In this case, actor `B` will be placed as a nested actor of `A`. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-24 15:21:10,546\tINFO resource_spec.py:212 -- Starting Ray with 3.71 GiB memory available for workers and up to 1.88 GiB for objects. You can adjust these settings with ray.init(memory=, object_store_memory=).\n", + "2020-01-24 15:21:10,797\tINFO services.py:1093 -- View the Ray dashboard at \u001b[1m\u001b[32mlocalhost:8273\u001b[39m\u001b[22m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Click here to open the dashboard: http://localhost:8273\n" + ] + } + ], + "source": [ + "import ray\n", + "import os\n", + "import time\n", + "import numpy as np\n", + "import requests\n", + "\n", + "addresses = ray.init()\n", + "print(\"Click here to open the dashboard: http://{}\".format(addresses[\"webui_url\"]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Debug blocked actor creation tasks\n", + "\n", + "If creating an actor requires resources (e.g. CPUs, GPUs, other custom resources) that are not currently available, the actor creation task becomes infeasible. It might causes hanging programs. \n", + "\n", + "To make developers aware of this issue, infeasible tasks are shown in red in the dashboard. \n", + "\n", + "![title](img/infeasible-task.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-24 15:24:29,294\tWARNING worker.py:1063 -- The actor or task with ID ffffffffffffffff1cc4b74c0100 is infeasible and cannot currently be scheduled. It requires {Custom: 1.000000} for execution and {Custom: 1.000000} for placement, however there are no nodes in the cluster that can provide the requested resources. To resolve this issue, consider reducing the resource requests of this task or add nodes that can fit the task.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Session hangs because actor A cannot be created. \n" + ] + } + ], + "source": [ + "@ray.remote(resources={\"Custom\": 1}, num_cpus=0)\n", + "class A(object):\n", + " def __init__(self):\n", + " pass\n", + " \n", + " def f(self):\n", + " return 0\n", + " \n", + "@ray.remote\n", + "class B(object):\n", + " def __init__(self, x, y):\n", + " self.a = A.remote()\n", + " \n", + " def f(self):\n", + " return ray.get(self.a.f.remote())\n", + "\n", + "b = B.remote(3, y=5)\n", + "\n", + "try:\n", + " ray.get(b.f.remote(), timeout=2)\n", + "except ray.exceptions.RayTimeoutError:\n", + " print(\"Session hangs because actor A cannot be created. \")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Inspect local memory usage\n", + "\n", + "The dashboard shows the following informaiton of local memory usage:\n", + "- Number of object ids in scope\n", + "- Number of local objects\n", + "- Used Object Memory\n", + " \n", + "In the example below, all objects (strings) are stored in local object memory. Used local object memory increases as the remote function `g` is repeatedly called. \n", + "\n", + "![title](img/local-memory-usage.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "@ray.remote\n", + "def g():\n", + " return \"hello world!\"\n", + "\n", + "@ray.remote\n", + "class A(object):\n", + " def f(self):\n", + " object_ids = []\n", + " for idx in range(50):\n", + " ray.show_in_webui(\"Loop index = {}...\".format(idx))\n", + " object_ids.append(g.remote())\n", + " time.sleep(0.5)\n", + "\n", + "a = A.remote()\n", + "_ = a.f.remote()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Inspect node memory usage\n", + "\n", + "Different from above example, used local object memory will alwasy be zero here because all objects (strings) are stored on the node. \n", + "\n", + "![title](img/node-memory-usage.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "@ray.remote\n", + "class C(object):\n", + " def __init__(self):\n", + " self.object_ids = []\n", + " \n", + " def push(self):\n", + " object_id = ray.put(\"test\")\n", + " self.object_ids.append(object_id)\n", + " time.sleep(1)\n", + " return object_id\n", + " \n", + " def clean_memory(self):\n", + " del self.object_ids\n", + " \n", + "@ray.remote\n", + "class D(object):\n", + " def __init__(self):\n", + " self.object_ids = []\n", + " \n", + " def fetch(self):\n", + " c = C.remote()\n", + " \n", + " for idx in range(20):\n", + " ray.show_in_webui(\"Loop index = {}...\".format(idx))\n", + " time.sleep(0.5)\n", + " object_id = ray.get(c.push.remote())\n", + " self.object_ids.append(object_id) \n", + "\n", + " def clean_memory(self):\n", + " del self.object_ids\n", + " \n", + "d = D.remote()\n", + "_ = d.fetch.remote()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following command clears out the number of object ids in scope for actor `d`, as all object ids become out of scope after `self.object_ids` is deleted. The field `NumObjectIdInScope` will be set to 0 on the dashboard. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "_ = d.clean_memory.remote()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Profile python program with py-spy\n", + "\n", + "Clicking the `profling` button on the dashboard launches `py-spy` that times your python program. The timing information will be visualized as flamegraph in a new browser tab. \n", + "\n", + "Checkout the example Learning to play Pong on ray documentation: https://ray.readthedocs.io/en/latest/auto_examples/plot_pong_example.html\n", + "\n", + "Click `profiling`, and click `Profiling result` when it is ready. Note that there could be multiple threads in the process and some are ray internal threads and the timing information may not be so interesting. Click the left and right arrow on the middle top to see profiling results on different threads.\n", + "\n", + "Now you can intuitively see where could be the computation bottleneck. More information on how to interpret the flamegraph is available at https://github.com/jlfwong/speedscope#usage.\n", + "\n", + "![title](img/profiling.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example\n", + "\n", + "The logical view of the dashboard allows users to track the progress (training accuracy, constructor configuration, memory usage, etc.) of all parallel actors." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 1: Monitor distributed actors\n", + "\n", + "Reference: github issue #3609, @EricSteinberger\n", + "\n", + "In this example, the dashboard displays parallel actors and report the number of tasks each actor has completed, the name of the task currently executed and the number of tasks pending on the queue. Click `collapse` if an actor spawns too many child actors. \n", + "\n", + "![title](img/example-1.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test: num_actors = 4, time = 14.119410037994385\n" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "\n", + "class NeuralNet(torch.nn.Module):\n", + " def __init__(self):\n", + " super().__init__()\n", + " self.l = torch.nn.Linear(1000, 2048)\n", + " self.l2 = torch.nn.Linear(2048, 2)\n", + "\n", + " def forward(self, x):\n", + " return self.l2(self.l(x))\n", + "\n", + "\n", + "@ray.remote(num_cpus=1)\n", + "class TestActor:\n", + " def __init__(self):\n", + " self.net = NeuralNet()\n", + "\n", + " def test(self, batch_size):\n", + " p = self.net(torch.rand((batch_size, 1000),))\n", + " \n", + "def test(num_actors):\n", + " t = time.time()\n", + " actors = [TestActor.remote() for _ in range(num_actors)]\n", + "\n", + " t = time.time()\n", + " for _ in range(5000//num_actors):\n", + " ray.get([actor.test.remote(128) for actor in actors])\n", + " \n", + " print(f\"Test: num_actors = {num_actors}, time = {time.time() - t}\")\n", + "\n", + "test(num_actors=4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 2: Distributed network training" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Reference: github issue #6633, @JaeLiiin\n", + "\n", + "![title](img/example-2.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "%%capture\n", + "\n", + "from tensorflow.keras import layers\n", + "import json\n", + "\n", + "\n", + "def create_keras_model():\n", + " import tensorflow as tf\n", + " model = tf.keras.Sequential()\n", + " # Adds a densely-connected layer with 64 units to the model:\n", + " model.add(layers.Dense(64, activation=\"relu\", input_shape=(32, )))\n", + " # Add another:\n", + " model.add(layers.Dense(64, activation=\"relu\"))\n", + " # Add a softmax layer with 10 output units:\n", + " model.add(layers.Dense(10, activation=\"softmax\"))\n", + "\n", + " model.compile(\n", + " optimizer=tf.keras.optimizers.RMSprop(0.01),\n", + " loss=tf.keras.losses.categorical_crossentropy,\n", + " metrics=[tf.keras.metrics.categorical_accuracy])\n", + " return model\n", + "\n", + "\n", + "def random_one_hot_labels(shape):\n", + " n, n_class = shape\n", + " classes = np.random.randint(0, n_class, n)\n", + " labels = np.zeros((n, n_class))\n", + " labels[np.arange(n), classes] = 1\n", + " return labels\n", + "\n", + "\n", + "@ray.remote\n", + "class Network(object):\n", + " def __init__(self):\n", + " self.model = create_keras_model()\n", + " self.dataset = np.random.random((1000, 32))\n", + " self.labels = random_one_hot_labels((1000, 10))\n", + "\n", + " def train(self):\n", + " history = self.model.fit(self.dataset, self.labels, verbose=False)\n", + " time.sleep(0.5)\n", + " ray.show_in_webui(repr(history.history))\n", + " return history.history\n", + "\n", + " def get_weights(self):\n", + " return self.model.get_weights()\n", + "\n", + " def set_weights(self, weights):\n", + " # Note that for simplicity this does not handle the optimizer state.\n", + " self.model.set_weights(weights)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "%%capture\n", + "\n", + "result_object_ids = []\n", + "result2_object_ids = []\n", + "\n", + "NetworkActor = Network.remote()\n", + "NetworkActor2 = Network.remote()\n", + "\n", + "for itr in range(20):\n", + " weights = ray.get(\n", + " [NetworkActor.get_weights.remote(),\n", + " NetworkActor2.get_weights.remote()])\n", + "\n", + " averaged_weights = [(layer1 + layer2) / 2\n", + " for layer1, layer2 in zip(weights[0], weights[1])]\n", + "\n", + " weight_id = ray.put(averaged_weights)\n", + " [\n", + " actor.set_weights.remote(weight_id)\n", + " for actor in [NetworkActor, NetworkActor2]\n", + " ]\n", + " result_object_ids.append(NetworkActor.train.remote())\n", + " result2_object_ids.append(NetworkActor2.train.remote())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 3: monitor MNIST training with tune\n", + "- Actor construction which exposes parameter configuration\n", + "- Task execution\n", + " - Number of tasks executed\n", + " - Function descriptor of currently executed task\n", + " - Number of pending tasks listed on the task queue\n", + "- Training accuracy shown as actor message\n", + "\n", + "![title](img/example-3.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-24 15:43:27,856\tINFO function_runner.py:250 -- tune.track signature detected.\n", + "2020-01-24 15:43:27,869\tERROR logger.py:328 -- pip install 'ray[tune]' to see TensorBoard files.\n", + "2020-01-24 15:43:27,869\tWARNING logger.py:417 -- Could not instantiate TBXLogger: No module named 'tensorboardX'.\n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 10.1/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 1/16 CPUs, 0/0 GPUs, 0.0/3.71 GiB heap, 0.0/1.27 GiB objects
Result logdir: /Users/yunzhi/ray_results/train_mnist
Number of trials: 3 (1 RUNNING, 2 PENDING)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc lr
train_mnist_51d5e2c2RUNNING
train_mnist_51d60950PENDING
train_mnist_51d627e6PENDING


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-24 15:43:27,892\tERROR logger.py:328 -- pip install 'ray[tune]' to see TensorBoard files.\n", + "2020-01-24 15:43:27,893\tWARNING logger.py:417 -- Could not instantiate TBXLogger: No module named 'tensorboardX'.\n", + "2020-01-24 15:43:27,913\tERROR logger.py:328 -- pip install 'ray[tune]' to see TensorBoard files.\n", + "2020-01-24 15:43:27,914\tWARNING logger.py:417 -- Could not instantiate TBXLogger: No module named 'tensorboardX'.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result for train_mnist_51d60950:\n", + " date: 2020-01-24_15-43-31\n", + " done: false\n", + " experiment_id: 430041a749c3485e89b5a16dbcae3c66\n", + " experiment_tag: 1_lr=0.01\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 1\n", + " mean_accuracy: 0.23125\n", + " node_ip: 192.168.1.27\n", + " pid: 12308\n", + " time_since_restore: 0.363037109375\n", + " time_this_iter_s: 0.363037109375\n", + " time_total_s: 0.363037109375\n", + " timestamp: 1579909411\n", + " timesteps_since_restore: 0\n", + " training_iteration: 0\n", + " trial_id: 51d60950\n", + " \n", + "Result for train_mnist_51d5e2c2:\n", + " date: 2020-01-24_15-43-31\n", + " done: false\n", + " experiment_id: 5e6369a0220c49359d02f5b5a19f21b8\n", + " experiment_tag: 0_lr=0.001\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 1\n", + " mean_accuracy: 0.065625\n", + " node_ip: 192.168.1.27\n", + " pid: 12309\n", + " time_since_restore: 0.46709609031677246\n", + " time_this_iter_s: 0.46709609031677246\n", + " time_total_s: 0.46709609031677246\n", + " timestamp: 1579909411\n", + " timesteps_since_restore: 0\n", + " training_iteration: 0\n", + " trial_id: 51d5e2c2\n", + " \n", + "Result for train_mnist_51d627e6:\n", + " date: 2020-01-24_15-43-31\n", + " done: false\n", + " experiment_id: 77705b95fef6468ea13c986602e7a71c\n", + " experiment_tag: 2_lr=0.1\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 1\n", + " mean_accuracy: 0.503125\n", + " node_ip: 192.168.1.27\n", + " pid: 12307\n", + " time_since_restore: 0.512376070022583\n", + " time_this_iter_s: 0.512376070022583\n", + " time_total_s: 0.512376070022583\n", + " timestamp: 1579909411\n", + " timesteps_since_restore: 0\n", + " training_iteration: 0\n", + " trial_id: 51d627e6\n", + " \n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 10.4/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 3/16 CPUs, 0/0 GPUs, 0.0/3.71 GiB heap, 0.0/1.27 GiB objects
Result logdir: /Users/yunzhi/ray_results/train_mnist
Number of trials: 3 (3 RUNNING)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc lr iter total time (s) acc
train_mnist_51d5e2c2RUNNING 192.168.1.27:123090.001 6 1.969410.05
train_mnist_51d60950RUNNING 192.168.1.27:123080.01 7 2.123120.775
train_mnist_51d627e6RUNNING 192.168.1.27:123070.1 6 2.013970.8375


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result for train_mnist_51d60950:\n", + " date: 2020-01-24_15-43-36\n", + " done: false\n", + " experiment_id: 430041a749c3485e89b5a16dbcae3c66\n", + " experiment_tag: 1_lr=0.01\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 23\n", + " mean_accuracy: 0.85625\n", + " node_ip: 192.168.1.27\n", + " pid: 12308\n", + " time_since_restore: 5.452777147293091\n", + " time_this_iter_s: 0.21289515495300293\n", + " time_total_s: 5.452777147293091\n", + " timestamp: 1579909416\n", + " timesteps_since_restore: 0\n", + " training_iteration: 22\n", + " trial_id: 51d60950\n", + " \n", + "Result for train_mnist_51d5e2c2:\n", + " date: 2020-01-24_15-43-36\n", + " done: false\n", + " experiment_id: 5e6369a0220c49359d02f5b5a19f21b8\n", + " experiment_tag: 0_lr=0.001\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 23\n", + " mean_accuracy: 0.128125\n", + " node_ip: 192.168.1.27\n", + " pid: 12309\n", + " time_since_restore: 5.5144970417022705\n", + " time_this_iter_s: 0.21251416206359863\n", + " time_total_s: 5.5144970417022705\n", + " timestamp: 1579909416\n", + " timesteps_since_restore: 0\n", + " training_iteration: 22\n", + " trial_id: 51d5e2c2\n", + " \n", + "Result for train_mnist_51d627e6:\n", + " date: 2020-01-24_15-43-36\n", + " done: false\n", + " experiment_id: 77705b95fef6468ea13c986602e7a71c\n", + " experiment_tag: 2_lr=0.1\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 23\n", + " mean_accuracy: 0.90625\n", + " node_ip: 192.168.1.27\n", + " pid: 12307\n", + " time_since_restore: 5.559006929397583\n", + " time_this_iter_s: 0.2171010971069336\n", + " time_total_s: 5.559006929397583\n", + " timestamp: 1579909416\n", + " timesteps_since_restore: 0\n", + " training_iteration: 22\n", + " trial_id: 51d627e6\n", + " \n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 10.3/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 3/16 CPUs, 0/0 GPUs, 0.0/3.71 GiB heap, 0.0/1.27 GiB objects
Result logdir: /Users/yunzhi/ray_results/train_mnist
Number of trials: 3 (3 RUNNING)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc lr iter total time (s) acc
train_mnist_51d5e2c2RUNNING 192.168.1.27:123090.001 29 7.058380.125
train_mnist_51d60950RUNNING 192.168.1.27:123080.01 30 7.220340.890625
train_mnist_51d627e6RUNNING 192.168.1.27:123070.1 29 7.100890.884375


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result for train_mnist_51d60950:\n", + " date: 2020-01-24_15-43-41\n", + " done: false\n", + " experiment_id: 430041a749c3485e89b5a16dbcae3c66\n", + " experiment_tag: 1_lr=0.01\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 45\n", + " mean_accuracy: 0.86875\n", + " node_ip: 192.168.1.27\n", + " pid: 12308\n", + " time_since_restore: 10.705771207809448\n", + " time_this_iter_s: 0.3253171443939209\n", + " time_total_s: 10.705771207809448\n", + " timestamp: 1579909421\n", + " timesteps_since_restore: 0\n", + " training_iteration: 44\n", + " trial_id: 51d60950\n", + " \n", + "Result for train_mnist_51d5e2c2:\n", + " date: 2020-01-24_15-43-41\n", + " done: false\n", + " experiment_id: 5e6369a0220c49359d02f5b5a19f21b8\n", + " experiment_tag: 0_lr=0.001\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 45\n", + " mean_accuracy: 0.24375\n", + " node_ip: 192.168.1.27\n", + " pid: 12309\n", + " time_since_restore: 10.82926321029663\n", + " time_this_iter_s: 0.33666110038757324\n", + " time_total_s: 10.82926321029663\n", + " timestamp: 1579909421\n", + " timesteps_since_restore: 0\n", + " training_iteration: 44\n", + " trial_id: 51d5e2c2\n", + " \n", + "Result for train_mnist_51d627e6:\n", + " date: 2020-01-24_15-43-41\n", + " done: false\n", + " experiment_id: 77705b95fef6468ea13c986602e7a71c\n", + " experiment_tag: 2_lr=0.1\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 45\n", + " mean_accuracy: 0.928125\n", + " node_ip: 192.168.1.27\n", + " pid: 12307\n", + " time_since_restore: 10.86169981956482\n", + " time_this_iter_s: 0.3371458053588867\n", + " time_total_s: 10.86169981956482\n", + " timestamp: 1579909421\n", + " timesteps_since_restore: 0\n", + " training_iteration: 44\n", + " trial_id: 51d627e6\n", + " \n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 10.4/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 3/16 CPUs, 0/0 GPUs, 0.0/3.71 GiB heap, 0.0/1.27 GiB objects
Result logdir: /Users/yunzhi/ray_results/train_mnist
Number of trials: 3 (3 RUNNING)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc lr iter total time (s) acc
train_mnist_51d5e2c2RUNNING 192.168.1.27:123090.001 49 12.17710.25
train_mnist_51d60950RUNNING 192.168.1.27:123080.01 50 12.32490.909375
train_mnist_51d627e6RUNNING 192.168.1.27:123070.1 49 12.19760.9125


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result for train_mnist_51d60950:\n", + " date: 2020-01-24_15-43-46\n", + " done: false\n", + " experiment_id: 430041a749c3485e89b5a16dbcae3c66\n", + " experiment_tag: 1_lr=0.01\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 64\n", + " mean_accuracy: 0.89375\n", + " node_ip: 192.168.1.27\n", + " pid: 12308\n", + " time_since_restore: 15.811901092529297\n", + " time_this_iter_s: 0.2762620449066162\n", + " time_total_s: 15.811901092529297\n", + " timestamp: 1579909426\n", + " timesteps_since_restore: 0\n", + " training_iteration: 63\n", + " trial_id: 51d60950\n", + " \n", + "Result for train_mnist_51d5e2c2:\n", + " date: 2020-01-24_15-43-46\n", + " done: false\n", + " experiment_id: 5e6369a0220c49359d02f5b5a19f21b8\n", + " experiment_tag: 0_lr=0.001\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 64\n", + " mean_accuracy: 0.340625\n", + " node_ip: 192.168.1.27\n", + " pid: 12309\n", + " time_since_restore: 15.890575170516968\n", + " time_this_iter_s: 0.2264111042022705\n", + " time_total_s: 15.890575170516968\n", + " timestamp: 1579909426\n", + " timesteps_since_restore: 0\n", + " training_iteration: 63\n", + " trial_id: 51d5e2c2\n", + " \n", + "Result for train_mnist_51d627e6:\n", + " date: 2020-01-24_15-43-46\n", + " done: false\n", + " experiment_id: 77705b95fef6468ea13c986602e7a71c\n", + " experiment_tag: 2_lr=0.1\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 64\n", + " mean_accuracy: 0.928125\n", + " node_ip: 192.168.1.27\n", + " pid: 12307\n", + " time_since_restore: 15.901074886322021\n", + " time_this_iter_s: 0.22142696380615234\n", + " time_total_s: 15.901074886322021\n", + " timestamp: 1579909426\n", + " timesteps_since_restore: 0\n", + " training_iteration: 63\n", + " trial_id: 51d627e6\n", + " \n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 10.3/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 3/16 CPUs, 0/0 GPUs, 0.0/3.71 GiB heap, 0.0/1.27 GiB objects
Result logdir: /Users/yunzhi/ray_results/train_mnist
Number of trials: 3 (3 RUNNING)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc lr iter total time (s) acc
train_mnist_51d5e2c2RUNNING 192.168.1.27:123090.001 69 17.29650.365625
train_mnist_51d60950RUNNING 192.168.1.27:123080.01 70 17.45630.8875
train_mnist_51d627e6RUNNING 192.168.1.27:123070.1 69 17.30680.921875


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result for train_mnist_51d60950:\n", + " date: 2020-01-24_15-43-51\n", + " done: false\n", + " experiment_id: 430041a749c3485e89b5a16dbcae3c66\n", + " experiment_tag: 1_lr=0.01\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 86\n", + " mean_accuracy: 0.89375\n", + " node_ip: 192.168.1.27\n", + " pid: 12308\n", + " time_since_restore: 20.95795702934265\n", + " time_this_iter_s: 0.21814513206481934\n", + " time_total_s: 20.95795702934265\n", + " timestamp: 1579909431\n", + " timesteps_since_restore: 0\n", + " training_iteration: 85\n", + " trial_id: 51d60950\n", + " \n", + "Result for train_mnist_51d5e2c2:\n", + " date: 2020-01-24_15-43-51\n", + " done: false\n", + " experiment_id: 5e6369a0220c49359d02f5b5a19f21b8\n", + " experiment_tag: 0_lr=0.001\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 86\n", + " mean_accuracy: 0.496875\n", + " node_ip: 192.168.1.27\n", + " pid: 12309\n", + " time_since_restore: 21.006662845611572\n", + " time_this_iter_s: 0.22823190689086914\n", + " time_total_s: 21.006662845611572\n", + " timestamp: 1579909431\n", + " timesteps_since_restore: 0\n", + " training_iteration: 85\n", + " trial_id: 51d5e2c2\n", + " \n", + "Result for train_mnist_51d627e6:\n", + " date: 2020-01-24_15-43-51\n", + " done: false\n", + " experiment_id: 77705b95fef6468ea13c986602e7a71c\n", + " experiment_tag: 2_lr=0.1\n", + " hostname: Yunzhis-MacBook-Pro.local\n", + " iterations_since_restore: 86\n", + " mean_accuracy: 0.940625\n", + " node_ip: 192.168.1.27\n", + " pid: 12307\n", + " time_since_restore: 21.0240797996521\n", + " time_this_iter_s: 0.23275399208068848\n", + " time_total_s: 21.0240797996521\n", + " timestamp: 1579909431\n", + " timesteps_since_restore: 0\n", + " training_iteration: 85\n", + " trial_id: 51d627e6\n", + " \n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 10.2/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 3/16 CPUs, 0/0 GPUs, 0.0/3.71 GiB heap, 0.0/1.27 GiB objects
Result logdir: /Users/yunzhi/ray_results/train_mnist
Number of trials: 3 (3 RUNNING)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc lr iter total time (s) acc
train_mnist_51d5e2c2RUNNING 192.168.1.27:123090.001 91 22.32220.5125
train_mnist_51d60950RUNNING 192.168.1.27:123080.01 92 22.48960.884375
train_mnist_51d627e6RUNNING 192.168.1.27:123070.1 91 22.33470.946875


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 10.2/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 0/16 CPUs, 0/0 GPUs, 0.0/3.71 GiB heap, 0.0/1.27 GiB objects
Result logdir: /Users/yunzhi/ray_results/train_mnist
Number of trials: 3 (3 TERMINATED)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc lr iter total time (s) acc
train_mnist_51d5e2c2TERMINATED 0.001 99 24.13950.5625
train_mnist_51d60950TERMINATED 0.01 99 24.054 0.89375
train_mnist_51d627e6TERMINATED 0.1 99 24.11020.95625


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-24 15:43:54,943\tINFO tune.py:330 -- Returning an analysis object by default. You can call `analysis.trials` to retrieve a list of trials. This message will be removed in future versions of Tune.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Best config: {'lr': 0.1}\n" + ] + } + ], + "source": [ + "import torch.optim as optim\n", + "from ray import tune\n", + "from ray.tune.examples.mnist_pytorch import get_data_loaders, ConvNet, train, test\n", + "\n", + "\n", + "def train_mnist(config):\n", + " train_loader, test_loader = get_data_loaders()\n", + " model = ConvNet()\n", + " optimizer = optim.SGD(model.parameters(), lr=config[\"lr\"])\n", + " for i in range(100):\n", + " train(model, optimizer, train_loader)\n", + " acc = test(model, test_loader)\n", + " ray.show_in_webui(str(acc))\n", + " tune.track.log(mean_accuracy=acc)\n", + "\n", + "\n", + "analysis = tune.run(\n", + " train_mnist, config={\"lr\": tune.grid_search([0.001, 0.01, 0.1])})\n", + "\n", + "print(\"Best config: \", analysis.get_best_config(metric=\"mean_accuracy\"))\n", + "\n", + "# Get a dataframe for analyzing trial results.\n", + "df = analysis.dataframe()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "More examples are available on https://ray.readthedocs.io/en/latest/auto_examples/overview.html.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/img/example-1.png b/examples/img/example-1.png new file mode 100644 index 0000000..a5fb195 Binary files /dev/null and b/examples/img/example-1.png differ diff --git a/examples/img/example-2.png b/examples/img/example-2.png new file mode 100644 index 0000000..ee7c55a Binary files /dev/null and b/examples/img/example-2.png differ diff --git a/examples/img/example-3.png b/examples/img/example-3.png new file mode 100644 index 0000000..f2d237f Binary files /dev/null and b/examples/img/example-3.png differ diff --git a/examples/img/infeasible-task.png b/examples/img/infeasible-task.png new file mode 100644 index 0000000..b481918 Binary files /dev/null and b/examples/img/infeasible-task.png differ diff --git a/examples/img/local-memory-usage.png b/examples/img/local-memory-usage.png new file mode 100644 index 0000000..5137927 Binary files /dev/null and b/examples/img/local-memory-usage.png differ diff --git a/examples/img/node-memory-usage.png b/examples/img/node-memory-usage.png new file mode 100644 index 0000000..8501565 Binary files /dev/null and b/examples/img/node-memory-usage.png differ diff --git a/examples/img/profiling.png b/examples/img/profiling.png new file mode 100644 index 0000000..db842d4 Binary files /dev/null and b/examples/img/profiling.png differ diff --git a/examples/news_recommendation_model.ipynb b/examples/news_recommendation_model.ipynb index f9266f0..e44ff6e 100644 --- a/examples/news_recommendation_model.ipynb +++ b/examples/news_recommendation_model.ipynb @@ -20,9 +20,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--2020-01-02 12:16:41-- https://s3-us-west-2.amazonaws.com/ray-tutorials/hackernews.zip\n", + "Resolving s3-us-west-2.amazonaws.com (s3-us-west-2.amazonaws.com)... 52.218.128.120\n", + "Connecting to s3-us-west-2.amazonaws.com (s3-us-west-2.amazonaws.com)|52.218.128.120|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 56402193 (54M) [application/zip]\n", + "Saving to: ‘hackernews.zip’\n", + "\n", + "hackernews.zip 100%[===================>] 53.79M 25.7MB/s in 2.1s \n", + "\n", + "2020-01-02 12:16:44 (25.7 MB/s) - ‘hackernews.zip’ saved [56402193/56402193]\n", + "\n", + "Archive: hackernews.zip\n", + " inflating: submission-1.json \n", + " inflating: submission-2.json \n", + " inflating: submission-3.json \n", + " inflating: submission-4.json \n", + "{\"body\": {\"descendants\": 0, \"url\": \"http://markpincus.blogspot.com/2005/03/peopleweb-i-believe-we-are-close-to.html\", \"text\": \"\", \"title\": \"The PeopleWeb | Mark Pincus Blog (March 2005)\", \"by\": \"sayemm\", \"score\": 3, \"time\": 1286515576, \"type\": \"story\", \"id\": 1770734}, \"source\": \"firebase\", \"id\": 1770734, \"retrieved_at_ts\": 1436469924}\n", + "{\"body\": {\"descendants\": 0, \"url\": \"http://omergertel.com/2010/11/16/honing-my-craft/\", \"text\": \"\", \"title\": \"Computer science and programming are two separate things\", \"by\": \"omergertel\", \"score\": 1, \"time\": 1289946709, \"type\": \"story\", \"id\": 1911996}, \"source\": \"firebase\", \"id\": 1911996, \"retrieved_at_ts\": 1436484897}\n" + ] + } + ], "source": [ "!wget -nc https://s3-us-west-2.amazonaws.com/ray-tutorials/hackernews.zip\n", "!unzip -o hackernews.zip\n", @@ -31,9 +56,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "env: RAY_DASHBOARD_DEBUG=True\n" + ] + } + ], "source": [ "from __future__ import absolute_import\n", "from __future__ import division\n", @@ -43,16 +76,51 @@ "import numpy as np\n", "import pandas as pd\n", "import ray\n", - "import time" + "import time\n", + "\n", + "%env RAY_DASHBOARD_DEBUG = True" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ - "ray.init(num_cpus=4, include_webui=False, ignore_reinit_error=True)" + "ray.shutdown()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-02 12:22:17,658\tINFO resource_spec.py:216 -- Starting Ray with 3.32 GiB memory available for workers and up to 1.66 GiB for objects. You can adjust these settings with ray.init(memory=, object_store_memory=).\n", + "2020-01-02 12:22:17,900\tINFO services.py:1101 -- View the Ray dashboard at \u001b[1m\u001b[32mlocalhost:8267\u001b[39m\u001b[22m.\n" + ] + }, + { + "data": { + "text/plain": [ + "{'node_ip_address': '10.1.10.91',\n", + " 'redis_address': '10.1.10.91:61548',\n", + " 'object_store_address': '/tmp/ray/session_2020-01-02_12-22-17_649165_4496/sockets/plasma_store',\n", + " 'raylet_socket_name': '/tmp/ray/session_2020-01-02_12-22-17_649165_4496/sockets/raylet',\n", + " 'webui_url': 'localhost:8267',\n", + " 'session_dir': '/tmp/ray/session_2020-01-02_12-22-17_649165_4496'}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ray.init(num_cpus=4, include_webui=True, ignore_reinit_error=True)" ] }, { @@ -64,7 +132,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -86,9 +154,85 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Took 2.8535571098327637 seconds to parse the hackernews submissions\n" + ] + }, + { + "data": { + "text/html": [ + "
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
datascore
0The PeopleWeb | Mark Pincus Blog (March 2005)3
1Computer science and programming are two separ...1
2Don't Go It Alone: Create an Advisory Board1
3Wikileaks Secret Dreams1
4MakeMyTrip.com: Is eCommerce in India Finall...1
\n", + "
" + ], + "text/plain": [ + " data score\n", + "0 The PeopleWeb | Mark Pincus Blog (March 2005) 3\n", + "1 Computer science and programming are two separ... 1\n", + "2 Don't Go It Alone: Create an Advisory Board 1\n", + "3 Wikileaks Secret Dreams 1\n", + "4 MakeMyTrip.com: Is eCommerce in India Finall... 1" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "start_time = time.time()\n", "\n", @@ -121,16 +265,27 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "1.0" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df[\"score\"].median()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -157,7 +312,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -174,9 +329,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:561: ConvergenceWarning: Maximum number of iteration reached before convergence. Consider increasing max_iter to improve the fit.\n", + " ConvergenceWarning)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy on the training set is 0.586221875\n" + ] + } + ], "source": [ "from sklearn.pipeline import Pipeline\n", "from sklearn.feature_extraction.text import CountVectorizer\n", @@ -196,9 +367,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy on the test set is 0.578675\n" + ] + } + ], "source": [ "predicted = pipeline.predict(test.data)\n", "print(\"Accuracy on the test set is {}\".format(np.mean(predicted == test.target)))" @@ -213,9 +392,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "array([ True, False])" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "pipeline.predict([\"Iconic consoles of the IBM System/360 mainframes, 55 years old today\",\n", " \"Are Banned Drugs in Your Meat?\"])" @@ -238,7 +428,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -260,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -268,7 +458,12 @@ "test_id = ray.put(test)\n", "\n", "def train_func(config, reporter):\n", - " pipeline = # TODO: Put in the training pipeline here\n", + " pipeline = Pipeline([\n", + " (\"vect\", CountVectorizer()),\n", + " (\"clf\", SGDClassifier(loss=\"hinge\", penalty=\"l2\",\n", + " alpha=config[\"alpha\"],\n", + " max_iter=5, tol=1e-3,\n", + " warm_start=True))]) # TODO: Put in the training pipeline here\n", " train = ray.get(train_id)\n", " test = ray.get(test_id)\n", " for i in range(5):\n", @@ -289,9 +484,385 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 26, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-02 12:23:13,171\tWARNING logger.py:413 -- Could not instantiate tf2_compat_logger: No module named 'tensorflow'.\n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 11.4/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 1/4 CPUs, 0/0 GPUs, 0.0/3.32 GiB heap, 0.0/1.12 GiB objects
Result logdir: /Users/yunzhi/ray_results/news_recommendation
Number of trials: 4 (1 RUNNING, 3 PENDING)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc alpha
train_func_b36a39c4RUNNING
train_func_b36dfc58PENDING
train_func_b36e24d0PENDING
train_func_b36e4bfePENDING


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-02 12:23:13,187\tWARNING logger.py:413 -- Could not instantiate tf2_compat_logger: No module named 'tensorflow'.\n", + "2020-01-02 12:23:13,198\tWARNING logger.py:413 -- Could not instantiate tf2_compat_logger: No module named 'tensorflow'.\n", + "2020-01-02 12:23:13,208\tWARNING logger.py:413 -- Could not instantiate tf2_compat_logger: No module named 'tensorflow'.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result for train_func_b36e24d0:\n", + " date: 2020-01-02_12-23-18\n", + " done: false\n", + " experiment_id: 0c18f4cfd3a54af0902bb2ade835f338\n", + " experiment_tag: 2_alpha=1e-05\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 1\n", + " mean_accuracy: 0.5702625\n", + " node_ip: 10.1.10.91\n", + " pid: 4527\n", + " time_since_restore: 4.267539978027344\n", + " time_this_iter_s: 4.267539978027344\n", + " time_total_s: 4.267539978027344\n", + " timestamp: 1577996598\n", + " timesteps_since_restore: 0\n", + " training_iteration: 1\n", + " trial_id: b36e24d0\n", + " \n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 11.4/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 4/4 CPUs, 0/0 GPUs, 0.0/3.32 GiB heap, 0.0/1.12 GiB objects
Result logdir: /Users/yunzhi/ray_results/news_recommendation
Number of trials: 4 (4 RUNNING)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc alpha iter total time (s) acc
train_func_b36a39c4RUNNING
train_func_b36dfc58RUNNING
train_func_b36e24d0RUNNING 10.1.10.91:4527 1e-05 1 4.267540.570263
train_func_b36e4bfeRUNNING


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result for train_func_b36e4bfe:\n", + " date: 2020-01-02_12-23-18\n", + " done: false\n", + " experiment_id: 8852a9f9a054441ea0fb3d6963922800\n", + " experiment_tag: 3_alpha=1e-06\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 1\n", + " mean_accuracy: 0.5621125\n", + " node_ip: 10.1.10.91\n", + " pid: 4525\n", + " time_since_restore: 4.303200960159302\n", + " time_this_iter_s: 4.303200960159302\n", + " time_total_s: 4.303200960159302\n", + " timestamp: 1577996598\n", + " timesteps_since_restore: 0\n", + " training_iteration: 1\n", + " trial_id: b36e4bfe\n", + " \n", + "Result for train_func_b36dfc58:\n", + " date: 2020-01-02_12-23-18\n", + " done: false\n", + " experiment_id: 12c88bd52e6047679f7a52af9aa71d02\n", + " experiment_tag: 1_alpha=0.0001\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 1\n", + " mean_accuracy: 0.59805\n", + " node_ip: 10.1.10.91\n", + " pid: 4528\n", + " time_since_restore: 4.316836833953857\n", + " time_this_iter_s: 4.316836833953857\n", + " time_total_s: 4.316836833953857\n", + " timestamp: 1577996598\n", + " timesteps_since_restore: 0\n", + " training_iteration: 1\n", + " trial_id: b36dfc58\n", + " \n", + "Result for train_func_b36a39c4:\n", + " date: 2020-01-02_12-23-18\n", + " done: false\n", + " experiment_id: f6a7dfdfaba84177bc8dbe4e28c227c4\n", + " experiment_tag: 0_alpha=0.001\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 1\n", + " mean_accuracy: 0.5814125\n", + " node_ip: 10.1.10.91\n", + " pid: 4526\n", + " time_since_restore: 4.329303026199341\n", + " time_this_iter_s: 4.329303026199341\n", + " time_total_s: 4.329303026199341\n", + " timestamp: 1577996598\n", + " timesteps_since_restore: 0\n", + " training_iteration: 1\n", + " trial_id: b36a39c4\n", + " \n", + "Result for train_func_b36e24d0:\n", + " date: 2020-01-02_12-23-26\n", + " done: false\n", + " experiment_id: 0c18f4cfd3a54af0902bb2ade835f338\n", + " experiment_tag: 2_alpha=1e-05\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 3\n", + " mean_accuracy: 0.5919625\n", + " node_ip: 10.1.10.91\n", + " pid: 4527\n", + " time_since_restore: 12.236334085464478\n", + " time_this_iter_s: 3.945594072341919\n", + " time_total_s: 12.236334085464478\n", + " timestamp: 1577996606\n", + " timesteps_since_restore: 0\n", + " training_iteration: 3\n", + " trial_id: b36e24d0\n", + " \n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 11.2/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 4/4 CPUs, 0/0 GPUs, 0.0/3.32 GiB heap, 0.0/1.12 GiB objects
Result logdir: /Users/yunzhi/ray_results/news_recommendation
Number of trials: 4 (4 RUNNING)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc alpha iter total time (s) acc
train_func_b36a39c4RUNNING 10.1.10.91:4526 0.001 2 8.396690.58005
train_func_b36dfc58RUNNING 10.1.10.91:4528 0.0001 2 8.383580.601413
train_func_b36e24d0RUNNING 10.1.10.91:4527 1e-05 3 12.2363 0.591962
train_func_b36e4bfeRUNNING 10.1.10.91:4525 1e-06 2 8.358940.568412


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result for train_func_b36e4bfe:\n", + " date: 2020-01-02_12-23-26\n", + " done: false\n", + " experiment_id: 8852a9f9a054441ea0fb3d6963922800\n", + " experiment_tag: 3_alpha=1e-06\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 3\n", + " mean_accuracy: 0.5668\n", + " node_ip: 10.1.10.91\n", + " pid: 4525\n", + " time_since_restore: 12.327115058898926\n", + " time_this_iter_s: 3.9681711196899414\n", + " time_total_s: 12.327115058898926\n", + " timestamp: 1577996606\n", + " timesteps_since_restore: 0\n", + " training_iteration: 3\n", + " trial_id: b36e4bfe\n", + " \n", + "Result for train_func_b36dfc58:\n", + " date: 2020-01-02_12-23-26\n", + " done: false\n", + " experiment_id: 12c88bd52e6047679f7a52af9aa71d02\n", + " experiment_tag: 1_alpha=0.0001\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 3\n", + " mean_accuracy: 0.60135\n", + " node_ip: 10.1.10.91\n", + " pid: 4528\n", + " time_since_restore: 12.36200499534607\n", + " time_this_iter_s: 3.9784250259399414\n", + " time_total_s: 12.36200499534607\n", + " timestamp: 1577996606\n", + " timesteps_since_restore: 0\n", + " training_iteration: 3\n", + " trial_id: b36dfc58\n", + " \n", + "Result for train_func_b36a39c4:\n", + " date: 2020-01-02_12-23-26\n", + " done: false\n", + " experiment_id: f6a7dfdfaba84177bc8dbe4e28c227c4\n", + " experiment_tag: 0_alpha=0.001\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 3\n", + " mean_accuracy: 0.578625\n", + " node_ip: 10.1.10.91\n", + " pid: 4526\n", + " time_since_restore: 12.378322124481201\n", + " time_this_iter_s: 3.981630325317383\n", + " time_total_s: 12.378322124481201\n", + " timestamp: 1577996606\n", + " timesteps_since_restore: 0\n", + " training_iteration: 3\n", + " trial_id: b36a39c4\n", + " \n", + "Result for train_func_b36e24d0:\n", + " date: 2020-01-02_12-23-34\n", + " done: false\n", + " experiment_id: 0c18f4cfd3a54af0902bb2ade835f338\n", + " experiment_tag: 2_alpha=1e-05\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 5\n", + " mean_accuracy: 0.596325\n", + " node_ip: 10.1.10.91\n", + " pid: 4527\n", + " time_since_restore: 20.07131314277649\n", + " time_this_iter_s: 3.911412239074707\n", + " time_total_s: 20.07131314277649\n", + " timestamp: 1577996614\n", + " timesteps_since_restore: 0\n", + " training_iteration: 5\n", + " trial_id: b36e24d0\n", + " \n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 11.2/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 4/4 CPUs, 0/0 GPUs, 0.0/3.32 GiB heap, 0.0/1.12 GiB objects
Result logdir: /Users/yunzhi/ray_results/news_recommendation
Number of trials: 4 (4 RUNNING)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc alpha iter total time (s) acc
train_func_b36a39c4RUNNING 10.1.10.91:4526 0.001 4 16.34480.578825
train_func_b36dfc58RUNNING 10.1.10.91:4528 0.0001 4 16.31860.609237
train_func_b36e24d0RUNNING 10.1.10.91:4527 1e-05 5 20.07130.596325
train_func_b36e4bfeRUNNING 10.1.10.91:4525 1e-06 4 16.267 0.5628


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result for train_func_b36e4bfe:\n", + " date: 2020-01-02_12-23-34\n", + " done: false\n", + " experiment_id: 8852a9f9a054441ea0fb3d6963922800\n", + " experiment_tag: 3_alpha=1e-06\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 5\n", + " mean_accuracy: 0.568875\n", + " node_ip: 10.1.10.91\n", + " pid: 4525\n", + " time_since_restore: 20.2430899143219\n", + " time_this_iter_s: 3.976069927215576\n", + " time_total_s: 20.2430899143219\n", + " timestamp: 1577996614\n", + " timesteps_since_restore: 0\n", + " training_iteration: 5\n", + " trial_id: b36e4bfe\n", + " \n", + "Result for train_func_b36dfc58:\n", + " date: 2020-01-02_12-23-34\n", + " done: false\n", + " experiment_id: 12c88bd52e6047679f7a52af9aa71d02\n", + " experiment_tag: 1_alpha=0.0001\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 5\n", + " mean_accuracy: 0.6095125\n", + " node_ip: 10.1.10.91\n", + " pid: 4528\n", + " time_since_restore: 20.28740692138672\n", + " time_this_iter_s: 3.968809127807617\n", + " time_total_s: 20.28740692138672\n", + " timestamp: 1577996614\n", + " timesteps_since_restore: 0\n", + " training_iteration: 5\n", + " trial_id: b36dfc58\n", + " \n", + "Result for train_func_b36a39c4:\n", + " date: 2020-01-02_12-23-34\n", + " done: false\n", + " experiment_id: f6a7dfdfaba84177bc8dbe4e28c227c4\n", + " experiment_tag: 0_alpha=0.001\n", + " hostname: Yunzhis-MBP.hsd1.ca.comcast.net\n", + " iterations_since_restore: 5\n", + " mean_accuracy: 0.5783875\n", + " node_ip: 10.1.10.91\n", + " pid: 4526\n", + " time_since_restore: 20.350215196609497\n", + " time_this_iter_s: 4.005417346954346\n", + " time_total_s: 20.350215196609497\n", + " timestamp: 1577996614\n", + " timesteps_since_restore: 0\n", + " training_iteration: 5\n", + " trial_id: b36a39c4\n", + " \n" + ] + }, + { + "data": { + "text/html": [ + "== Status ==
Memory usage on this node: 11.1/16.0 GiB
Using FIFO scheduling algorithm.
Resources requested: 0/4 CPUs, 0/0 GPUs, 0.0/3.32 GiB heap, 0.0/1.12 GiB objects
Result logdir: /Users/yunzhi/ray_results/news_recommendation
Number of trials: 4 (4 TERMINATED)
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Trial name status loc alpha iter total time (s) acc
train_func_b36a39c4TERMINATED 0.001 5 20.35020.578388
train_func_b36dfc58TERMINATED 0.0001 5 20.28740.609513
train_func_b36e24d0TERMINATED 1e-05 5 20.07130.596325
train_func_b36e4bfeTERMINATED 1e-06 5 20.24310.568875


" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-02 12:23:34,849\tINFO tune.py:334 -- Returning an analysis object by default. You can call `analysis.trials` to retrieve a list of trials. This message will be removed in future versions of Tune.\n" + ] + } + ], "source": [ "all_trials = tune.run(\n", " train_func,\n", @@ -338,7 +909,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.8" + "version": "3.7.4" } }, "nbformat": 4, diff --git a/examples/sharded_parameter_server.ipynb b/examples/sharded_parameter_server.ipynb index 3785506..815e8e7 100644 --- a/examples/sharded_parameter_server.ipynb +++ b/examples/sharded_parameter_server.ipynb @@ -24,9 +24,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "env: RAY_DASHBOARD_DEBUG=True\n" + ] + } + ], "source": [ "from __future__ import absolute_import\n", "from __future__ import division\n", @@ -34,16 +42,43 @@ "\n", "import numpy as np\n", "import ray\n", - "import time" + "import time\n", + "\n", + "%env RAY_DASHBOARD_DEBUG = True" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-24 14:32:55,735\tINFO resource_spec.py:212 -- Starting Ray with 2.69 GiB memory available for workers and up to 1.36 GiB for objects. You can adjust these settings with ray.init(memory=, object_store_memory=).\n", + "2020-01-24 14:32:56,852\tINFO services.py:501 -- Failed to connect to the redis server, retrying.\n", + "2020-01-24 14:32:57,123\tINFO services.py:1093 -- View the Ray dashboard at \u001b[1m\u001b[32mlocalhost:8268\u001b[39m\u001b[22m\n" + ] + }, + { + "data": { + "text/plain": [ + "{'node_ip_address': '192.168.1.27',\n", + " 'redis_address': '192.168.1.27:16149',\n", + " 'object_store_address': '/tmp/ray/session_2020-01-24_14-32-55_727080_11529/sockets/plasma_store',\n", + " 'raylet_socket_name': '/tmp/ray/session_2020-01-24_14-32-55_727080_11529/sockets/raylet',\n", + " 'webui_url': 'localhost:8268',\n", + " 'session_dir': '/tmp/ray/session_2020-01-24_14-32-55_727080_11529'}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "ray.init(num_cpus=30, include_webui=False, ignore_reinit_error=True)" + "ray.init(num_cpus=30, include_webui=True, ignore_reinit_error=True)" ] }, { @@ -57,12 +92,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "dim = 10\n", "\n", + "@ray.remote\n", "class ParameterServer(object):\n", " def __init__(self, dim):\n", " self.parameters = np.zeros(dim)\n", @@ -74,7 +110,7 @@ " self.parameters += update\n", "\n", "\n", - "ps = ParameterServer(dim)\n", + "ps = ParameterServer.remote(dim)\n", "\n", "assert hasattr(ParameterServer, 'remote'), ('You need to turn ParameterServer into an '\n", " 'actor (by using the ray.remote keyword).')" @@ -91,18 +127,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ + "@ray.remote\n", "def worker(ps, dim, num_iters):\n", " for _ in range(num_iters):\n", " # Get the latest parameters.\n", - " parameters = ps.get_parameters()\n", + " parameters = ray.get(ps.get_parameters.remote())\n", " # Compute an update.\n", " update = 1e-3 * parameters + np.ones(dim)\n", " # Update the parameters.\n", - " ps.update_parameters(update)\n", + " ray.get(ps.update_parameters.remote(update))\n", " # Sleep a little to simulate a real workload.\n", " time.sleep(0.5)\n", "\n", @@ -112,12 +149,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# Start two workers.\n", - "worker_results = [worker(ps, dim, 100) for _ in range(2)]" + "worker_results = [worker.remote(ps, dim, 100) for _ in range(2)]" ] }, { @@ -131,9 +168,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[41.81828509 41.81828509 41.81828509 41.81828509 41.81828509 41.81828509\n", + " 41.81828509 41.81828509 41.81828509 41.81828509]\n" + ] + } + ], "source": [ "print(ray.get(ps.get_parameters.remote()))" ] @@ -155,10 +201,11 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ + "@ray.remote\n", "class ParameterServerShard(object):\n", " def __init__(self, sharded_dim):\n", " self.parameters = np.zeros(sharded_dim)\n", @@ -178,7 +225,7 @@ " 'perfectly divide the total dimension.')\n", "\n", "# Start some parameter servers.\n", - "ps_shards = [ParameterServerShard(total_dim // num_shards) for _ in range(num_shards)]\n", + "ps_shards = [ParameterServerShard.remote(total_dim // num_shards) for _ in range(num_shards)]\n", "\n", "assert hasattr(ParameterServerShard, 'remote'), ('You need to turn ParameterServerShard into an '\n", " 'actor (by using the ray.remote keyword).')" @@ -200,17 +247,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ + "@ray.remote\n", "def worker_task(total_dim, num_iters, *ps_shards):\n", " # Note that ps_shards are passed in using Python's variable number\n", " # of arguments feature. We do this because currently actor handles\n", " # cannot be passed to tasks inside of lists or other objects.\n", " for _ in range(num_iters):\n", " # Get the current parameters from each parameter server.\n", - " parameter_shards = [ps.get_parameters() for ps in ps_shards]\n", + " parameter_shards = ray.get([ps.get_parameters.remote() for ps in ps_shards])\n", " assert all([isinstance(shard, np.ndarray) for shard in parameter_shards]), (\n", " 'The parameter shards must be numpy arrays. Did you forget to call ray.get?')\n", " # Concatenate them to form the full parameter vector.\n", @@ -224,7 +272,7 @@ " \n", " # Apply the updates to the relevant parameter server shards.\n", " for ps, update_shard in zip(ps_shards, update_shards):\n", - " ps.update_parameters(update_shard)\n", + " ray.get(ps.update_parameters.remote(update_shard))\n", "\n", "\n", "# Test that worker_task is implemented correctly. You do not need to change this line.\n", @@ -242,18 +290,47 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "This took 1.3368570804595947 seconds.\n", + "This took 1.6423673629760742 seconds.\n", + "This took 3.1816182136535645 seconds.\n" + ] + }, + { + "ename": "RayTaskError", + "evalue": "\u001b[36mray::__main__.worker_task()\u001b[39m (pid=11559, ip=192.168.1.27)\n File \"python/ray/_raylet.pyx\", line 647, in ray._raylet.execute_task\n File \"\", line 22, in worker_task\nray.exceptions.RayTaskError: \u001b[36mray::ParameterServerShard\u001b[39m (pid=11551, ip=192.168.1.27)\n File \"python/ray/_raylet.pyx\", line 633, in ray._raylet.execute_task\n File \"python/ray/_raylet.pyx\", line 634, in ray._raylet.execute_task\n File \"python/ray/_raylet.pyx\", line 519, in ray._raylet.deserialize_args\nray.exceptions.UnreconstructableError: Object 2ca53902e2591031ffffffff0100008004000000 is lost (either LRU evicted or deleted by user) and cannot be reconstructed. Try increasing the object store memory available with ray.init(object_store_memory=) or setting object store limits with ray.remote(object_store_memory=). See also: https://ray.readthedocs.io/en/latest/memory-management.html", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRayTaskError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# duration changes.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mstart\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mray\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mworker_task\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mremote\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtotal_dim\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mps_shards\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0m_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnum_workers\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'This took {} seconds.'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mstart\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/ray/python/ray/worker.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(object_ids, timeout)\u001b[0m\n\u001b[1;32m 1490\u001b[0m \u001b[0mworker\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcore_worker\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdump_object_store_memory_usage\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1491\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mRayTaskError\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1492\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mas_instanceof_cause\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1493\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1494\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mRayTaskError\u001b[0m: \u001b[36mray::__main__.worker_task()\u001b[39m (pid=11559, ip=192.168.1.27)\n File \"python/ray/_raylet.pyx\", line 647, in ray._raylet.execute_task\n File \"\", line 22, in worker_task\nray.exceptions.RayTaskError: \u001b[36mray::ParameterServerShard\u001b[39m (pid=11551, ip=192.168.1.27)\n File \"python/ray/_raylet.pyx\", line 633, in ray._raylet.execute_task\n File \"python/ray/_raylet.pyx\", line 634, in ray._raylet.execute_task\n File \"python/ray/_raylet.pyx\", line 519, in ray._raylet.deserialize_args\nray.exceptions.UnreconstructableError: Object 2ca53902e2591031ffffffff0100008004000000 is lost (either LRU evicted or deleted by user) and cannot be reconstructed. Try increasing the object store memory available with ray.init(object_store_memory=) or setting object store limits with ray.remote(object_store_memory=). See also: https://ray.readthedocs.io/en/latest/memory-management.html" + ] + } + ], "source": [ - "num_workers = 4\n", + "for num_workers in [1, 2, 4, 8]:\n", "\n", - "# Start some workers. Try changing various quantities and see how the\n", - "# duration changes.\n", - "start = time.time()\n", - "ray.get([worker_task(total_dim, 5, *ps_shards) for _ in range(num_workers)])\n", - "print('This took {} seconds.'.format(time.time() - start))" + " # Start some workers. Try changing various quantities and see how the\n", + " # duration changes.\n", + " start = time.time()\n", + " ray.get([worker_task.remote(total_dim, 5, *ps_shards) for _ in range(num_workers)])\n", + " print('This took {} seconds.'.format(time.time() - start))" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -272,7 +349,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.4" + "version": "3.7.4" } }, "nbformat": 4, diff --git a/rllib_exercises/rllib_exercise03_custom_env.ipynb b/rllib_exercises/rllib_exercise03_custom_env.ipynb index 039de0e..1c7f285 100644 --- a/rllib_exercises/rllib_exercise03_custom_env.ipynb +++ b/rllib_exercises/rllib_exercise03_custom_env.ipynb @@ -24,9 +24,58 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:544: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:545: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:550: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n", + "lz4 not available, disabling sample compression. This will significantly impact RLlib performance. To install lz4, run `pip install lz4`.\n", + "2020-01-24 14:42:09,225\tINFO resource_spec.py:212 -- Starting Ray with 4.0 GiB memory available for workers and up to 2.01 GiB for objects. You can adjust these settings with ray.init(memory=, object_store_memory=).\n", + "2020-01-24 14:42:09,552\tINFO services.py:1093 -- View the Ray dashboard at \u001b[1m\u001b[32mlocalhost:8270\u001b[39m\u001b[22m\n" + ] + }, + { + "data": { + "text/plain": [ + "{'node_ip_address': '192.168.1.27',\n", + " 'redis_address': '192.168.1.27:22733',\n", + " 'object_store_address': '/tmp/ray/session_2020-01-24_14-42-09_215023_11778/sockets/plasma_store',\n", + " 'raylet_socket_name': '/tmp/ray/session_2020-01-24_14-42-09_215023_11778/sockets/raylet',\n", + " 'webui_url': 'localhost:8270',\n", + " 'session_dir': '/tmp/ray/session_2020-01-24_14-42-09_215023_11778'}" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from __future__ import absolute_import\n", "from __future__ import division\n", @@ -73,9 +122,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Success!\n" + ] + } + ], "source": [ "action_space_map = {\n", " \"discrete_10\": spaces.Discrete(10),\n", @@ -86,9 +143,9 @@ "\n", "action_space_jumble = {\n", " \"discrete_10\": 1,\n", - " \"CHANGE_ME\": np.array([0, 0, 0, 2]),\n", - " \"CHANGE_ME\": np.array([[-1.2657754], [-1.6528835], [ 0.5982418]]),\n", - " \"CHANGE_ME\": np.array([0.89089584]),\n", + " \"multi_discrete\": np.array([0, 0, 0, 2]),\n", + " \"box_3x1\": np.array([[-1.2657754], [-1.6528835], [ 0.5982418]]),\n", + " \"box_1\": np.array([0.89089584]),\n", "}\n", "\n", "\n", @@ -143,9 +200,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Testing if spaces have been setup correctly...\n", + "Success! You've setup the spaces correctly.\n", + "Testing if reward has been setup correctly...\n", + "Success! You've setup the rewards correctly.\n" + ] + } + ], "source": [ "class ChainEnv(gym.Env):\n", " \n", @@ -162,8 +230,8 @@ " def _setup_spaces(self):\n", " ##############\n", " # TODO: Implement this so that it passes tests\n", - " self.action_space = None\n", - " self.observation_space = None\n", + " self.action_space = spaces.Discrete(2)\n", + " self.observation_space = spaces.Discrete(self.n)\n", " ##############\n", "\n", " def step(self, action):\n", @@ -171,18 +239,18 @@ " if action == 1: # 'backwards': go back to the beginning, get small reward\n", " ##############\n", " # TODO 2: Implement this so that it passes tests\n", - " reward = -1\n", + " reward = self.small_reward\n", " ##############\n", " self.state = 0\n", " elif self.state < self.n - 1: # 'forwards': go up along the chain\n", " ##############\n", " # TODO 2: Implement this so that it passes tests\n", - " reward = -1\n", + " reward = 0\n", " self.state += 1\n", " else: # 'forwards': stay at the end of the chain, collect large reward\n", " ##############\n", " # TODO 2: Implement this so that it passes tests\n", - " reward = -1\n", + " reward = self.large_reward\n", " ##############\n", " self._counter += 1\n", " done = self._counter >= self._horizon\n", @@ -209,7 +277,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -222,9 +290,47 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-24 14:45:27,438\tINFO trainer.py:377 -- Tip: set 'eager': true or the --eager flag to enable TensorFlow eager execution\n", + "2020-01-24 14:45:27,444\tERROR logger.py:328 -- pip install 'ray[tune]' to see TensorBoard files.\n", + "2020-01-24 14:45:27,444\tWARNING logger.py:417 -- Could not instantiate TBXLogger: No module named 'tensorboardX'.\n", + "2020-01-24 14:45:27,446\tINFO trainer.py:524 -- Current log_level is WARN. For more information, set 'log_level': 'INFO' / 'DEBUG' or use the -v and -vv flags.\n", + "2020-01-24 14:45:30,616\tWARNING util.py:41 -- Install gputil for GPU system monitoring.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training iteration 0...\n", + "Training iteration 1...\n", + "Training iteration 2...\n", + "Training iteration 3...\n", + "Training iteration 4...\n", + "Training iteration 5...\n", + "Training iteration 6...\n", + "Training iteration 7...\n", + "Training iteration 8...\n", + "Training iteration 9...\n", + "Training iteration 10...\n", + "Training iteration 11...\n", + "Training iteration 12...\n", + "Training iteration 13...\n", + "Training iteration 14...\n", + "Training iteration 15...\n", + "Training iteration 16...\n", + "Training iteration 17...\n", + "Training iteration 18...\n", + "Training iteration 19...\n" + ] + } + ], "source": [ "trainer = PPOTrainer(trainer_config, ChainEnv);\n", "for i in range(20):\n", @@ -234,9 +340,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cumulative reward you've received is: 40. Congratulations!\n", + "Max state you've visited is: 0. This is out of 20 states.\n" + ] + } + ], "source": [ "env = ChainEnv({})\n", "state = env.reset()\n", @@ -270,9 +385,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Testing if behavior has been changed...\n", + "Success! Behavior of environment is correct.\n" + ] + } + ], "source": [ "class ShapedChainEnv(ChainEnv):\n", " def step(self, action):\n", @@ -303,9 +427,58 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-01-24 14:46:04,206\tERROR logger.py:328 -- pip install 'ray[tune]' to see TensorBoard files.\n", + "2020-01-24 14:46:04,207\tWARNING logger.py:417 -- Could not instantiate TBXLogger: No module named 'tensorboardX'.\n", + "2020-01-24 14:46:07,247\tWARNING util.py:41 -- Install gputil for GPU system monitoring.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training iteration 0...\n", + "Training iteration 1...\n", + "Training iteration 2...\n", + "Training iteration 3...\n", + "Training iteration 4...\n", + "Training iteration 5...\n", + "Training iteration 6...\n", + "Training iteration 7...\n", + "Training iteration 8...\n", + "Training iteration 9...\n", + "Training iteration 10...\n", + "Training iteration 11...\n", + "Training iteration 12...\n", + "Training iteration 13...\n", + "Training iteration 14...\n", + "Training iteration 15...\n", + "Training iteration 16...\n", + "Training iteration 17...\n", + "Training iteration 18...\n", + "Training iteration 19...\n", + "Cumulative reward you've received is: -20!\n", + "Max state you've visited is: 3.2. This is out of 20 states.\n" + ] + }, + { + "ename": "AssertionError", + "evalue": "This policy did not traverse many states.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Cumulative reward you've received is: {}!\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcumulative_reward\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 23\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Max state you've visited is: {}. This is out of {} states.\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmax_states\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0menv\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 24\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0menv\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmax_states\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0menv\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0.2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"This policy did not traverse many states.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAssertionError\u001b[0m: This policy did not traverse many states." + ] + } + ], "source": [ "trainer = PPOTrainer(trainer_config, ShapedChainEnv);\n", "for i in range(20):\n", @@ -357,7 +530,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.7.4" } }, "nbformat": 4, diff --git a/rllib_exercises/rllib_exercise04_serving.ipynb b/rllib_exercises/rllib_exercise04_serving.ipynb index ac4132c..0eec2c2 100644 --- a/rllib_exercises/rllib_exercise04_serving.ipynb +++ b/rllib_exercises/rllib_exercise04_serving.ipynb @@ -265,7 +265,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" } }, "nbformat": 4, diff --git a/solutions/colab01-03_solution.ipynb b/solutions/colab01-03_solution.ipynb index 1d8eb94..836fbe1 100644 --- a/solutions/colab01-03_solution.ipynb +++ b/solutions/colab01-03_solution.ipynb @@ -132,7 +132,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -176,7 +176,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -191,7 +191,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "2019-10-13 10:06:37,698\tERROR worker.py:1432 -- Calling ray.init() again after it has already been called.\n" + "2020-01-24 14:35:16,520\tINFO resource_spec.py:212 -- Starting Ray with 3.08 GiB memory available for workers and up to 1.54 GiB for objects. You can adjust these settings with ray.init(memory=, object_store_memory=).\n", + "2020-01-24 14:35:16,888\tINFO services.py:1093 -- View the Ray dashboard at \u001b[1m\u001b[32mlocalhost:8266\u001b[39m\u001b[22m\n" ] } ], @@ -217,7 +218,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 3, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -232,7 +233,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Executing the for loop took 1.013 seconds.\n", + "Executing the for loop took 1.014 seconds.\n", "The results are: [0, 1, 2, 3]\n", "Run the next cell to check if the exercise was performed correctly.\n" ] @@ -271,7 +272,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -286,7 +287,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Success! The example took 1.0131359100341797 seconds.\n" + "Success! The example took 1.014420986175537 seconds.\n" ] } ], @@ -445,7 +446,7 @@ }, { "cell_type": "code", - "execution_count": 0, + "execution_count": 5, "metadata": { "colab": {}, "colab_type": "code", diff --git a/tune_exercises/exercise_1_basics.ipynb b/tune_exercises/exercise_1_basics.ipynb index 5ce7585..5dbf01b 100644 --- a/tune_exercises/exercise_1_basics.ipynb +++ b/tune_exercises/exercise_1_basics.ipynb @@ -76,9 +76,40 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:544: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:545: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", + "/Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:550: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n" + ] + } + ], "source": [ "import numpy as np\n", "np.random.seed(0)\n", @@ -130,9 +161,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA7MAAAF2CAYAAAC8pM9BAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOzde5wcVZ338U91zz1CIHQChAAmZCW7Dxuicsl6gcjFyAOajbpHfS0DuK5cVlfkooIr4A1ZV8FrRFFEGLxwuESIbEQgTMDFQMIuzuNKVBIICbnNMCQhmclMprueP7pn0t3TNVPdU93VXf19v8gr06dP1Tm/niFnTlWd33Fc10VERERERESklsTC7oCIiIiIiIhIsTSZFRERERERkZqjyayIiIiIiIjUHE1mRUREREREpOZoMisiIiIiIiI1R5NZERERERERqTkNYXdggrSvkIiIBM0JuwM1TmOziIgEreDYXOuTWTZv3hx2FwpKJBL09PSE3Y1ARCkWiFY8iqU6RSkWiFY848Uyffr0CvYmuoIam6P0s1eMeo0b6jf2eo0b6jf2eo0bio99rLFZjxmLiIiIiIhIzdFkVkRERERERGqOJrMiIiIiIiJSc2p+zayISD1wXZe9e/eSSqVwnMrmJ9q2bRsDAwMVbbNctm3bxt69e4nFYrS0tFT8sxQRkeiYyNgcpbG1WIVid123pLFZk1kRkRqwd+9eGhsbaWio/D/bDQ0NxOPxirdbDsOxDA0NsXfvXlpbW8PukoiI1KiJjM1RGluL5RV7KWOzHjMWEakBqVQqlIlsVDU0NJBKpcLuhoiI1DCNzcEqZWzWZFZEpAbocdjg6TMVEZGJ0DgSvGI/U01mRUQkcHfddRdbt24NuxsiIiKSEcWxWffFRUQiKLWqE3dpB/T2wJQEzuJ2YvMXVKz9u+++mzlz5nDYYYdVrE0REZFqlj02Jw+ZivP352psniBNZkVEIia1qhO3YwkMZjIF9nbjdiwhBRMaNPv6+rjooovYsmULqVSKSy+9lJkzZ/KFL3yBPXv2MGXKFL7xjW+wevVqfv/73/Pxj3+clpYWHnjgAdasWcOXvvQlkskkxx9/PDfccAPNzc185Stf4Te/+Q0NDQ2ccsopXHvttfzmN7/h29/+NoODgxx88MF897vfZerUqYF8NiIiImEYNTa/sl1jcwA0mRURiRh3acf+wXLY4EC6fAID5mOPPcZhhx1GR0cHALt27eLcc8/ltttu45BDDuH+++/nq1/9KjfddBM/+clPuOaaazj++OPZu3cvl112GXfddRfHHHMMn/jEJ7jjjjt4//vfz/Lly3n88cdxHIedO3cCcNJJJ7Fs2TIcx+FnP/sZ3/ve97juuutK7reIiEjYNDaXhyazIiJR09tTXLlPc+bM4Utf+hLXX389Z5xxBpMnT+ZPf/oTH/zgB4F0Vsdp06aNOm7dunUcddRRHHPMMQD8wz/8A7fffjsf/vCHaW5u5sorr+T000/njDPOAGDLli1ccsklbN++ncHBQY466qgJ9VtERCR0GpvLQpNZEZGomZKA3u7C5RNwzDHHsHz5clasWMENN9zAKaecwhve8AaWLVs25nGu6xYsb2ho4MEHH+S3v/0t999/P7fddht3330311xzDRdeeCHvfOc7efLJJ7npppsm1G8REZHQaWwuC2UzFhGJGGdxOzQ15xY2NafLJ2Dr1q20trbyvve9j4svvpj/+Z//obe3lzVr1gCwb98+/vSnPwEwadIkdu/eDcDs2bPZuHEjL7zwAgD33nsv8+fPZ8+ePbz22mucfvrpfOELX+CPf/wjkH5Eajg5xd133z2hPouIiFQDjc3loTuzIiIRE5u/gBQEns147dq1fPnLX8ZxHBobG7nhhhuIx+Nce+217Nq1i2QyyT//8z9z7LHHYozhqquuGkkycdNNN3HRRReNJJlob29nx44d/NM//RMDAwO4rjuy9uaKK67goosu4rDDDuNNb3oTGzdunPiHIiIiEqJRY3NA2YzrfWx2vG4x1wh38+bNYfehoEQiQU/PxJ6BrxZRigWiFY9iqU7liKWvr4+2trZAz+lXQ0MDQ0NDobQdtOxYCn2m06dPByhux3bJF9jYHKV/F4pRr3FD/cZer3FDbcc+kbE5SmNrscaKvdixWY8Zi4iIiIiISM3RZFZERERERERqjiazIiIiIiIiUnM0mRUREREREZGao8msiIiIiIiI1BxNZkVERERERKTmaDIrIiKh+drXvsbjjz9e9HFPPvkk5513Xhl6JCIiUt9qaWxuqGhrIiJSEStf2EnHs9309A2RaGugfd5UTp05OZS+uK6L67rEYqOvn37qU5+qSB+GhoZoaNCQJyIi4ckZmyc1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uIO777671K6JiIjUpXoam3VnVqQUvR77oXmVi1TYpg0DrO3aS3+fS2ubw5y5Lcw4unn8A4t02GGH8cMf/nBU+dDQEA0N3kPM17/+9XHPfd55502obyIiItUkd2yOMWdus8bmCdJkVqQUUxLQ2124XCRkmzYM0LW6n2Qy/bq/z6VrdT/AhAbN66+/niOOOIILLrgAgBtvvJFJkyZhrWXFihXcddddPProowwMDNDX18ddd93Fv/3bv7Fq1SqOPPJIXNflAx/4AOeccw7vf//7ueaaazj++OP5q7/6Kz7ykY/wyCOP0NLSwm233cbUqVNHzn/xxRfzwgsvcNVVV/HKK68Qj8f5wQ9+wNSpU/nwhz/Mzp07GRoa4tOf/jQLFy6c6McnIiISuNFjc0pjcwD0mLFICZzF7dCU9w9PU3O6XCRka7v2jgyWw5LJdPlELFq0iGXLlo28XrZsGfPmzcup88wzz/DNb36Tu+++m//8z/9k06ZNPProo3z961/nmWeeKXjevr4+3vSmN/HII48wf/58fvrTn46q86//+q9ccMEFPPLII9x///0ceuihNDc3c+utt/LQQw9x991388UvfhHXdScUo4iISDlobC4P3ZkVKUFs/gJSoGzGUpX6+woPGl7lfh133HH09PSwdetWXnnlFSZPnswRRxyRU+eUU07h4IMPBuDpp5/mnHPOIRaLMW3aNN7ylrcUPG9TUxNnnnkmAH/7t3/LE088kfP+7t272bJlC2eddRYALS0tAOzbt49///d/56mnnsJxHLZu3Up3dzfTpk2bUJwiIiJB09hcnrFZk1mREsXmLwBNXqUKtbY5BQfH1jZnwuc+++yzefDBB9m+fTuLFi0a9X5bW1vR52xoaMBx0n2Lx+MMDQ3lvO91Rfe+++7jlVdeYfny5TQ2NnLyySczMDBQsK6IiEiYNDaXhx4zFhGJmDlzW4jHc8vi8XT5RC1atIj777+fBx98kLPPPnvMuieeeCIPPvggqVSK7u5ufve735XU5gEHHMDhhx/Or3/9awAGBgbo7+/ntddeI5FI0NjYyH/913+xadOmks4vIiJSbhqby0OTWRGRiJlxdDNzT2wdudrb2uYw98TWQDImHnvssezZs4fDDjuMQw89dMy6Z599NocffjinnXYan/nMZ3jjG9/IgQceWFK73/72t7n11ls544wzWLRo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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "from sklearn.datasets import load_iris\n", "\n", @@ -182,7 +226,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -206,7 +250,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -234,9 +278,273 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING:tensorflow:From /Users/yunzhi/anaconda3/lib/python3.7/site-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Call initializer instance with the dtype argument instead of passing it to the constructor\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "WARNING:tensorflow:Can save best model only with accuracy available, skipping.\n", + "Loss is 0.6368\n", + "Accuracy is 0.5526\n" + ] + } + ], "source": [ "original_model = train_on_iris() # This trains the model and returns it.\n", "train_x, train_y, test_x, test_y = get_iris_data()\n", @@ -258,7 +566,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -305,11 +613,40 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], - "source": [ - "def tune_iris(): # TODO: Change me.\n", + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "pip install 'ray[tune]' to see TensorBoard files.\n", + "Could not instantiate TBXLogger: No module named 'tensorboardX'.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test-running to make sure this function will run correctly.\n" + ] + }, + { + "ename": "AssertionError", + "evalue": "Did you set the right configuration?", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 21\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Test-running to make sure this function will run correctly.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[0mtune\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrack\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# For testing purposes only.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 23\u001b[0;31m \u001b[0mtune_iris\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m\"lr\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0.1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"dense_1\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"dense_2\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 24\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Success!\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mtune_iris\u001b[0;34m(config)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mtune_iris\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconfig\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# TODO: Change me.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mtrain_x\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrain_y\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtest_x\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtest_y\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_iris_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mmodel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcreate_model\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlearning_rate\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdense_1\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdense_2\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# TODO: Change me.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m checkpoint_callback = ModelCheckpoint(\n\u001b[1;32m 5\u001b[0m \"model.h5\", monitor='loss', save_best_only=True, save_freq=2)\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mcreate_model\u001b[0;34m(learning_rate, dense_1, dense_2)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcreate_model\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlearning_rate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdense_1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdense_2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0mlearning_rate\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mdense_1\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mdense_2\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"Did you set the right configuration?\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mmodel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mSequential\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mDense\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdense_1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput_shape\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mactivation\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'relu'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'fc1'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mDense\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdense_2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mactivation\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'relu'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'fc2'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mAssertionError\u001b[0m: Did you set the right configuration?" + ] + } + ], + "source": [ + "def tune_iris(config): # TODO: Change me.\n", " train_x, train_y, test_x, test_y = get_iris_data()\n", " model = create_model(learning_rate=0, dense_1=0, dense_2=0) # TODO: Change me.\n", " checkpoint_callback = ModelCheckpoint(\n", @@ -383,15 +720,27 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "ename": "AssertionError", + "evalue": "The hyperparameter space is not fully designated. It must include all of ['lr', 'dense_1', 'dense_2']", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mHP_KEYS\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m\"lr\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"dense_1\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"dense_2\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m assert all(key in hyperparameter_space for key in HP_KEYS), (\n\u001b[0;32m---> 10\u001b[0;31m \"The hyperparameter space is not fully designated. It must include all of {}\".format(HP_KEYS))\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0;31m######################################################################################################\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mAssertionError\u001b[0m: The hyperparameter space is not fully designated. It must include all of ['lr', 'dense_1', 'dense_2']" + ] + } + ], "source": [ "# This seeds the hyperparameter sampling.\n", "import numpy as np; np.random.seed(5) \n", - "hyperparameter_space = {} # TODO: Fill me out.\n", + "hyperparameter_space = {\"lr\"} # TODO: Fill me out.\n", "num_samples = 1 # TODO: Fill me out.\n", "\n", "####################################################################################################\n", @@ -547,7 +896,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" } }, "nbformat": 4,