| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| version=None, | ||
| force_tfrecord=False): | ||
| import json | ||
| import itertools |
There was a problem hiding this comment.
why the local imports? This is not a DF job.
Sorry, something went wrong.
There was a problem hiding this comment.
This way the necessary inputs will show up in snippets in the docs. The [START foo] and [END foo] blocks indicate a displayable chunk for the docs
Sorry, something went wrong.
|
Note. On discussing with @jonparrott I'm going to remove predict_from_files and write a short webapp. |
Sorry, something went wrong.
|
|
||
| # Requests to online prediction | ||
| # can have at most 100 instances | ||
| args = [instances] * 100 |
There was a problem hiding this comment.
why are we making 100 copies of this tuple. This looks wrong.
Sorry, something went wrong.
There was a problem hiding this comment.
100 copies of the generator. This is how you batch generators in python (it's weird). But I'm deleting this code anyway in favor of a webapp.
Sorry, something went wrong.
| batch, | ||
| version=version | ||
| )) | ||
| return results |
There was a problem hiding this comment.
where are the results saved or printed?
Sorry, something went wrong.
| args = [instances] * 100 | ||
| instance_batches = itertools.izip(*args) | ||
|
|
||
| results = [] |
There was a problem hiding this comment.
so the input data could need batching (be large), but the results don't need batching? I'm ok with this script not doing batching. Depends on what others say.
Sorry, something went wrong.
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| # License for the specific language governing permissions and limitations under | ||
| # the License. | ||
| """Examples of using the Cloud ML Engine's online prediction service.""" |
There was a problem hiding this comment.
Add comments on authentication. When should this work, or what needs to be true for the script to work.
Sorry, something went wrong.
There was a problem hiding this comment.
Done
Sorry, something went wrong.
There was a problem hiding this comment.
in get_ml_engine_service, can you add a link to the doc page describing how I can download a service account file?
Sorry, something went wrong.
| @@ -0,0 +1 @@ | |||
| {"age": 25, "workclass": " Private", "education": " 11th", "education_num": 7, "marital_status": " Never-married", "occupation": " Machine-op-inspct", "relationship": " Own-child", "race": " Black", "gender": " Male", "capital_gain": 0, "capital_loss": 0, "hours_per_week": 40, "native_country": " United-States"} | |||
There was a problem hiding this comment.
does your batching code really work? Hard to tell with just 1 prediction row
Sorry, something went wrong.
|
@brandondutra Switched to user input stream to avoid problems of batching and file reading which don't really belong in an online prediction sample. |
Sorry, something went wrong.
Sorry, something went wrong.
|
@jonparrott Installing TensorFlow appears to be broken... @jonparrott can you PTAL? |
Sorry, something went wrong.
| import json | ||
| while True: | ||
| try: | ||
| user_input = json.loads(raw_input("Valid JSON >>>")) |
There was a problem hiding this comment.
I'm not a fan of raw-input (cannot re-run this quickly, and typing valid json is a pain). But this allows interactive input and "python predict.py < my_data.json". Maybe add file-level comments on these two ways of using this script?
Sorry, something went wrong.
There was a problem hiding this comment.
So the main reason I wanted to do it this way, is we already have a solution for batch prediction (via the API) and a 100 request limit seems really bad if the use-case we are highlighting is predicting from files.
Sorry, something went wrong.
|
|
||
|
|
||
| # [START census_to_example_bytes] | ||
| def census_to_example_bytes(json_instance): |
There was a problem hiding this comment.
I was expecting the file path to be in the census example (in cloudml-samples). Is this file part of the census sample or a more generic 'calling online prediction' sample? If the latter, we need better warnings that this will not work with every model, and we need to describe what the model is expecting.
If this is not part of the census sample, a s/census/json/g is needed.
Sorry if this is a bad question, I not familiar with python-docs-samples
Sorry, something went wrong.
There was a problem hiding this comment.
I was thinking we have sort of a hard separation between "things run as part of training" and "code run in your own client to send requests to the prediction service" The former being in cloudml-samples (and in the future tf/garden) and the latter being in python-docs-samples.
I will definitely add some better prose around this in the form of a docstring, and we'll also make it clear in docs.
Sorry, something went wrong.
| from predict import census_to_example_bytes, predict_json | ||
|
|
||
|
|
||
| MODEL = 'census' |
There was a problem hiding this comment.
I'm starting to think you want these files in GoogleCloudPlatform/cloudml-samples/census/something
Sorry, something went wrong.
| @@ -0,0 +1,173 @@ | |||
| # Copyright 2016 Google Inc. All Rights Reserved. Licensed under the Apache | |||
There was a problem hiding this comment.
This license header looks weird, copy it from elsewhere?
Sorry, something went wrong.
There was a problem hiding this comment.
s/2016/2017/g
Sorry, something went wrong.
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| # License for the specific language governing permissions and limitations under | ||
| # the License. | ||
| """Examples of using the Cloud ML Engine's online prediction service.""" |
There was a problem hiding this comment.
Nit: blank line between license and docstring.
Sorry, something went wrong.
| @@ -0,0 +1,173 @@ | |||
| # Copyright 2016 Google Inc. All Rights Reserved. Licensed under the Apache | |||
There was a problem hiding this comment.
Needs a shebang
Sorry, something went wrong.
| # [END import_libraries] | ||
|
|
||
|
|
||
| # [START authenticating] |
There was a problem hiding this comment.
We generally show constructing the service in each snippet instead of centralizing it. Every indirection adds cognitive load to the users.
Sorry, something went wrong.
| # [START predict_json] | ||
| def predict_json(project, model, instances, version=None): | ||
| """Send data instances to a deployed model for prediction | ||
| Args: |
There was a problem hiding this comment.
blank newline above here.
Sorry, something went wrong.
| to data. | ||
| version: [optional] str, version of the model to target. | ||
| Returns: | ||
| A dictionary of prediction results defined by the model. |
There was a problem hiding this comment.
We generally encourage snippets to be simple enough not to require this, but I understand if that's not reasonable here. If you're going to go full docstring, follow Napoleon style:
Args:
project (str): ...
model (str): ...
instances (Mapping[ str, dict ]): ...
version (str): optional ...
Returns:
Mapping [str, ...] : ...
Sorry, something went wrong.
| Returns: | ||
| A dictionary of prediction results defined by the model. | ||
| """ | ||
| import base64 |
There was a problem hiding this comment.
Don't import here, import at the top.
Sorry, something went wrong.
There was a problem hiding this comment.
How do you highlight that this import is only necessary for this snippet?
Is that not important?
Sorry, something went wrong.
| for example_bytes in example_bytes_list | ||
| ]} | ||
| ).execute() | ||
| if 'error' in response: |
There was a problem hiding this comment.
Blank new line to separate control statements.
Sorry, something went wrong.
|
|
||
| def main(project, model, version=None, force_tfrecord=False): | ||
| """Send user input to the prediction service.""" | ||
| import json |
There was a problem hiding this comment.
Don't import here.
Sorry, something went wrong.
| import json | ||
| while True: | ||
| try: | ||
| user_input = json.loads(raw_input("Valid JSON >>>")) |
There was a problem hiding this comment.
Where do the users find out what kind of json to send here?
Sorry, something went wrong.
There was a problem hiding this comment.
It depends on their model. This snippet will be part of a docs page that is attempting to explain just that. This will be at the end "now that you know what the prediction service does, here's how you call it".
Sorry, something went wrong.
| @@ -0,0 +1,38 @@ | |||
| # Online Prediction with the Cloud Machine Learning Engine | |||
There was a problem hiding this comment.
We don't have hand-written readmes in here any more. Please move all of this to the documentation and just link to the docs from here. I can add an auto-generated readme later.
Sorry, something went wrong.
There was a problem hiding this comment.
Oh cool.
Sorry, something went wrong.
| # the License. | ||
|
|
||
| """Examples of using the Cloud ML Engine's online prediction service.""" | ||
| from __future__ import print_function |
There was a problem hiding this comment.
This isn't necessary.
Sorry, something went wrong.
| model (str): model name. | ||
| instances ([Mapping[str: any]]): dictionaries from string keys | ||
| defined by the model deployment, to data with types that match | ||
| expected tensors |
There was a problem hiding this comment.
Period? Also, maybe it's just my unfamiliarity with tensorflow, but this reads like gibberish.
Sorry, something went wrong.
There was a problem hiding this comment.
Yeah it doesn't make much sense with context. But could also use some rewording.
Sorry, something went wrong.
| Args: | ||
| project (str): project where the Cloud ML Engine Model is deployed. | ||
| model (str): model name. | ||
| instances ([Mapping[str: any]]): dictionaries from string keys |
There was a problem hiding this comment.
Any is capital. What's the key and value here?
Sorry, something went wrong.
| expected tensors | ||
| version: str, version of the model to target. | ||
| Returns: | ||
| Mapping[str: any]: dictionary of prediction results defined by the |
There was a problem hiding this comment.
What's the key and value here?
Sorry, something went wrong.
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| # License for the specific language governing permissions and limitations under | ||
| # the License. | ||
| """Tests for predict.py .""" |
There was a problem hiding this comment.
blank newline both above and below this.
Sorry, something went wrong.
| @@ -0,0 +1,68 @@ | |||
| # Copyright 2016 Google Inc. All Rights Reserved. Licensed under the Apache | |||
There was a problem hiding this comment.
2017, also, these headers still seem different from the ones in the rest of the repo.
Sorry, something went wrong.
|
|
||
| import pytest | ||
|
|
||
| from predict import census_to_example_bytes, predict_json |
There was a problem hiding this comment.
just import predict, please don't import individual members.
Sorry, something went wrong.
| predict_json(PROJECT, MODEL, [{"foo": "bar"}], version=VERSION) | ||
|
|
||
|
|
||
| # TODO(elibixby) Run on Travis when TensorFlow PyPi package supports |
There was a problem hiding this comment.
Don't put todos in code, just file an issue or bug to track it.
Sorry, something went wrong.
| @@ -0,0 +1 @@ | |||
| tensorflow>=1.0.0 | |||
There was a problem hiding this comment.
Don't use ranges, pin the version and dpebot will handle updating it.
Sorry, something went wrong.
There was a problem hiding this comment.
LGTM after final nits, pending Travis.
Sorry, something went wrong.
| import googleapiclient.discovery | ||
| # [END import_libraries] | ||
|
|
||
| import six |
There was a problem hiding this comment.
this goes in the same section as import googleapiclient.discovery
Sorry, something went wrong.
| assert base64.b64encode(b) is not None | ||
|
|
||
|
|
||
| def test_predict_tfrecord(): |
There was a problem hiding this comment.
Why not write a real test and mark it with pytest.mark.xfail('reason')?
Sorry, something went wrong.
File-like objects should be opened in binary mode for `blob.upload_from_file()` - cpython standard library accorded with [RFC 2616 Section 3.7.1](https://datatracker.ietf.org/doc/html/rfc2616#section-3.7.1) states the text default charset of iso-8859-1 - add clarifying notes in docstring - update code sample Fixes #818 🦕
| Back | FazBrowse Home | New Git URL |
Add samples for triggering online prediction from code.
@nikhilk @brandondutra @JayLoomis since I can't make you reviewers on this repo.
Tests are to follow. This is to solicit initial feedback while I write tests. Note that I don't think we should highlight predict_from_files in the docs, as that's redundant and not as efficient as batch prediction. It's mainly there for testing and to make the file runnable (A repository policy).