Changed ray.select() to ray.wait() and its functionality (#426)

* Re-implemented select, changed name to wait

* Changed tests for select to tests for wait

* Updated the hyperopt example to match wait

* Small fixes and improve example readme.

* Make tests pass.
This commit is contained in:
Wapaul1
2016-09-14 17:14:11 -07:00
committed by Philipp Moritz
parent 8c6d3a88a9
commit d5815673a5
12 changed files with 132 additions and 69 deletions
+42 -4
View File
@@ -63,8 +63,9 @@ def generate_random_params():
results = []
for _ in range(100):
randparams = generate_random_params()
results.append((randparams, train_cnn_and_compute_accuracy(randparams, train_images, train_labels, validation_images, validation_labels)))
params = generate_random_params()
accuracy = train_cnn_and_compute_accuracy(randparams, train_images, train_labels, validation_images, validation_labels)
results.append(accuracy)
```
Then we can inspect the contents of `results` and see which set of
@@ -101,16 +102,53 @@ computation. Instead, it simply submits a number of tasks to the scheduler.
```python
result_ids = []
# Launch 100 tasks.
for _ in range(100):
params = generate_random_params()
results.append((params, train_cnn_and_compute_accuracy.remote(params, train_images, train_labels, validation_images, validation_labels)))
accuracy_id = train_cnn_and_compute_accuracy.remote(randparams, train_images, train_labels, validation_images, validation_labels)
result_ids.append(accuracy_id)
```
If we wish to wait until the results have all been retrieved, we can retrieve
their values with `ray.get`.
```python
results = [(params, ray.get(result_id)) for (params, result_id) in result_ids]
results = ray.get(result_ids)
```
One drawback of the above approach is that nothing will be printed until all of
the experiments have finished. What we'd really like is to start processing
the results of certain experiments as soon as they finish (and possibly launch
more experiments based on the outcomes of the first ones). To do this, we can
use `ray.wait`, which takes a list of object IDs and returns two lists of object
IDs.
```python
ready_ids, remaining_ids = ray.wait(result_ids, num_returns=3, timeout=10)
```
In the above, `result_ids` is a list of object IDs. The command `ray.wait` will
return as soon as either three of the object IDs in `result_ids` are ready (that
is, the task that created the corresponding object finished executing and stored
the object in the object store) or ten seconds pass, whichever comes first. To
wait indefinitely, omit the timeout argument. Now, we can rewrite the script as
follows.
```python
remaining_ids = []
# Launch 100 tasks.
for _ in range(100):
params = generate_random_params()
accuracy_id = train_cnn_and_compute_accuracy.remote(randparams, train_images, train_labels, validation_images, validation_labels)
result_ids.append(accuracy_id)
# Process the tasks one at a time.
while len(remaining_ids) > 0:
# Process the next task that finishes.
ready_ids, remaining_ids = ray.wait(remaining_ids, num_returns=1)
# Get the accuracy corresponding to the ready object ID.
accuracy = ray.get(ready_ids[0])
print "Accuracy {}".format(accuracy)
```
## Additional notes
+24 -11
View File
@@ -39,26 +39,39 @@ if __name__ == "__main__":
validation_images = ray.put(mnist.validation.images)
validation_labels = ray.put(mnist.validation.labels)
# Store the best parameters, the best accuracy, and all of the results.
# Keep track of the best parameters and the best accuracy.
best_params = None
best_accuracy = 0
results = []
# This list holds the object IDs for all of the experiments that we have
# launched and that have not yet been processed.
remaining_ids = []
# This is a dictionary mapping the object ID of an experiment to the
# parameters used for that experiment.
params_mapping = {}
# Randomly generate some hyperparameters, and launch a task for each set.
for i in range(trials):
# A function for generating random hyperparameters.
def generate_random_params():
learning_rate = 10 ** np.random.uniform(-5, 5)
batch_size = np.random.randint(1, 100)
dropout = np.random.uniform(0, 1)
stddev = 10 ** np.random.uniform(-5, 5)
params = {"learning_rate": learning_rate, "batch_size": batch_size, "dropout": dropout, "stddev": stddev}
results.append((params, hyperopt.train_cnn_and_compute_accuracy.remote(params, steps, train_images, train_labels, validation_images, validation_labels)))
return {"learning_rate": learning_rate, "batch_size": batch_size, "dropout": dropout, "stddev": stddev}
# Fetch the results of the tasks and print the results.
# Randomly generate some hyperparameters, and launch a task for each set.
for i in range(trials):
# Get the index of the first task that completes.
index = ray.select([result_id for _, result_id in results], num_objects=1)[0]
# Process the output of this task and remove it from the list.
params, result_id = results.pop(index)
params = generate_random_params()
accuracy_id = hyperopt.train_cnn_and_compute_accuracy.remote(params, steps, train_images, train_labels, validation_images, validation_labels)
remaining_ids.append(accuracy_id)
# Keep track of which parameters correspond to this experiment.
params_mapping[accuracy_id] = params
# Fetch and print the results of the tasks in the order that they complete.
for i in range(trials):
# Use ray.wait to get the object ID of the first task that completes.
ready_ids, remaining_ids = ray.wait(remaining_ids)
# Process the output of this task.
result_id = ready_ids[0]
params = params_mapping[result_id]
accuracy = ray.get(result_id)
print """We achieve accuracy {:.3}% with
learning_rate: {:.2}