This commit is contained in:
Ali Abid 2020-07-08 06:52:37 -07:00
commit db2b65764d
8 changed files with 263 additions and 101 deletions

221
README.md
View File

@ -4,14 +4,155 @@
<img src="https://i.ibb.co/GHRk2JP/header-2.png" alt="drawing" width="1000"/>
At Gradio, we often try to understand what inputs that a model is particularly sensitive to. To help facilitate this, we've developed and open-sourced `gradio`, a python library that allows you to easily create input and output interfaces over trained models to make it easy for you to "play around" with your model in your browser by dragging-and-dropping in your own images (or pasting your own text, recording your own voice, etc.) and seeing what the model outputs. We are working on making creating a shareable, public link to your model so you can share the interface with others (e.g. your client, your advisor, or your dad), who can use the model without writing any code.
At Gradio, we often try to understand what inputs a model is particularly sensitive to. To help facilitate this, we've developed and open-sourced `gradio`, a python library that allows you to quickly create input and output interfaces over trained models to make it easy for you to "play around" with your model in your browser by dragging-and-dropping in your own images (or pasting your own text, recording your own voice, etc.) and seeing what the model outputs. `gradio` can also generate a share link which allows anyone, anywhere to use the interface as the model continues to run on your machine.
Gradio is useful for:
* Creating demos of your machine learning code for clients / collaborators / users
* Getting feedback on model performance from users
* Debugging your model interactively during development
For more details, see the accompanying paper: ["Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild"](https://arxiv.org/pdf/1906.02569.pdf), *ICML HILL 2019*, and please use the citation below.
To get a sense of `gradio`, take a look at a few of these examples, and find more on our website: www.gradio.app.
## Installation
```
pip install gradio
```
(you may need to replace `pip` with `pip3` if you're running `python3`).
## Usage
Gradio is very easy to use with your existing code. Here are a few working examples:
### 0. Hello World [![alt text](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/18ODkJvyxHutTN0P5APWyGFO_xwNcgHDZ?usp=sharing)
Let's start with a basic function (no machine learning yet!) that greets an input name. We'll wrap the function with a `Text` to `Text` interface.
```python
import gradio as gr
def greet(name):
return "Hello " + name + "!"
gr.Interface(fn=greet, inputs="text", outputs="text").launch()
```
The core Interface class is initialized with three parameters:
- `fn`: the function to wrap
- `inputs`: the name of the input interface
- `outputs`: the name of the output interface
Calling the `launch()` function of the `Interface` object produces the interface shown in image below.
<p align="center">
<img src="https://i.ibb.co/Z8p7gLZ/hello-world.png" alt="drawing"/>
</p>
### 1. Inception Net [![alt text](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1c6gQiW88wKBwWq96nqEwuQ1Kyt5LejiU?usp=sharing)
Now, let's do a machine learning example. We're going to wrap an
interface around the InceptionV3 image classifier, which we'll load
using Tensorflow! Since this is an image classification model, we will use the `Image` input interface.
We'll output a dictionary of labels and their corresponding confidence scores with the `Label` output
interface. (The original Inception Net architecture [can be found here](https://arxiv.org/abs/1409.4842))
```python
import gradio as gr
import tensorflow as tf
import numpy as np
import requests
inception_net = tf.keras.applications.InceptionV3() # load the model
# Download human-readable labels for ImageNet.
response = requests.get("https://git.io/JJkYN")
labels = response.text.split("\n")
def classify_image(inp):
inp = inp.reshape((-1, 299, 299, 3))
inp = tf.keras.applications.inception_v3.preprocess_input(inp)
prediction = inception_net.predict(inp).flatten()
return {labels[i]: float(prediction[i]) for i in range(1000)}
image = gr.inputs.Image(shape=(299, 299, 3))
label = gr.outputs.Label(num_top_classes=3)
gr.Interface(fn=classify_image, inputs=image, outputs=label).launch()
```
This code will produce the interface below. The interface gives you a way to test
Inception Net by dragging and dropping images, and also allows you to use naturally modify the input image using image editing tools that
appear when you click EDIT. Notice here we provided actual `gradio.inputs` and `gradio.outputs` objects to the Interface
function instead of using string shortcuts. This lets us use built-in preprocessing (e.g. image resizing)
and postprocessing (e.g. choosing the number of labels to display) provided by these
interfaces.
<p align="center">
<img src="https://i.ibb.co/BtRNc62/inception-net.png" alt="drawing"/>
</p>
You can supply your own model instead of the pretrained model above, as well as use different kinds of models or functions. Here's a list of the interfaces we currently support, along with their preprocessing / postprocessing parameters:
**Input Interfaces**:
- `Sketchpad(shape=(28, 28), invert_colors=True, flatten=False, scale=1/255, shift=0, dtype='float64')`
- `Webcam(image_width=224, image_height=224, num_channels=3, label=None)`
- `Textbox(lines=1, placeholder=None, label=None, numeric=False)`
- `Radio(choices, label=None)`
- `Dropdown(choices, label=None)`
- `CheckboxGroup(choices, label=None)
- `Slider(minimum=0, maximum=100, default=None, label=None)`
- `Image(shape=(224, 224, 3), image_mode='RGB', scale=1/127.5, shift=-1, label=None)`
- `Microphone()`
**Output Interfaces**:
- `Label(num_top_classes=None, label=None)`
- `KeyValues(label=None)`
- `Textbox(lines=1, placeholder=None, label=None)`
- `Image(label=None, plot=False)`
Interfaces can also be combined together, for multiple-input or multiple-output models.
### 2. Real-Time MNIST [![alt text](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1LXJqwdkZNkt1J_yfLWQ3FLxbG2cAF8p4?usp=sharing)
Let's wrap a fun `Sketchpad`-to-`Label` UI around MNIST. For this example, we'll take advantage of the `live`
feature in the library. Set `live=True` inside `Interface()`> to have it run continuous predictions.
We've abstracted the model training from the code below, but you can see the full code on the colab link.
```python
import tensorflow as tf
import gradio as gr
from urllib.request import urlretrieve
urlretrieve("https://gr-models.s3-us-west-2.amazonaws.com/mnist-model.h5","mnist-model.h5")
model = tf.keras.models.load_model("mnist-model.h5")
def recognize_digit(inp):
prediction = model.predict(inp.reshape(1, 28, 28, 1)).tolist()[0]
return {str(i): prediction[i] for i in range(10)}
sketchpad = gr.inputs.Sketchpad()
label = gr.outputs.Label(num_top_classes=3)
gr.Interface(fn=recognize_digit, inputs=sketchpad,
outputs=label, live=True).launch()
```
This code will produce the interface below.
<p align="center">
<img src="https://i.ibb.co/9n2mGgk/mnist-live.png" alt="drawing"/>
</p>
## Contributing:
If you would like to contribute and your contribution is small, you can directly open a pull request (PR). If you would like to contribute a larger feature, we recommend first creating an issue with a proposed design for discussion. Please see our contributing guidelines for more info.
## License:
Gradio is licensed under the Apache License 2.0
## See more:
You can find many more examples (like GPT-2, model comparison, multiple inputs, and numerical interfaces) as well as more info on usage on our website: www.gradio.app
See, also, the accompanying paper: ["Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild"](https://arxiv.org/pdf/1906.02569.pdf), *ICML HILL 2019*, and please use the citation below.
```
@article{abid2019gradio,
@ -22,80 +163,4 @@ year={2019}
}
```
To get a sense of `gradio`, take a look at the at the `examples` and `demo` folders, or read on below! And be sure to visit the gradio website: www.gradio.app.
## Installation
```
pip install gradio
```
(you may need to replace `pip` with `pip3` if you're running `python3`).
## Usage
Gradio is very easy to use with your existing code. Here's a working example:
```python
import gradio
import tensorflow as tf
from imagenetlabels import idx_to_labels
def classify_image(inp):
inp = inp.reshape((1, 224, 224, 3))
prediction = mobile_net.predict(inp).flatten()
return {idx_to_labels[i].split(',')[0]: float(prediction[i]) for i in range(1000)}
imagein = gradio.inputs.Image(shape=(224, 224, 3))
label = gradio.outputs.Label(num_top_classes=3)
gr.Interface(classify_image, imagein, label, capture_session=True).launch();
```
![alt text](https://i.ibb.co/nM97z2B/image-interface.png)
You can supply your own model instead of the pretrained model above, as well as use different kinds of models or functions. Changing the `input` and `output` parameters in the `Interface` face object allow you to create different interfaces, depending on the needs of your model. Take a look at the python notebooks for more examples. The currently supported interfaces are as follows:
**Input interfaces**:
* Sketchpad
* ImageUplaod
* Webcam
* Textbox
**Output interfaces**:
* Label
* Textbox
## Screenshots
Here are a few screenshots that show examples of gradio interfaces
#### MNIST Digit Recognition (Input: Sketchpad, Output: Label)
```python
sketchpad = Sketchpad()
label = Label(num_top_classes=4)
gradio.Interface(predict, sketchpad, label).launch();
```
![alt text](https://i.ibb.co/CV8Kk3D/sketchpad-interface.png)
#### Human DNA Variant Effect Prediction (Input: Textbox, Output: Label)
```python
gradio.Interface(predict, 'textbox', 'label').launch()
```
![alt text](https://i.ibb.co/C7GXDDQ/label-interface.png)
### Contributing:
If you would like to contribute and your contribution is small, you can directly open a pull request (PR). If you would like to contribute a larger feature, we recommend first creating an issue with a proposed design for discussion. Please see our contributing guidelines for more info.
### License:
Gradio is licensed under the Apache License 2.0
### See more:
Find more info on usage here: www.gradio.app.

View File

@ -19,9 +19,15 @@ import inspect
from IPython import get_ipython
import sys
import weakref
import analytics
import socket
PKG_VERSION_URL = "https://gradio.app/api/pkg-version"
analytics.write_key = "uxIFddIEuuUcFLf9VgH2teTEtPlWdkNy"
analytics_url = 'https://api.gradio.app/'
hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
class Interface:
@ -89,6 +95,21 @@ class Interface:
self.simple_server = None
Interface.instances.add(self)
data = {'fn': fn,
'inputs': inputs,
'outputs': outputs,
'saliency': saliency,
'live': live,
'capture_session': capture_session,
'host_name': hostname,
'ip_address': ip_address
}
try:
requests.post(analytics_url + 'gradio-initiated-analytics/',
data=data)
except requests.ConnectionError:
print("gradio-initiated-analytics/ Connection Error")
def get_config_file(self):
config = {
"input_interfaces": [
@ -184,6 +205,12 @@ class Interface:
processed_input = self.input_interface.preprocess(msg)
prediction = self.predict(processed_input)
except Exception as e:
data = {'error': e}
try:
requests.post(analytics_url + 'gradio-error-analytics/',
data=data)
except requests.ConnectionError:
print("gradio-error-analytics/ Connection Error")
if self.verbose:
print("\n----------")
print(
@ -194,6 +221,12 @@ class Interface:
try:
_ = self.output_interface.postprocess(prediction)
except Exception as e:
data = {'error': e}
try:
requests.post(analytics_url + 'gradio-error-analytics/',
data=data)
except requests.ConnectionError:
print("gradio-error-analytics/ Connection Error")
if self.verbose:
print("\n----------")
print(
@ -250,6 +283,12 @@ class Interface:
is_colab = True
print("Google colab notebook detected.")
except NameError:
data = {'error': 'NameError in launch method'}
try:
requests.post(analytics_url + 'gradio-error-analytics/',
data=data)
except requests.ConnectionError:
print("Connection Error")
pass
try:
@ -278,6 +317,12 @@ class Interface:
share_url = networking.setup_tunnel(server_port)
print("Running on External URL:", share_url)
except RuntimeError:
data = {'error': 'RuntimeError in launch method'}
try:
requests.post(analytics_url + 'gradio-error-analytics/',
data=data)
except requests.ConnectionError:
print("Connection Error")
share_url = None
if self.verbose:
print(strings.en["NGROK_NO_INTERNET"])
@ -343,6 +388,19 @@ class Interface:
sys.stdout.flush()
time.sleep(0.1)
launch_method = 'browser' if inbrowser else 'inline'
data = {'launch_method': launch_method,
'is_google_colab': is_colab,
'is_sharing_on': share,
'share_url': share_url,
'host_name': hostname,
'ip_address': ip_address
}
try:
requests.post(analytics_url + 'gradio-hosted-launched-analytics/',
data=data)
except requests.ConnectionError:
print("Connection Error")
return httpd, path_to_local_server, share_url
@classmethod

View File

@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: gradio
Version: 0.9.8
Version: 0.9.9.1
Summary: Python library for easily interacting with trained machine learning models
Home-page: https://github.com/gradio-app/gradio-UI
Author: Abubakar Abid

View File

@ -4,3 +4,4 @@ paramiko
scipy
IPython
scikit-image
analytics

View File

@ -243,8 +243,7 @@ class Checkbox(AbstractInput):
class Image(AbstractInput):
def __init__(self, cast_to=None, shape=(224, 224), image_mode='RGB', label=None):
self.cast_to = cast_to
def __init__(self, shape=(224, 224), image_mode='RGB', label=None):
self.image_width = shape[0]
self.image_height = shape[1]
self.image_mode = image_mode
@ -264,29 +263,10 @@ class Image(AbstractInput):
**super().get_template_context()
}
def cast_to_base64(self, inp):
return inp
def cast_to_im(self, inp):
return preprocessing_utils.decode_base64_to_image(inp)
def cast_to_numpy(self, inp):
im = self.cast_to_im(inp)
arr = np.array(im).flatten()
return arr
def preprocess(self, inp):
"""
Default preprocessing method for is to convert the picture to black and white and resize to be 48x48
"""
cast_to_type = {
"base64": self.cast_to_base64,
"numpy": self.cast_to_numpy,
"pillow": self.cast_to_im
}
if self.cast_to:
return cast_to_type[self.cast_to](inp)
im = preprocessing_utils.decode_base64_to_image(inp)
with warnings.catch_warnings():
warnings.simplefilter("ignore")

View File

@ -19,9 +19,15 @@ import inspect
from IPython import get_ipython
import sys
import weakref
import analytics
import socket
PKG_VERSION_URL = "https://gradio.app/api/pkg-version"
analytics.write_key = "uxIFddIEuuUcFLf9VgH2teTEtPlWdkNy"
analytics_url = 'https://api.gradio.app/'
hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
class Interface:
@ -89,6 +95,21 @@ class Interface:
self.simple_server = None
Interface.instances.add(self)
data = {'fn': fn,
'inputs': inputs,
'outputs': outputs,
'saliency': saliency,
'live': live,
'capture_session': capture_session,
'host_name': hostname,
'ip_address': ip_address
}
try:
requests.post(analytics_url + 'gradio-initiated-analytics/',
data=data)
except requests.ConnectionError:
print("gradio-initiated-analytics/ Connection Error")
def get_config_file(self):
config = {
"input_interfaces": [
@ -184,6 +205,12 @@ class Interface:
processed_input = self.input_interface.preprocess(msg)
prediction = self.predict(processed_input)
except Exception as e:
data = {'error': e}
try:
requests.post(analytics_url + 'gradio-error-analytics/',
data=data)
except requests.ConnectionError:
print("gradio-error-analytics/ Connection Error")
if self.verbose:
print("\n----------")
print(
@ -194,6 +221,12 @@ class Interface:
try:
_ = self.output_interface.postprocess(prediction)
except Exception as e:
data = {'error': e}
try:
requests.post(analytics_url + 'gradio-error-analytics/',
data=data)
except requests.ConnectionError:
print("gradio-error-analytics/ Connection Error")
if self.verbose:
print("\n----------")
print(
@ -250,6 +283,12 @@ class Interface:
is_colab = True
print("Google colab notebook detected.")
except NameError:
data = {'error': 'NameError in launch method'}
try:
requests.post(analytics_url + 'gradio-error-analytics/',
data=data)
except requests.ConnectionError:
print("Connection Error")
pass
try:
@ -278,6 +317,12 @@ class Interface:
share_url = networking.setup_tunnel(server_port)
print("Running on External URL:", share_url)
except RuntimeError:
data = {'error': 'RuntimeError in launch method'}
try:
requests.post(analytics_url + 'gradio-error-analytics/',
data=data)
except requests.ConnectionError:
print("Connection Error")
share_url = None
if self.verbose:
print(strings.en["NGROK_NO_INTERNET"])
@ -343,6 +388,19 @@ class Interface:
sys.stdout.flush()
time.sleep(0.1)
launch_method = 'browser' if inbrowser else 'inline'
data = {'launch_method': launch_method,
'is_google_colab': is_colab,
'is_sharing_on': share,
'share_url': share_url,
'host_name': hostname,
'ip_address': ip_address
}
try:
requests.post(analytics_url + 'gradio-hosted-launched-analytics/',
data=data)
except requests.ConnectionError:
print("Connection Error")
return httpd, path_to_local_server, share_url
@classmethod

View File

@ -5,7 +5,7 @@ except ImportError:
setup(
name='gradio',
version='0.9.8',
version='0.9.9.1',
include_package_data=True,
description='Python library for easily interacting with trained machine learning models',
author='Abubakar Abid',

0
upload_to_pypi.sh Normal file → Executable file
View File