如何快速地将机器学习模型,给创建和分享出去,让更多的人来体验?
Gradio就是一种快速搭建web界面来演示机器学习模型的方式,任何人都可以在任何地方使用它。
官网地址:https://gradio.app/
1、安装Gradio
前提条件:Gradio需要Python 3.7或更高版本,仅此而已!
一般国内用户我都推荐加镜像来安装,个人喜欢豆瓣镜像,稳定,速度快。
pip install gradio -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
检测下安装是否成功,这里可以是在命令行或jupyter lab中都可以,运行方式很多。
import gradio as gr
print(gr.__version__)
3.28.1
2、运行Demo
2.1、给输入加个“你好”
先来个最简单的Demo,输入一个人名,点击提交,输出一个“你好,人名”
import gradio as gr
def greet(name):
return "你好," + name + "!"
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
demo.launch()
运行之后,可以看到左边输入“寅恪光潜”,点击“Submit”之后,右边输出“你好,寅恪光潜”。这里我是在JupyterLab中运行的,所以这种交互式可以直接在当前运行界面进行直接的输入和输出,当然这里也会提供一个URL:http://127.0.0.1:7861 点击这个链接同样也可以进行交互,如下图:
还可以生成公共链接,只需要在launch函数里面指定share=True即可
demo.launch(share=True)
这样就除了一个本地URL之外还有一个72小时有效期的公共外链,很方便的让不同地区的用户来体验。
这个就是安装到运行的过程,可以看到,过程是很简单的,代码也很简单,就是调用gradio模块中的Interface类。这里只用到三个参数就搞定,第一个是回调函数,第二个是输入组件,这里的类型是文本框,第二个是输出组件,类型是文本框。当然对于这个类的更详细的介绍,可以print(help(gr.Interface))
是不是省去了很多搭建前端的工作,确实是一个很Nice的工具!
2.2、多行输入文本
上面的文本框默认是单行,也可以指定为多行,也是gradio模块里面的类,我们可以查看其下面有哪些:
['Accordion', 'AnnotatedImage', 'Annotatedimage', 'Audio', 'BarPlot', 'Blocks', 'Box', 'Button', 'CSVLogger', 'Carousel', 'Chatbot', 'Checkbox', 'CheckboxGroup', 'Checkboxgroup', 'Code', 'ColorPicker', 'Column', 'DataFrame', 'Dataframe', 'Dataset', 'Dropdown', 'Error', 'EventData', 'Examples', 'File', 'Files', 'FlaggingCallback', 'Gallery', 'Group', 'HTML', 'Highlight', 'HighlightedText', 'Highlightedtext', 'HuggingFaceDatasetJSONSaver', 'HuggingFaceDatasetSaver', 'Image', 'ImageMask', 'ImagePaint', 'Interface', 'Interpretation', 'JSON', 'Json', 'Label', 'LinePlot', 'List', 'Markdown', 'Matrix', 'Mic', 'Microphone', 'Model3D', 'Number', 'Numpy', 'Paint', 'Parallel', 'Pil', 'PlayableVideo', 'Plot', 'Progress', 'Radio', 'Request', 'Row', 'ScatterPlot', 'SelectData', 'Series', 'SimpleCSVLogger', 'Sketchpad', 'Slider', 'State', 'StatusTracker', 'Tab', 'TabItem', 'TabbedInterface', 'Tabs', 'Text', 'TextArea', 'Textbox', 'Theme', 'TimeSeries', 'Timeseries', 'UploadButton', 'Variable', 'Video', 'Webcam', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'blocks', 'close_all', 'component', 'components', 'context', 'current_pkg_version', 'data_classes', 'deprecation', 'events', 'exceptions', 'external', 'external_utils', 'flagging', 'gradio', 'helpers', 'inputs', 'interface', 'interpretation', 'ipython_ext', 'layouts', 'load', 'load_ipython_extension', 'make_waveform', 'mix', 'mount_gradio_app', 'networking', 'outputs', 'pipelines', 'pkgutil', 'processing_utils', 'queueing', 'ranged_response', 'routes', 'skip', 'strings', 'templates', 'themes', 'tunneling', 'update', 'utils']
可以看到除了文本框之外,复选框、图片、视频、文件、麦克风等等都有,还是很丰富的。
文本指定为多行,只需要指定其参数lines=num即可
demo = gr.Interface(fn=greet, inputs=gr.Textbox(lines=4,placeholder='请输入名字'), outputs="text")
这里就指定为4行的多行文本框,其中placeholder是个占位符,起到提示作用。
2.3、接收多个组件的输入
除了接收一个输入源之外,我们还可以接收来自多个组件的输入,也可以输出多个,我们来看下输入这边,除了文本框之外,加一个复选框,滑动块(华氏度),输出也是多个,一个文本框和一个数字框。
import gradio as gr
def greet(name, is_boy, Fahrenheit):
salutation = "你好,帅哥。" if is_boy else "你好,美女。"
celsius = round((Fahrenheit - 32)/1.8 , 2)
greeting = f"{salutation} {name}. 今天温度:{celsius}摄氏度"
return greeting,celsius
demo = gr.Interface(
fn=greet,
inputs=["text", "checkbox", gr.Slider(0, 100)],
outputs=["text", "number"],
)
demo.launch()
这里我们可以知道,输入和输出的组件,都顺序放在列表当中,其中函数的输入组件跟函数的参数一一对应,同样的输出组件也是一一对应。这种极简的做法真的大大减少了工作量,更快速的生成web界面给顾客使用。当然也可以不到web界面进行输入,直接调用来测试结果:
from gradio_client import Client
client = Client("http://127.0.0.1:7872/")
result = client.predict("Tony",False,33,api_name="/predict")
print(result)
'''
Loaded as API: http://127.0.0.1:7872/ ✔
('你好,美女。 Tony. 今天温度:0.56摄氏度', 0.56)
'''
2.4、图像组件
既然是为机器学习模型而开发的工具,那么图片是最常用的一种,肯定是支持的,我们来看下,将一张彩色图片转换成棕黑色滤镜的图片,代码如下:
import numpy as np
import gradio as gr
def sepia(input_img):
sepia_filter = np.array([
[0.393, 0.769, 0.189],
[0.349, 0.686, 0.168],
[0.272, 0.534, 0.131]
])
sepia_img = input_img.dot(sepia_filter.T)
sepia_img /= sepia_img.max() #控制在[-1,1]
return sepia_img
demo = gr.Interface(sepia, gr.Image(shape=(600, 600)), "image")
demo.launch()
代码可以知道,输入和输出都是图片组件,可以指定图片的大小,这里宽高都指定为600,跟输入图片的实际大小无关。然后函数接收的图片是(W,H,3),其中最后一维是3个通道,就是RGB值。最后我们将以NumPy数组的形式返回一个图像,当然在浏览器中又要做处理,转换成图片格式。
我们看下效果图:
其中右上角的红色圈位置,可以点击对图片进行编辑,以这种方式裁剪图像可以帮助我们了解机器学习模型中的偏见或隐藏缺陷。
3、使用Blocks更灵活的控制
上面我们使用的是Interface接口来实现,这个优点就是快速布局,接下来我们来看下Blocks,可以控制组件在页面中的位置,处理复杂的数据流(例如输出可以作为其他函数的输入),以及基于用户交互更新组件的属性/可见性,显得更加的灵活。
import gradio as gr
def greet(name):
return "很久不见 " + name + "你好"
with gr.Blocks() as demo:
name = gr.Textbox(label="姓名")
output = gr.Textbox(label="输出问候语")
greet_btn = gr.Button("Greet")
greet_btn.click(fn=greet, inputs=name, outputs=output, api_name="greet")
demo.launch()
Blocks是用with子句创建的,在这个子句中创建的任何组件都会自动添加到应用中。组件按照创建的顺序垂直显示在应用程序中。
创建一个Button,然后向该按钮添加了一个单击事件侦听器。这个API看起来应该很熟悉!与Interface一样,click方法接受一个Python函数、输入组件和输出组件。其中api_name可选。
4、更复杂的Blocks应用
对Blocks有了了解之后,我们来做一个复杂点的东西,使用菜单来做多个功能的切换,接下来是两个菜单,一个翻转文本,一个翻转图片的功能:
import numpy as np
import gradio as gr
def flip_text(x):
return x[::-1]
def flip_image(x):
return np.fliplr(x)
with gr.Blocks() as demo:
gr.Markdown("翻转文本或图片")
with gr.Tab("翻转文本"):
text_input = gr.Textbox()
text_output = gr.Textbox()
text_button = gr.Button("点击翻转")
with gr.Tab("翻转图片"):
with gr.Row():
image_input = gr.Image()
image_output = gr.Image()
image_button = gr.Button("翻转图片")
with gr.Accordion("查看更多!"):
gr.Markdown("这里可以是一些说明之类的...")
text_button.click(flip_text, inputs=text_input, outputs=text_output)
image_button.click(flip_image, inputs=image_input, outputs=image_output)
demo.launch()
多出一个gr.Markdown()这里面可以放Markdown格式的内容,或gr.HTML()这个就是常见的HTML内容了
在gr.Blocks()下面使用gr.Tab()来做翻转文本和翻转图片的菜单。其余的差不多,参数也是函数、输入、输出。
小结:总的来说,真的就是一个字,爽。特别的方便,因为在输入和输出的时候,已做了前置处理和后置处理,比如说输入的图片,首先前置转换为numpy,然后经过函数处理之后,就做后置处理,转换成浏览器能够显示的图片格式,呈现出来。