7.4K Star! 只需几分钟,为机器学习模型生成一个漂亮的交互界面

人工智能 机器学习 开源
通过使用 Gradio, 您可以围绕机器学习模型或数据科学工作流,快速创建出漂亮的 UI 界面。

Gradio 是一个可用于构建机器学习、数据科学相关 demo 和 web 应用的开源 python 库。

通过使用 Gradio, 您可以围绕机器学习模型或数据科学工作流,快速创建出漂亮的 UI 界面,同时可以在浏览器中进行图像拖拽、文本粘贴、声音录制、与 demo 进行交互等操作。

图片

Gradio 适用于:

  • 为客户、合伙人、用户、学生群体演示您的机器学习模型
  • 使用自动共享链接功能快速部署您的模型,并且获得有关其性能的反馈信息
  • 使用内置的操作和解释工具,以交互的方式调试您的模型

您可以在 https://gradio.app/getting_started[1] 找到下方入门指南的交互式版本。

快速开始

前提:使用 Gradio 要求 Python 版本 >= 3.7

项目地址

https://github.com/gradio-app/gradio

Gradio 解决了什么问题 ?😲

与他人共享您的机器学习模型、API 或数据科学工作流的最好方式之一就是创建一个交互式的 demo,并允许您的用户或同事可以在他们的浏览器中体验这个 demo。

基于 web 的演示 demo 很值得青睐,因为它可以让任何可直接使用浏览器的人(不仅仅是技术人员)直观地尝试他们自己的输入,并了解您所构建的内容。

但是创建此类基于 web 的 demo 会很困难,因为您需要了解支撑 web 应用的后端服务以及构建 UI 界面的前端开发知识(HTML、CSS、JavaScript )。

Gradio 允许您通过仅使用 Python 的方式构建 demo 并分享它们,并且通常只需要几行代码!让我们开始吧。

Hello, World ⚡

在让 Gradio 运行一个简单的 “Hello World” 示例之前,请先遵循以下三个步骤:

1、使用 pip 安装 Gradio,请注意 python 的版本最低要求是 3.7。

pip install gradio

2、以执行 python 脚本的方式(或直接在 notebook 中)运行下面这段代码:

import gradio as gr

def greet(name):
return "Hello " + name + "!!"

demo = gr.Interface(fn=greet, inputs="text", outputs="text")

demo.launch()

3、下方的 demo 会自动出现在 notebook 中,如果以 python 脚本方式运行的话,则会在浏览器中自动弹出 http://localhost:7860[2]  页面。

图片

Interface 类 🧡

您可能会注意到,在上面创建的 demo 中,我们使用 gradio.Interface​ 类定义了一个对象。Interface 类几乎可以实现:以 UI 的方式装饰任何 python 函数。在示例中,我们使用了一个简单的、与文本相关的函数。但实际上,这个函数可以是任何东西:从音乐生成器到税收计算器,再到(最常见的)预训练机器学习模型的预测函数。

核心 Interface 类需要使用三个参数进行初始化:

  • fn:被 UI 装饰的函数
  • inputs​:输入组件。如"text"​、"image"​、"audio"等
  • outputs​:输出组件。如"text"​、"image"​、"label"等

Gradio 支持 20 多种不同的组件类型,其中大部分都可以作为输入/输出组件(完整列表可参考 官方文档[3])。

组件属性

使用 Interface​ 的三个参数,您可以快速创建 UI 界面并 launch() 它们。但是如何您想修改 UI 样式或表现方式,要如何做呢?

假设您想要自定义一个文本输入场景,例如,您希望文本框更大并且带有输入提示。通过使用 Textbox​ 类代替 "text" 输入类型,您就可以通过组件属性实现更多的定制化方案:

import gradio as gr

def greet(name):
return "Hello " + name + "!"

demo = gr.Interface(
fn=greet,
inputs=gr.Textbox(lines=2, placeholder="Name Here..."),
outputs="text",
)

demo.launch()

图片

想要查看 Gradio 支持的所有组件列表以及您可以使用哪些属性来自定义它们,请查阅 官方文档[3]。

多个输入与输出 🔥

假设您有一个更复杂的函数,有多个输入和输出。在下面的示例中,我们定义了一个函数,它的入参包含一个字符串、一个布尔值和一个数字,并返回一个字符串和一个数字。让我们看看此时要如何传递输入和输出组件列表。

import gradio as gr

def greet(name, is_morning, temperature):
salutation = "Good morning" if is_morning else "Good evening"
greeting = "%s %s. It is %s degrees today" % (salutation, name, temperature)
celsius = (temperature - 32) * 5 / 9
return greeting, round(celsius, 2)

demo = gr.Interface(
fn=greet,
inputs=["text", "checkbox", gr.Slider(0, 100)],
outputs=["text", "number"],
)
demo.launch()

图片

您只需将组件放在列表中:inputs​ 列表中的每个组件按顺序对应于函数的参数之一,outputs 列表中的每个组件也都对应于函数返回的值之一,同样按顺序排列。

图像 🎨

让我们尝试一个“图像转图像”的功能!当使用 Image​ 组件时,您的函数将接收指定大小的 numpy​ 数组,其形状为 (width, height, 3)​,其中最后一个维度表示 RGB​ 值。我们将以 numpy 数组的形式返回图像。

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()
return sepia_img

demo = gr.Interface(sepia, gr.Image(shape=(200, 200)), "image")

demo.launch()

图片

此外,我们的图像输入界面带有一个“编辑”按钮 ✏️,它可以打开用于裁剪和放大图像的工具。我们发现以这种方式处理图像,有助于揭示机器学习模型中的偏差或隐藏缺陷。

除了图像,Gradio 还支持其他媒体类型,例如音频或视频。可在 官方文档[3] 中阅读这些内容。

DataFrame 与图表 📈

您可以使用 Gradio 来支持来自数据库或数据文件的输入和输出。例如 ​​numpy​​​ 数组、​​pandas​​ dataframe 和绘图数据等。看看下面的演示(函数中复杂的数据操作可忽略):

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np

import gradio as gr

def sales_projections(employee_data):
sales_data = employee_data.iloc[:, 1:4].astype("int").to_numpy()
regression_values = np.apply_along_axis(
lambda row: np.array(np.poly1d(np.polyfit([0, 1, 2], row, 2))), 0, sales_data
)
projected_months = np.repeat(
np.expand_dims(np.arange(3, 12), 0), len(sales_data), axis=0
)
projected_values = np.array(
[
month * month * regression[0] + month * regression[1] + regression[2]
for month, regression in zip(projected_months, regression_values)
]
)
plt.plot(projected_values.T)
plt.legend(employee_data["Name"])
return employee_data, plt.gcf(), regression_values

demo = gr.Interface(
sales_projections,
gr.Dataframe(
headers=["Name", "Jan Sales", "Feb Sales", "Mar Sales"],
value=[["Jon", 12, 14, 18], ["Alice", 14, 17, 2], ["Sana", 8, 9.5, 12]],
),
["dataframe", "plot", "numpy"],
description="Enter sales figures for employees to predict sales trajectory over year.",
)
demo.launch()

图片

使用示例数据作为输入 🦮

您可以提供用户可以轻松加载到模型中的示例数据。这有助于演示模型所期望的输入类型,并提供一种结合模型探索数据集的方法。要加载示例数据,您可以为 Interface​ 构造函数中的 examples= 关键字参数提供一个嵌套列表。其中外部列表中的每个子列表代表一个数据样本,子列表中的每个元素代表每个输入组件的实际输入。每个组件的示例数据格式在 官方文档[3] 中也有所提及。

import gradio as gr

def calculator(num1, operation, num2):
if operation == "add":
return num1 + num2
elif operation == "subtract":
return num1 - num2
elif operation == "multiply":
return num1 * num2
elif operation == "divide":
return num1 / num2

demo = gr.Interface(
calculator,
[gr.Number(4), gr.Radio(["add", "subtract", "multiply", "divide"]), "number"],
"number",
examples=[
[5, "add", 3],
[4, "divide", 2],
[-4, "multiply", 2.5],
[0, "subtract", 1.2],
],
title="test calculator",
description="heres a sample toy calculator. enjoy!",
)

demo.launch()

图片

您可以将大型数据集加载到示例中,并通过 Gradio 浏览数据集并与之交互。示例将自动分页(您可以通过 ​​Interface​​​ 的 ​​examples_per_page​​ 参数进行配置)。

实时界面 🪁

您可以通过在 Interface​ 中设置 live=True 来使界面自动刷新。这样一旦用户输入发生变化,界面就会重新计算。

import gradio as gr

def calculator(num1, operation, num2):
if operation == "add":
return num1 + num2
elif operation == "subtract":
return num1 - num2
elif operation == "multiply":
return num1 * num2
elif operation == "divide":
return num1 / num2

demo = gr.Interface(
calculator,
["number", gr.Radio(["add", "subtract", "multiply", "divide"]), "number"],
"number",
live=True,
)

demo.launch()

图片

请注意,此处没有提交按钮,因为界面会在更改时自动重新提交。

标记 🚩

在界面的 output​ 下方,有一个“Flag”按钮。当测试您模型的用户看到带有有趣输出的输入时:例如错误或意外的模型行为,他们可以标记此时的输入以供界面创建者查看。在接口构造函数的 flagging_dir= 参数提供的目录中,会生成一个 CSV 文件用于记录标记的输入。如果接口涉及文件数据:例如图像和音频组件,则会创建文件夹来存储这些标记的数据。

例如,使用上面显示的计算器界面,我们会将标记数据存储在如下所示的标记目录中:

+-- calculator.py
+-- flagged/
| +-- logs.csv

flagged/logs.csv 内容:

num1,operation,num2,Output
5,add,7,12
6,subtract,1.5,4.5

使用上面实现的 sepia intereface,我们将标记数据存储在如下所示的标记目录中:

+-- sepia.py
+-- flagged/
| +-- logs.csv
| +-- im/
| | +-- 0.png
| | +-- 1.png
| +-- Output/
| | +-- 0.png
| | +-- 1.png

flagged/logs.csv 内容:

im,Output
im/0.png,Output/0.png
im/1.png,Output/1.png

您可以通过手动浏览标记目录来查看这些标记输入,或者通过将 examples=​ 参数指向标记目录将它们加载到 Gradio 接口的示例中。如果您希望用户提供标记的原因,您可以将字符串列表传递给 Interface 的 flagging_options 参数。用户在标记时必须选择其中一个字符串,该字符串将作为附加列保存到 CSV。

Blocks: 更好的灵活性与控制 🧱

Gradio 为用户提供了两个 API:(1) Interface,一个用于创建演示的高级抽象类(到目前为止我们一直在讨论),以及 (2) Blocks,一个用于设计具有更灵活布局的 Web 应用程序的低级 API 和数据流。

Blocks 允许您执行以下操作:将相关的演示组合在一起,更改组件在页面上的显示位置,处理复杂的数据流(例如,输出可以作为其他功能的输入),以及基于用户交互更新组件的属性/可见性等。——以上这些依然仅需要使用 Python。

例如,Blocks 使用 Python 中的嵌套 with 语句在页面上布局组件,如下所示:

import numpy as np
import gradio as gr

demo = gr.Blocks()

def flip_text(x):
return x[::-1]

def flip_image(x):
return np.fliplr(x)

with demo:
gr.Markdown("Flip text or image files using this demo.")
with gr.Tabs():
with gr.TabItem("Flip Text"):
text_input = gr.Textbox()
text_output = gr.Textbox()
text_button = gr.Button("Flip")
with gr.TabItem("Flip Image"):
with gr.Row():
image_input = gr.Image()
image_output = gr.Image()
image_button = gr.Button("Flip")

text_button.click(flip_text, inputs=text_input, outputs=text_output)
image_button.click(flip_image, inputs=image_input, outputs=image_output)

demo.launch()

图片

如果您对 Blocks 的工作原理感兴趣,请阅读其专用指南[4]。

分享 Demo 🌎

通过在 launch()​ 方法中设置 share=True,可以轻松地公开共享 Gradio demo。像这样:

gr.Interface(classify_image, "image", "label").launch(share=True)

这样会生成一个公开的、可共享的链接,您可以将其发送给任何人。当您发送此链接时,另一方的用户可以在他们的浏览器中试用该模型。因为处理过程发生在您的设备上(只要您的设备保持开启),您不必担心任何打包任何依赖项。分享链接通常看起来像这样:XXXXXX.gradio.app。虽然链接是通过 Gradio URL 提供的,但我们只是您本地服务器的代理,不会存储通过接口发送的任何数据。

但是请记住,这些链接是可公开访问的,这意味着任何人都可以使用您的模型进行预测!因此,请确保不要通过您编写的函数公开任何敏感信息,或允许在您的设备上发生任何关键更改。如果您设置 share=False​(默认值,colab notebook 除外),则仅创建一个本地链接,该链接可以通过 端口转发[5] 与特定用户共享。

共享链接在 72 小时后过期。

图片

责任编辑:张燕妮 来源: 开源前哨
相关推荐

2024-04-19 09:37:49

Ollama大语言模型开源

2013-07-02 09:58:38

ClojureClojure教程

2024-12-03 15:38:14

2020-09-11 09:18:07

PythonPython包开发

2020-04-30 21:46:46

机器学习病毒数据

2016-09-30 15:13:01

Python代码

2021-03-23 13:49:21

人工智能机器学习

2022-05-20 07:36:02

LiveTerm工具

2010-01-06 15:35:06

JSON对象

2009-12-29 09:01:46

ADSL断线

2022-03-28 08:00:00

数据库GraphQL公共云

2017-08-03 17:30:26

戴尔IoT设备

2009-11-25 17:22:12

路由器安装

2010-03-01 18:13:22

Python程序

2010-02-23 14:19:30

Python目录操作

2010-01-21 09:46:24

C++程序

2020-11-03 07:34:12

Kafka后端工程师

2010-01-06 13:39:51

扩展Jquery的Js

2018-12-17 09:10:52

机器学习TensorFlow容器

2010-03-04 10:01:01

Android基本组件
点赞
收藏

51CTO技术栈公众号