Gradio入門到進(jìn)階全網(wǎng)最詳細(xì)教程[一]:快速搭建AI算法可視化部署演示(側(cè)重項(xiàng)目搭建和案例分享)
常用的兩款A(yù)I可視化交互應(yīng)用比較:
-
Gradio
Gradio的優(yōu)勢(shì)在于易用性,代碼結(jié)構(gòu)相比Streamlit簡(jiǎn)單,只需簡(jiǎn)單定義輸入和輸出接口即可快速構(gòu)建簡(jiǎn)單的交互頁(yè)面,更輕松部署模型。適合場(chǎng)景相對(duì)簡(jiǎn)單,想要快速部署應(yīng)用的開發(fā)者。便于分享:gradio可以在啟動(dòng)應(yīng)用時(shí)設(shè)置share=True參數(shù)創(chuàng)建外部分享鏈接,可以直接在微信中分享給用戶使用。
方便調(diào)試:gradio可以在jupyter中直接展示頁(yè)面,更加方便調(diào)試。
-
Streamlit
Streamlit的優(yōu)勢(shì)在于可擴(kuò)展性,相比Gradio復(fù)雜,完全熟練使用需要一定時(shí)間。可以使用Python編寫完整的包含前后端的交互式應(yīng)用。適合場(chǎng)景相對(duì)復(fù)雜,想要構(gòu)建豐富多樣交互頁(yè)面的開發(fā)者。
Gradio官網(wǎng)鏈接:https://gradio.app/
1. 安裝&基本用法
Python第三方庫(kù)Gradio快速上手,當(dāng)前版本V3.27.0
- python版本要求3.7及以上
pip install gradio
#為了更快安裝,可以使用清華鏡像源
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple gradio
安裝完直接在IDE上啟動(dòng)快速,
1.1 快速入門
import gradio as gr
#輸入文本處理程序
def greet(name):
return "Hello " + name + "!"
#接口創(chuàng)建函數(shù)
#fn設(shè)置處理函數(shù),inputs設(shè)置輸入接口組件,outputs設(shè)置輸出接口組件
#fn,inputs,outputs都是必填函數(shù)
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
demo.launch()
運(yùn)行程序后,打開 http://localhost:7860 即可看到網(wǎng)頁(yè)效果。左邊是文本輸入框,右邊是結(jié)果展示框。Clear按鈕用于重置網(wǎng)頁(yè)狀態(tài),Submit按鈕用于執(zhí)行處理程序,F(xiàn)lag按鈕用于保存結(jié)果到本地。
#執(zhí)行結(jié)果
Running on local URL: http://127.0.0.1:7860
To create a public link, set `share=True` in `launch()`.
打開瀏覽器使用即可
在本地開發(fā)時(shí),如果你想將代碼作為Python腳本運(yùn)行,你可以使用Gradio CLI在重載模式下啟動(dòng)應(yīng)用程序,這將提供無(wú)縫和快速的開發(fā)。
gradio app.py
Note:你也可以做python app.py,但它不會(huì)提供自動(dòng)重新加載機(jī)制。
2.基本參數(shù)|支持的接口
2.1 Interface類以及基礎(chǔ)模塊
Gradio 可以包裝幾乎任何 Python 函數(shù)為易于使用的用戶界面。從上面例子我們看到,簡(jiǎn)單的基于文本的函數(shù)。但這個(gè)函數(shù)還可以處理很多類型。
Interface類通過以下三個(gè)參數(shù)進(jìn)行初始化:
- fn:包裝的函數(shù)
- inputs:輸入組件類型,(例如:“text”、"image)
- ouputs:輸出組件類型,(例如:“text”、"image)
通過這三個(gè)參數(shù),我們可以快速創(chuàng)建一個(gè)接口并發(fā)布他們。
-
最常用的基礎(chǔ)模塊構(gòu)成。
-
應(yīng)用界面:gr.Interface(簡(jiǎn)易場(chǎng)景), gr.Blocks(定制化場(chǎng)景)
-
輸入輸出:gr.Image(圖像), gr.Textbox(文本框), gr.DataFrame(數(shù)據(jù)框), gr.Dropdown(下拉選項(xiàng)), gr.Number(數(shù)字), gr.Markdown, gr.Files
-
控制組件:gr.Button(按鈕)
-
布局組件:gr.Tab(標(biāo)簽頁(yè)), gr.Row(行布局), gr.Column(列布局)
-
1.2.1 自定義輸入組件
import gradio as gr
def greet(name):
return "Hello " + name + "!"
demo = gr.Interface(
fn=greet,
# 自定義輸入框
# 具體設(shè)置方法查看官方文檔
inputs=gr.Textbox(lines=3, placeholder="Name Here...",label="my input"),
outputs="text",
)
demo.launch()
-
Interface.launch()方法返回三個(gè)值
- app,為 Gradio 演示提供支持的 FastAPI 應(yīng)用程序
- local_url,本地地址
- share_url,公共地址,當(dāng)share=True時(shí)生成
import gradio as gr
def greet(name):
return "Hello " + name + "!"
iface = gr.Interface(
fn=greet,
inputs=gr.inputs.Textbox(lines=2, placeholder="Name Here..."),
outputs="text",
)
if __name__ == "__main__":
app, local_url, share_url = iface.launch()
1.2.2 多個(gè)輸入和輸出
對(duì)于復(fù)雜程序,輸入列表中的每個(gè)組件按順序?qū)?yīng)于函數(shù)的一個(gè)參數(shù)。輸出列表中的每個(gè)組件按順序排列對(duì)應(yīng)于函數(shù)返回的一個(gè)值。
import gradio as gr
#該函數(shù)有3個(gè)輸入?yún)?shù)和2個(gè)輸出參數(shù)
def greet(name, is_morning, temperature):
salutation = "Good morning" if is_morning else "Good evening"
greeting = f"{salutation} {name}. It is {temperature} degrees today"
celsius = (temperature - 32) * 5 / 9
return greeting, round(celsius, 2)
demo = gr.Interface(
fn=greet,
#按照處理程序設(shè)置輸入組件
inputs=["text", "checkbox", gr.Slider(0, 100)],
#按照處理程序設(shè)置輸出組件
outputs=["text", "number"],
)
demo.launch()
inputs列表里的每個(gè)字段按順序?qū)?yīng)函數(shù)的每個(gè)參數(shù),outputs同理。
1.2.3 圖像組件
Gradio支持許多類型的組件,如image、dataframe、video。使用示例如下:
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
#shape設(shè)置輸入圖像大小
demo = gr.Interface(sepia, gr.Image(shape=(200, 200)), "image")
demo.launch()
當(dāng)使用Image組件作為輸入時(shí),函數(shù)將收到一個(gè)維度為(w,h,3)的numpy數(shù)組,按照RGB的通道順序排列。要注意的是,我們的輸入圖像組件帶有一個(gè)編輯按鈕,可以對(duì)圖像進(jìn)行裁剪和放大。以這種方式處理圖像可以幫助揭示機(jī)器學(xué)習(xí)模型中的偏差或隱藏的缺陷。此外對(duì)于輸入組件有個(gè)shape參數(shù),指的設(shè)置輸入圖像大小。但是處理方式是保持長(zhǎng)寬比的情況下,將圖像最短邊縮放為指定長(zhǎng)度,然后按照中心裁剪方式裁剪最長(zhǎng)邊到指定長(zhǎng)度。當(dāng)圖像不大的情況,一種更好的方式是不設(shè)置shape,這樣直接傳入原圖。輸入組件Image也可以設(shè)置輸入類型type,比如type=filepath設(shè)置傳入處理圖像的路徑。具體可以查看官方文檔,文檔寫的很清楚。
1.2.4 動(dòng)態(tài)界面接口:簡(jiǎn)單計(jì)算器模板實(shí)時(shí)變化
在Interface添加live=True參數(shù),只要輸入發(fā)生變化,結(jié)果馬上發(fā)生改變。
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
iface = gr.Interface(
calculator,
["number", gr.inputs.Radio(["add", "subtract", "multiply", "divide"]), "number"],
"number",
live=True,
)
iface.launch()
import gradio as gr
#一個(gè)簡(jiǎn)單計(jì)算器,含實(shí)例說明
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":
if num2 == 0:
# 設(shè)置報(bào)錯(cuò)彈窗
raise gr.Error("Cannot divide by zero!")
return num1 / num2
demo = gr.Interface(
calculator,
# 設(shè)置輸入
[
"number",
gr.Radio(["add", "subtract", "multiply", "divide"]),
"number"
],
# 設(shè)置輸出
"number",
# 設(shè)置輸入?yún)?shù)示例
examples=[
[5, "add", 3],
[4, "divide", 2],
[-4, "multiply", 2.5],
[0, "subtract", 1.2],
],
# 設(shè)置網(wǎng)頁(yè)標(biāo)題
title="Toy Calculator",
# 左上角的描述文字
description="Here's a sample toy calculator. Enjoy!",
# 左下角的文字
article = "Check out the examples",
)
demo.launch()
2.2 interface進(jìn)階使用
2.2.1 interface狀態(tài)
全局變量
全局變量的好處就是在調(diào)用函數(shù)后仍然能夠保存,例如在機(jī)器學(xué)習(xí)中通過全局變量從外部加載一個(gè)大型模型,并在函數(shù)內(nèi)部使用它,以便每次函數(shù)調(diào)用都不需要重新加載模型。下面就展示了全局變量使用的好處。
import gradio as gr
scores = []
def track_score(score):
scores.append(score)
#返回分?jǐn)?shù)top3
top_scores = sorted(scores, reverse=True)[:3]
return top_scores
demo = gr.Interface(
track_score,
gr.Number(label="Score"),
gr.JSON(label="Top Scores")
)
demo.launch()
會(huì)話狀態(tài)
Gradio支持的另一種數(shù)據(jù)持久性是會(huì)話狀態(tài),數(shù)據(jù)在一個(gè)頁(yè)面會(huì)話中的多次提交中持久存在。然而,數(shù)據(jù)不會(huì)在你模型的不同用戶之間共享。會(huì)話狀態(tài)的典型例子就是聊天機(jī)器人,你想訪問用戶之前提交的信息,但你不能將聊天記錄存儲(chǔ)在一個(gè)全局變量中,因?yàn)槟菢拥脑?,聊天記錄?huì)在不同的用戶之間亂成一團(tuán)。注意該狀態(tài)會(huì)在每個(gè)頁(yè)面內(nèi)的提交中持續(xù)存在,但如果您在另一個(gè)標(biāo)簽頁(yè)中加載該演示(或刷新頁(yè)面),該演示將不會(huì)共享聊天歷史。
要在會(huì)話狀態(tài)下存儲(chǔ)數(shù)據(jù),你需要做三件事。
- 在你的函數(shù)中傳入一個(gè)額外的參數(shù),它代表界面的狀態(tài)。
- 在函數(shù)的最后,將狀態(tài)的更新值作為一個(gè)額外的返回值返回。
- 在添加輸入和輸出時(shí)添加state組件。
import random
import gradio as gr
def chat(message, history):
history = history or []
message = message.lower()
if message.startswith("how many"):
response = random.randint(1, 10)
elif message.startswith("how"):
response = random.choice(["Great", "Good", "Okay", "Bad"])
elif message.startswith("where"):
response = random.choice(["Here", "There", "Somewhere"])
else:
response = "I don't know"
history.append((message, response))
return history, history
#設(shè)置一個(gè)對(duì)話窗
chatbot = gr.Chatbot().style(color_map=("green", "pink"))
demo = gr.Interface(
chat,
# 添加state組件
["text", "state"],
[chatbot, "state"],
# 設(shè)置沒有保存數(shù)據(jù)的按鈕
allow_flagging="never",
)
demo.launch()
2.2.2 interface交互
實(shí)時(shí)變化
在Interface中設(shè)置live=True,則輸出會(huì)跟隨輸入實(shí)時(shí)變化。這個(gè)時(shí)候界面不會(huì)有submit按鈕,因?yàn)椴恍枰謩?dòng)提交輸入。
同1.2.4
流模式
在許多情形下,我們的輸入是實(shí)時(shí)視頻流或者音頻流,那么意味這數(shù)據(jù)不停地發(fā)送到后端,這是可以采用streaming模式處理數(shù)據(jù)。
import gradio as gr
import numpy as np
def flip(im):
return np.flipud(im)
demo = gr.Interface(
flip,
gr.Image(source="webcam", streaming=True),
"image",
live=True
)
demo.launch()
2.3自定制組件:Blocks構(gòu)建應(yīng)用
相比Interface,Blocks提供了一個(gè)低級(jí)別的API,用于設(shè)計(jì)具有更靈活布局和數(shù)據(jù)流的網(wǎng)絡(luò)應(yīng)用。Blocks允許控制組件在頁(yè)面上出現(xiàn)的位置,處理復(fù)雜的數(shù)據(jù)流(例如,輸出可以作為其他函數(shù)的輸入),并根據(jù)用戶交互更新組件的屬性可見性??梢远ㄖ聘嘟M件,更多詳細(xì)定制可查看文檔
2.3.1 簡(jiǎn)單演示
import gradio as gr
def greet(name):
return "Hello " + name + "!"
with gr.Blocks() as demo:
#設(shè)置輸入組件
name = gr.Textbox(label="Name")
# 設(shè)置輸出組件
output = gr.Textbox(label="Output Box")
#設(shè)置按鈕
greet_btn = gr.Button("Greet")
#設(shè)置按鈕點(diǎn)擊事件
greet_btn.click(fn=greet, inputs=name, outputs=output)
demo.launch()
Blocks方式需要with語(yǔ)句添加組件,如果不設(shè)置布局方式,那么組件將按照創(chuàng)建的順序垂直出現(xiàn)在應(yīng)用程序中,運(yùn)行界面
2.3.2 多模塊應(yīng)用☆
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:
#用markdown語(yǔ)法編輯輸出一段話
gr.Markdown("Flip text or image files using this demo.")
# 設(shè)置tab選項(xiàng)卡
with gr.Tab("Flip Text"):
#Blocks特有組件,設(shè)置所有子組件按垂直排列
#垂直排列是默認(rèn)情況,不加也沒關(guān)系
with gr.Column():
text_input = gr.Textbox()
text_output = gr.Textbox()
text_button = gr.Button("Flip")
with gr.Tab("Flip Image"):
#Blocks特有組件,設(shè)置所有子組件按水平排列
with gr.Row():
image_input = gr.Image()
image_output = gr.Image()
image_button = gr.Button("Flip")
#設(shè)置折疊內(nèi)容
with gr.Accordion("Open for More!"):
gr.Markdown("Look at me...")
text_button.click(flip_text, inputs=text_input, outputs=text_output)
image_button.click(flip_image, inputs=image_input, outputs=image_output)
demo.launch()
2.3.3 Flagging標(biāo)記
相信有小伙伴已經(jīng)注意到,輸出框下有個(gè)Flag按鈕。當(dāng)測(cè)試您的模型的用戶看到某個(gè)輸入導(dǎo)致輸出錯(cuò)誤或意外的模型行為,他們可以標(biāo)記這個(gè)輸入讓開發(fā)者知道。這個(gè)文件夾由Interface的flagging_dir參數(shù)指定,默認(rèn)為’flagged’。將這些會(huì)導(dǎo)致錯(cuò)誤的輸入保存到一個(gè)csv文件。如果Interface包含文件數(shù)據(jù),文件夾也會(huì)創(chuàng)建來(lái)保存這些標(biāo)記數(shù)據(jù)。
打開log.csv展示如下:
2.3.4 樣式、隊(duì)列、生成器
- 樣式
在Gradio官方文檔,搜索不同的組件加.style(如image.style),可以獲取該組件的樣式參數(shù)設(shè)置樣例。例如image組件的設(shè)置如下:
img = gr.Image("lion.jpg").style(height='24', rounded=False)
- 隊(duì)列
如果函數(shù)推理時(shí)間較長(zhǎng),比如目標(biāo)檢測(cè);或者應(yīng)用程序處理流量過大,則需要使用queue方法進(jìn)行排隊(duì)。queue方法使用websockets,可以防止網(wǎng)絡(luò)超時(shí)。使用方式如下:
demo = gr.Interface(...).queue()
demo.launch()
#或
with gr.Blocks() as demo:
#...
demo.queue()
demo.launch()
- 生成器
在某些情況下,你可能想顯示一連串的輸出,而不是單一的輸出。例如,你可能有一個(gè)圖像生成模型,如果你想顯示在每個(gè)步驟中生成的圖像,從而得到最終的圖像。在這種情況下,你可以向Gradio提供一個(gè)生成器函數(shù),而不是一個(gè)常規(guī)函數(shù)。下面是一個(gè)生成器的例子,每隔1秒返回1張圖片。
import gradio as gr
import numpy as np
import time
#生成steps張圖片,每隔1秒鐘返回
def fake_diffusion(steps):
for _ in range(steps):
time.sleep(1)
image = np.random.randint(255, size=(300, 600, 3))
yield image
demo = gr.Interface(fake_diffusion,
#設(shè)置滑窗,最小值為1,最大值為10,初始值為3,每次改動(dòng)增減1位
inputs=gr.Slider(1, 10, value=3, step=1),
outputs="image")
#生成器必須要queue函數(shù)
demo.queue()
demo.launch()
2.4 Blocks進(jìn)階使用
2.4.1 Blocks事件
可交互設(shè)置
任何輸入的組件內(nèi)容都是可編輯的,而輸出組件默認(rèn)是不能編輯的。如果想要使得輸出組件內(nèi)容可編輯,設(shè)置interactive=True即可。
import gradio as gr
def greet(name):
return "Hello " + name + "!"
with gr.Blocks() as demo:
name = gr.Textbox(label="Name")
# 不可交互
# output = gr.Textbox(label="Output Box")
# 可交互
output = gr.Textbox(label="Output", interactive=True)
greet_btn = gr.Button("Greet")
greet_btn.click(fn=greet, inputs=name, outputs=output)
demo.launch()
事件設(shè)置
我們可以為不同的組件設(shè)置不同事件,如為輸入組件添加change事件。可以進(jìn)一步查看官方文檔,看看組件還有哪些事件。
import gradio as gr
def welcome(name):
return f"Welcome to Gradio, {name}!"
with gr.Blocks() as demo:
gr.Markdown(
"""
# Hello World!
Start typing below to see the output.
""")
inp = gr.Textbox(placeholder="What is your name?")
out = gr.Textbox()
#設(shè)置change事件
inp.change(fn = welcome, inputs = inp, outputs = out)
demo.launch()
多個(gè)數(shù)據(jù)流
如果想處理多個(gè)數(shù)據(jù)流,只要設(shè)置相應(yīng)的輸入輸出組件即可。
import gradio as gr
def increase(num):
return num + 1
with gr.Blocks() as demo:
a = gr.Number(label="a")
b = gr.Number(label="b")
# 要想b>a,則使得b = a+1
atob = gr.Button("b > a")
atob.click(increase, a, b)
# 要想a>b,則使得a = b+1
btoa = gr.Button("a > b")
btoa.click(increase, b, a)
demo.launch()
多輸出值處理
- 下面的例子展示了輸出多個(gè)值時(shí),以列表形式表現(xiàn)的處理方式。
import gradio as gr
with gr.Blocks() as demo:
food_box = gr.Number(value=10, label="Food Count")
status_box = gr.Textbox()
def eat(food):
if food > 0:
return food - 1, "full"
else:
return 0, "hungry"
gr.Button("EAT").click(
fn=eat,
inputs=food_box,
#根據(jù)返回值改變輸入組件和輸出組件
outputs=[food_box, status_box]
)
demo.launch()
- 下面的例子展示了輸出多個(gè)值時(shí),以字典形式表現(xiàn)的處理方式。
組件配置修改
事件監(jiān)聽器函數(shù)的返回值通常是相應(yīng)的輸出組件的更新值。有時(shí)我們也想更新組件的配置,比如說可見性。在這種情況下,我們可以通過返回update函數(shù)更新組件的配置。
import gradio as gr
def change_textbox(choice):
#根據(jù)不同輸入對(duì)輸出控件進(jìn)行更新
if choice == "short":
return gr.update(lines=2, visible=True, value="Short story: ")
elif choice == "long":
return gr.update(lines=8, visible=True, value="Long story...")
else:
return gr.update(visible=False)
with gr.Blocks() as demo:
radio = gr.Radio(
["short", "long", "none"], label="Essay Length to Write?"
)
text = gr.Textbox(lines=2, interactive=True)
radio.change(fn=change_textbox, inputs=radio, outputs=text)
demo.launch()
2.4.2 Blocks布局
Blocks應(yīng)用的是html中的flexbox模型布局,默認(rèn)情況下組件垂直排列。
組件水平排列
使用Row函數(shù)會(huì)將組件按照水平排列,但是在Row函數(shù)塊里面的組件都會(huì)保持同等高度。
import gradio as gr
with gr.Blocks() as demo:
with gr.Row():
img1 = gr.Image()
text1 = gr.Text()
btn1 = gr.Button("button")
demo.launch()
組件垂直排列與嵌套
組件通常是垂直排列,我們可以通過Row函數(shù)和Column函數(shù)生成不同復(fù)雜的布局。
import gradio as gr
with gr.Blocks() as demo:
with gr.Row():
text1 = gr.Textbox(label="t1")
slider2 = gr.Textbox(label="s2")
drop3 = gr.Dropdown(["a", "b", "c"], label="d3")
with gr.Row():
# scale與相鄰列相比的相對(duì)寬度。例如,如果列A的比例為2,列B的比例為1,則A的寬度將是B的兩倍。
# min_width設(shè)置最小寬度,防止列太窄
with gr.Column(scale=2, min_width=600):
text1 = gr.Textbox(label="prompt 1")
text2 = gr.Textbox(label="prompt 2")
inbtw = gr.Button("Between")
text4 = gr.Textbox(label="prompt 1")
text5 = gr.Textbox(label="prompt 2")
with gr.Column(scale=1, min_width=600):
img1 = gr.Image("test.jpg")
btn = gr.Button("Go")
demo.launch()
組件可視化:輸出可視化從無(wú)到有
如下所示,我們可以通過visible和update函數(shù)構(gòu)建更為復(fù)雜的應(yīng)用。
import gradio as gr
with gr.Blocks() as demo:
# 出錯(cuò)提示框
error_box = gr.Textbox(label="Error", visible=False)
# 輸入框
name_box = gr.Textbox(label="Name")
age_box = gr.Number(label="Age")
symptoms_box = gr.CheckboxGroup(["Cough", "Fever", "Runny Nose"])
submit_btn = gr.Button("Submit")
# 輸出不可見
with gr.Column(visible=False) as output_col:
diagnosis_box = gr.Textbox(label="Diagnosis")
patient_summary_box = gr.Textbox(label="Patient Summary")
def submit(name, age, symptoms):
if len(name) == 0:
return {error_box: gr.update(value="Enter name", visible=True)}
if age < 0 or age > 200:
return {error_box: gr.update(value="Enter valid age", visible=True)}
return {
output_col: gr.update(visible=True),
diagnosis_box: "covid" if "Cough" in symptoms else "flu",
patient_summary_box: f"{name}, {age} y/o"
}
submit_btn.click(
submit,
[name_box, age_box, symptoms_box],
[error_box, diagnosis_box, patient_summary_box, output_col],
)
demo.launch()
組件渲染:點(diǎn)擊作為輸入
在某些情況下,您可能希望在實(shí)際在UI中呈現(xiàn)組件之前定義組件。例如,您可能希望在相應(yīng)的gr.Textbox輸入上方顯示使用gr.examples的示例部分。由于gr.Examples需要輸入組件對(duì)象作為參數(shù),因此您需要先定義輸入組件,然后在定義gr.Exmples對(duì)象后再進(jìn)行渲染。解決方法是在gr.Blocks()范圍外定義gr.Textbox,并在UI中希望放置的任何位置使用組件的.render()方法。
import gradio as gr
input_textbox = gr.Textbox()
with gr.Blocks() as demo:
#提供示例輸入給input_textbox,示例輸入以嵌套列表形式設(shè)置
gr.Examples(["hello", "bonjour", "merhaba"], input_textbox)
# render函數(shù)渲染input_textbox
input_textbox.render()
demo.launch()
2.4.3 樣式修改
自定義css
要獲得額外的樣式功能,您可以設(shè)置行內(nèi)css屬性將任何樣式給應(yīng)用程序。如下所示。
import gradio as gr
#修改blocks的背景顏色
with gr.Blocks(css=".gradio-container {background-color: red}") as demo:
box1 = gr.Textbox(value="Good Job")
box2 = gr.Textbox(value="Failure")
demo.launch()
元素選擇
您可以向任何組件添加HTML元素。通過elem_id選擇對(duì)應(yīng)的css元素。
import gradio as gr
# 這里用的是id屬性設(shè)置
with gr.Blocks(css="#warning {background-color: red}") as demo:
box1 = gr.Textbox(value="Good Job", elem_id="warning")
box2 = gr.Textbox(value="Failure")
box3 = gr.Textbox(value="None", elem_id="warning")
demo.launch()
3. 應(yīng)用分享
3.1 互聯(lián)網(wǎng)分享
如果運(yùn)行環(huán)境能夠連接互聯(lián)網(wǎng),在launch函數(shù)中設(shè)置share參數(shù)為True,那么運(yùn)行程序后。Gradio的服務(wù)器會(huì)提供XXXXX.gradio.app地址。通過其他設(shè)備,比如手機(jī)或者筆記本電腦,都可以訪問該應(yīng)用。這種方式下該鏈接只是本地服務(wù)器的代理,不會(huì)存儲(chǔ)通過本地應(yīng)用程序發(fā)送的任何數(shù)據(jù)。這個(gè)鏈接在有效期內(nèi)是免費(fèi)的,好處就是不需要自己搭建服務(wù)器,壞處就是太慢了,畢竟數(shù)據(jù)經(jīng)過別人的服務(wù)器。
demo.launch(share=True)
3.2 huggingface托管
為了便于向合作伙伴永久展示我們的模型App,可以將gradio的模型部署到 HuggingFace的 Space托管空間中,完全免費(fèi)的哦。
方法如下:
1,注冊(cè)huggingface賬號(hào):https://huggingface.co/join
2,在space空間中創(chuàng)建項(xiàng)目:https://huggingface.co/spaces
3,創(chuàng)建好的項(xiàng)目有一個(gè)Readme文檔,可以根據(jù)說明操作,也可以手工編輯app.py和requirements.txt文件。
3.3 局域網(wǎng)分享
通過設(shè)置server_name=‘0.0.0.0’(表示使用本機(jī)ip),server_port(可不改,默認(rèn)值是7860)。那么可以通過本機(jī)ip:端口號(hào)在局域網(wǎng)內(nèi)分享應(yīng)用。
#show_error為True表示在控制臺(tái)顯示錯(cuò)誤信息。
demo.launch(server_name='0.0.0.0', server_port=8080, show_error=True)
這里host地址可以自行在電腦查詢,C:\Windows\System32\drivers\etc\hosts 修改一下即可 127.0.0.1再制定端口號(hào)
3.4 密碼驗(yàn)證
在首次打開網(wǎng)頁(yè)前,可以設(shè)置賬戶密碼。比如auth參數(shù)為(賬戶,密碼)的元組數(shù)據(jù)。這種模式下不能夠使用queue函數(shù)。
demo.launch(auth=("admin", "pass1234"))
如果想設(shè)置更為復(fù)雜的賬戶密碼和密碼提示,可以通過函數(shù)設(shè)置校驗(yàn)規(guī)則。
#賬戶和密碼相同就可以通過
def same_auth(username, password):
return username == password
demo.launch(auth=same_auth,auth_message="username and password must be the same")
4.案例升級(jí)展示
4.1 文本分類
#!pip install gradio, ultralytics, transformers, torchkeras
import gradio as gr
from transformers import pipeline
pipe = pipeline("text-classification")
def clf(text):
result = pipe(text)
label = result[0]['label']
score = result[0]['score']
res = {label:score,'POSITIVE' if label=='NEGATIVE' else 'NEGATIVE': 1-score}
return res
demo = gr.Interface(fn=clf, inputs="text", outputs="label")
gr.close_all()
demo.launch(share=True)
4.2 圖像分類
import gradio as gr
import pandas as pd
from ultralytics import YOLO
from skimage import data
from PIL import Image
model = YOLO('yolov8n-cls.pt')
def predict(img):
result = model.predict(source=img)
df = pd.Series(result[0].names).to_frame()
df.columns = ['names']
df['probs'] = result[0].probs
df = df.sort_values('probs',ascending=False)
res = dict(zip(df['names'],df['probs']))
return res
gr.close_all()
demo = gr.Interface(fn = predict,inputs = gr.Image(type='pil'), outputs = gr.Label(num_top_classes=5),
examples = ['cat.jpeg','people.jpeg','coffee.jpeg'])
demo.launch()
4.3 目標(biāo)檢測(cè)
import gradio as gr
import pandas as pd
from skimage import data
from ultralytics.yolo.data import utils
model = YOLO('yolov8n.pt')
#load class_names
yaml_path = str(Path(ultralytics.__file__).parent/'datasets/coco128.yaml')
class_names = utils.yaml_load(yaml_path)['names']
def detect(img):
if isinstance(img,str):
img = get_url_img(img) if img.startswith('http') else Image.open(img).convert('RGB')
result = model.predict(source=img)
if len(result[0].boxes.boxes)>0:
vis = plots.plot_detection(img,boxes=result[0].boxes.boxes,
class_names=class_names, min_score=0.2)
else:
vis = img
return vis
with gr.Blocks() as demo:
gr.Markdown("# yolov8目標(biāo)檢測(cè)演示")
with gr.Tab("捕捉攝像頭喔"):
in_img = gr.Image(source='webcam',type='pil')
button = gr.Button("執(zhí)行檢測(cè)",variant="primary")
gr.Markdown("## 預(yù)測(cè)輸出")
out_img = gr.Image(type='pil')
button.click(detect,
inputs=in_img,
outputs=out_img)
gr.close_all()
demo.queue(concurrency_count=5)
demo.launch()
4.4 圖片篩選器
盡管gradio的設(shè)計(jì)初衷是為了快速創(chuàng)建機(jī)器學(xué)習(xí)用戶交互頁(yè)面。但實(shí)際上,通過組合gradio的各種組件,用戶可以很方便地實(shí)現(xiàn)非常實(shí)用的各種應(yīng)用小工具。
例如: 數(shù)據(jù)分析展示dashboard, 數(shù)據(jù)標(biāo)注工具, 制作一個(gè)小游戲界面等等。
本范例我們將應(yīng)用 gradio來(lái)構(gòu)建一個(gè)圖片篩選器,從百度爬取的一堆貓咪表情包中刷選一些我們喜歡的出來(lái)。
#!pip install -U torchkeras
import torchkeras
from torchkeras.data import download_baidu_pictures
download_baidu_pictures('貓咪表情包',100)
import gradio as gr
from PIL import Image
import time,os
from pathlib import Path
base_dir = '貓咪表情包'
selected_dir = 'selected'
files = [str(x) for x in
Path(base_dir).rglob('*.jp*g')
if 'checkpoint' not in str(x)]
def show_img(path):
return Image.open(path)
def fn_before(done,todo):
...
return done,todo,path,img
def fn_next(done,todo):
...
return done,todo,path,img
def save_selected(img_path):
...
return msg
def get_default_msg():
...
return msg
with gr.Blocks() as demo:
with gr.Row():
total = gr.Number(len(files),label='總數(shù)量')
with gr.Row(scale = 1):
bn_before = gr.Button("上一張")
bn_next = gr.Button("下一張")
with gr.Row(scale = 2):
done = gr.Number(0,label='已完成')
todo = gr.Number(len(files),label='待完成')
path = gr.Text(files[0],lines=1, label='當(dāng)前圖片路徑')
feedback_button = gr.Button("選擇圖片",variant="primary")
msg = gr.TextArea(value=get_default_msg,lines=3,max_lines = 5)
img = gr.Image(value = show_img(files[0]),type='pil')
bn_before.click(fn_before,
inputs= [done,todo],
outputs=[done,todo,path,img])
bn_next.click(fn_next,
inputs= [done,todo],
outputs=[done,todo,path,img])
feedback_button.click(save_selected,
inputs = path,
outputs = msg
)
demo.launch()
參考鏈接:
Gradio官方倉(cāng)庫(kù)
基于Gradio可視化部署機(jī)器學(xué)習(xí)應(yīng)用文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-424633.html
gradio官方文檔文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-424633.html
到了這里,關(guān)于Gradio入門到進(jìn)階全網(wǎng)最詳細(xì)教程[一]:快速搭建AI算法可視化部署演示(側(cè)重項(xiàng)目搭建和案例分享)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!