『开发』网页端展示深度学习模型|Gradio上手教程

2022-03-07 14:00:08 浏览数 (1)

安装

Gradio需要Python 3。一旦你有Python,你可以下载gradio使用pip 的最新版本,如下所示:

代码语言:javascript复制
pip install gradio

或者,pip3 install gradio如果您有多个Python安装,则可能需要执行此操作。

基本用法

使用gradio创建界面只需在现有代码中添加几行。例如,以下是gradio使用预训练keras模型创建界面的方法:

代码语言:javascript复制
import gradio, tensorflow as tf
image_mdl = tf.keras.applications.inception_v3.InceptionV3()
io = gradio.Interface(inputs="imageupload", outputs="label", model_type="keras", model=image_mdl)
io.launch()

运行上面的代码将打开一个带有图像上传的新浏览器窗口。用户可以拖放自己的图像,这会产生如下输出:

基本参数

运行GradIO接口需要创建一个对象,该对象作为输入参数:- 表示要使用的输入接口的字符串,或者用于其他自定义的子类(参见下文)。- 表示要使用的输出接口的字符串,或者用于其他自定义的子类(参见下文)。 - 表示传入模型类型的字符串。支持的类型包括keras。 - 用于处理的实际模型。Interface(inputs : str, outputs : str, model_type : str, model : Any) inputsgradio.AbstractInput outputsgradio.AbstractOutput model_type model

可以提供表示输入和输出接口的对象,而不是为inputs和提供字符串名称outputs。例如,Basic Usage部分中的代码执行方式如下:

代码语言:javascript复制
import gradio, tensorflow as tf
image_mdl = tf.keras.applications.inception_v3.InceptionV3()
inp = gradio.inputs.ImageUpload()
out = gradio.outputs.Label()
io = gradio.Interface(inputs=inp, outputs=out, model_type="keras", model=mdl)
io.launch()

这允许通过将参数传递给输入和输出构造函数来定制接口。每个接口构造函数接受的参数如下所述。

支持的接口

这是GradIO中当前支持的接口列表。所有输入接口都可以与任何输出接口配对。

输入接口

inputs=“text”

使用此界面输入文本作为输入。参数:

输入

inputs=“imageupload”

使用此界面将图像上载到模型。参数: shape- 一个元组,其形状应在传入模型之前将上传的图像调整大小。默认值:(224, 224, 3) image_mode- PIL图像模式,用于将图像转换为numpy数组。通常为“RGB”(3通道RGB)或“L”(1通道灰度)。默认值:'RGB' scale- 用于重新缩放图像中每个像素值的浮点数。默认值:1/127.5 shift- 用于在缩放后移动图像中的每个像素值的浮点数。默认值:-1 cropper_aspect_ratio- 无或者浮点数是裁剪器的纵横比。默认:None

输入

在此处删除图像 - 或 - 单击上载

inputs=“snapshot”

使用此界面从用户的网络摄像头拍摄快照。参数: shape- 一个元组,其形状应在传入模型之前将上传的图像调整大小。默认值:(224, 224, 3) image_mode- PIL图像模式,用于将图像转换为numpy数组。通常为“RGB”(3通道RGB)或“L”(1通道灰度)。默认值:'RGB' scale- 用于重新缩放图像中每个像素值的浮点数。默认值:1/127.5 shift- 用于在缩放后移动图像中的每个像素值的浮点数。默认值:-1 cropper_aspect_ratio- 无或者浮点数是裁剪器的纵横比。默认:None

输入

单击以从网络摄像头上载快照。

inputs=“sketchpad”

使用此界面将简单的单色cketches作为输入。参数: shape- 一个元组,其形状应在传入模型之前将上传的图像调整大小。默认值:(224, 224, 3) invert_colors- 一个布尔值,指定在传入模型之前是否应该反转颜色。默认:True

输入

inputs=“microphone”

将此接口用于麦克风的音频输入。

输入

单击以从麦克风上载音频。

inputs=“audio_file”

使用此界面将音频上传到模型。

输入

在此处删除音频文件 - 或 - 单击上传

输出接口

outputs=“classifier”

使用此界面进行分类。以置信区间回应。

产量

快乐

快乐

73%

吃惊

20%

伤心

愤怒

outputs=“text”

使用此界面显示输出文本。

产量

outputs=“image”

使用此界面显示输出文本。

产量

自定义界面

实际上,定制输入和输出接口是相当典型的,因此它们以模型接受的方式预处理输入,或者以适当的方式对模型的结果进行后处理,以便输出接口可以显示结果。例如,您可能需要调整图像上载界面的预处理,以便在将图像输入模型之前将图像调整为正确的尺寸。这可以通过以下两种方式之一完成:(1)使用自定义参数实例化gradio.Input/ gradio.Output对象,或(2)提供自定义预处理/后处理功能。

具有自定义参数的输入/输出对象

对于输入和输出接口的小的常见更改,您通常可以简单地更改输入和输出对象的构造函数中的参数,以影响预处理/后处理。下面是一个示例,在将图像输入模型之前将图像调整为不同大小,并调整输出界面以隐藏置信区并显示前5个类而不是默认3:

代码语言:javascript复制
import gradio, tensorflow as tf
image_mdl = tf.keras.applications.inception_v3.InceptionV3()
inp = gradio.inputs.ImageUpload(shape=(299, 299, 3))
out = gradio.outputs.Label(num_top_classes=5)
io = gradio.Interface(inputs=inp, outputs=out, model_type="keras", model=mdl)
io.launch()

自定义预处理/后处理功能

或者,您可以通过提供自己的功能完全覆盖默认的预处理/后处理功能。例如,这里我们修改ImageUpload接口的预处理功能,在将图像输入模型之前为图像添加一些噪声。

代码语言:javascript复制
import gradio, base64, numpy as np, tensorflow as tf
from io import BytesIO
from PIL import Image
image_mdl = tf.keras.applications.inception_v3.InceptionV3()

def pre(inp):
    im = gradio.preprocessing_utils.encoding_to_image(inp)
    im = gradio.preprocessing_utils.resize_and_crop(im, (299, 299))
    im = np.array(im).flatten()
    im = im * 1/127.5 - 1
    im = im   np.random.normal(0, 0.1, im.shape)  # Adding the noise
    array = im.reshape(1, 299, 299, 3)
    return array

inp = gradio.inputs.ImageUpload(preprocessing_fn=pre)
io = gradio.Interface(inputs=inp, outputs="label", model_type="keras", model=mdl)
io.launch()

型号类型

我们目前支持以下几种型号:

model_type="sklearn"

这允许您传入scikit-learn模型,并从模型中获取预测。这是一个训练sklearn模型并gradio围绕它创建界面的完整示例。

代码语言:javascript复制
from sklearn import datasets, svm
import gradio

digits = datasets.load_digits()
n_samples = len(digits.images)
data = digits.images.reshape((n_samples, -1))  # flatten the images

# Create a classifier: a support vector classifier
classifier = svm.SVC(gamma=0.001)
classifier.fit(data, digits.target)

# The sklearn digits dataset is different from MNIST: it is 8x8 and consists of black digits on a white background.
inp = gradio.inputs.Sketchpad(shape=(8, 8), flatten=True, scale=16/255, invert_colors=False)
io = gradio.Interface(inputs=inp, outputs="label", model_type="sklearn", model=classifier)
io.launch()

model_type="keras"

这允许您传入keras模型,并从模型中获取预测。这是一个训练keras模型并gradio围绕它创建界面的完整示例。

代码语言:javascript复制
import gradio, tensorflow as tf

(x_train, y_train),(x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5)
loss, accuracy = model.evaluate(x_test, y_test)

io = gradio.Interface(inputs="sketchpad", outputs="label", model=model, model_type='keras')
io.launch(inline=True, share=True)

在colab笔记本中运行此代码,以查看嵌入在笔记本中的界面。

model_type="pytorch"

这允许您传入pytorch模型,并从模型中获取预测。这是一个训练pytorch模型并gradio围绕它创建界面的完整示例。

代码语言:javascript复制
import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
import gradio

# Device configuration
device = torch.device('cpu')

# Hyper-parameters
input_size = 784
hidden_size = 500
num_classes = 10
num_epochs = 2
batch_size = 100
learning_rate = 0.001

# MNIST dataset
train_dataset = torchvision.datasets.MNIST(root='../../data', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = torchvision.datasets.MNIST(root='../../data',train=False, transform=transforms.ToTensor())
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size,shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)

# Fully connected neural network with one hidden layer
class NeuralNet(nn.Module):
    def __init__(self, input_size, hidden_size, num_classes):
        super(NeuralNet, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, num_classes)

    def forward(self, x):
        out = self.fc1(x)
        out = self.relu(out)
        out = self.fc2(out)
        return out

model = NeuralNet(input_size, hidden_size, num_classes).to(device)

# Loss and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

# Train the model
total_step = len(train_loader)
for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        # Move tensors to the configured device
        images = images.reshape(-1, 28*28).to(device)
        labels = labels.to(device)

        # Forward pass
        outputs = model(images)
        loss = criterion(outputs, labels)

        # Backward and optimize
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

inp = gradio.inputs.Sketchpad(flatten=True, scale=1/255, dtype='float32')
io = gradio.Interface(inputs=inp, outputs="label", model_type="pytorch", model=model)
io.launch()

model_type="pyfunc"

这允许您传入任意python函数,并从函数中获取输出。这是一个带有gradio界面的“模型”的一个非常简单的例子。

代码语言:javascript复制
import gradio

# A very simplistic function that capitalizes each letter in the given string
def big(x):
    return x.upper()

io = gradio.Interface(inputs="textbox", outputs="textbox", model=big, model_type='pyfunc')
io.launch(inline=True, share=True)

pyfunc用例的更现实的例子可能如下,我们希望使用带有训练模型的TensorFlow会话来进行预测。所以我们将会话包装在python函数中,如下所示:

代码语言:javascript复制
import tensorflow as tf
import gradio

n_classes = 10
(x_train, y_train),(x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train.reshape(-1, 784) / 255.0, x_test.reshape(-1, 784) / 255.0
y_train = tf.keras.utils.to_categorical(y_train, n_classes).astype(float)
y_test = tf.keras.utils.to_categorical(y_test, n_classes).astype(float)

learning_rate = 0.5
epochs = 5
batch_size = 100

x = tf.placeholder(tf.float32, [None, 784], name="x")
y = tf.placeholder(tf.float32, [None, 10], name="y")

W1 = tf.Variable(tf.random_normal([784, 300], stddev=0.03), name='W1')
b1 = tf.Variable(tf.random_normal([300]), name='b1')
W2 = tf.Variable(tf.random_normal([300, 10], stddev=0.03), name='W2')
hidden_out = tf.add(tf.matmul(x, W1), b1)
hidden_out = tf.nn.relu(hidden_out)
y_ = tf.matmul(hidden_out, W2)

probs = tf.nn.softmax(y_)
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=y_, labels=y))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cross_entropy)
init_op = tf.global_variables_initializer()
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

sess = tf.Session()
sess.run(init_op)
total_batch = int(len(y_train) / batch_size)
for epoch in range(epochs):
    avg_cost = 0
    for start, end in zip(range(0, len(y_train), batch_size), range(batch_size, len(y_train) 1, batch_size)):
        batch_x = x_train[start: end]
        batch_y = y_train[start: end]
        _, c = sess.run([optimizer, cross_entropy], feed_dict={x: batch_x, y: batch_y})
        avg_cost  = c / total_batch

def predict(inp):
    return sess.run(probs, feed_dict={x:inp})

inp = gradio.inputs.Sketchpad(flatten=True)
io = gradio.Interface(inputs=inp, outputs="label", model_type="pyfunc", model=predict)
io.launch(inline=True, share=True)

显着性图

imageupload界面还支持显着性模型,其中热图叠加在输入图像的顶部。这可以用于显示特征属性,例如作为解释方法。用户提供自己的显着性函数,该函数应该包含三个参数:模型对象,输入要素和输入标签。以下是显着性函数的示例及其可能产生的内容:

代码语言:javascript复制
import numpy as np
import tensorflow as tf
from deepexplain.tensorflow import DeepExplain
from tensorflow.keras import backend as K
from tensorflow.keras.models import Sequential, Model
import gradio

model = tf.keras.applications.MobileNet()

def saliency(model, x, y):
    y = y.reshape(1, 1, 1, 1000)
    with DeepExplain(session=K.get_session()) as de:
        input_tensor = model.layers[0].input
        fModel = Model(inputs=input_tensor, outputs = model.layers[-3].output)
        target_tensor = fModel(input_tensor)

        attributions_gradin = de.explain('grad*input', target_tensor, input_tensor, x, ys=y)
        sal = np.sum(np.abs(attributions_gradin.squeeze()), axis=-1)
        sal = (sal - sal.min()) / (sal.max() - sal.min())
        return sal

inp = gradio.inputs.ImageUpload()
out = gradio.outputs.Label(label_names='imagenet1000', max_label_words=1, word_delimiter=",")

io = gradio.Interface(inputs=inp,
                      outputs=out,
                      model=model,
                      model_type='keras',
                      saliency=saliency)

io.launch();

产生这个:

启动选项

启动界面时,您可以选择传递几个布尔参数来确定界面的显示方式。以下示例显示了所有可能的参数:

代码语言:javascript复制
io.launch(inbrowser=True, inline=False, validate=False, share=True)

inbrowser - 模型是否应在新的浏览器窗口中启动。 inline - 模型是否应该嵌入在交互式python环境中(如jupyter notebooks或colab notebooks)。 validate - gradio是否应该在启动之前尝试验证接口模型兼容性。 share - 是否应创建共享模型的公共链接。用于处理。

0 人点赞