# 高级接口功能

现在我们可以构建和共享一个基本接口, 让我们来探索一些更高级的特性, 如状态和解释。

### 使用状态保存数据

Gradio 支持 会话状态, 其中数据在页面加载中的多个提交中持续存在。会话状态对于构建演示很有用, 例如, 你希望在用户与模型交互时保留数据的聊天机器人。请注意, 会话状态不会在模型的不同用户之间共享数据。

要将数据存储在会话状态中, 你需要做三件事:

1. 向函数中传递一个 额外的参数 , 该参数表示接口的状态。
2. 在函数结束时, 将状态的更新值作为 额外的返回值 返回。
3. 在创建`接口`时添加 ‘state’ 输入和 ‘state’ 输出组件。

请参阅下面的聊天机器人示例:

    import random

    import gradio as gr

    def chat(message, history):
        history = history or []
        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

    iface = gr.Interface(
        chat,
        ["text", "state"],
        ["chatbot", "state"],
        allow_screenshot=False,
        allow_flagging="never",
    )
    iface.launch()

请注意输出组件的状态如何在提交之间保持不变。注意: 可以给 state 参数传入一个默认值, 作为 state 的初始值。

### 通过解释来理解预测

大多数机器学习模型都是黑盒子, 函数的内部逻辑对终端用户是隐藏的。为了提高透明度, 我们通过简单地将 Interface 类中的解释关键字设置为默认值, 使向模型添加解释变得非常容易。这允许你的用户理解输入的哪些部分负责输出。看看下面这个简单的接口, 它显示了一个还包括解释的图像分类器:

    import requests
    import tensorflow as tf

    import gradio as gr

    inception_net = tf.keras.applications.MobileNetV2()  # 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, 224, 224, 3))
        inp = tf.keras.applications.mobilenet_v2.preprocess_input(inp)
        prediction = inception_net.predict(inp).flatten()
        return {labels[i]: float(prediction[i]) for i in range(1000)}

    image = gr.Image(shape=(224, 224))
    label = gr.Label(num_top_classes=3)

    title = "Gradio Image Classifiction + Interpretation Example"
    gr.Interface(
        fn=classify_image, inputs=image, outputs=label, interpretation="default", title=title
    ).launch()

通过提交一个输入, 然后单击输出组件下的Interpret来测试解释功能。

除了Gradio提供的默认解释方法之外, 你还可以为 `interpretation` 参数指定 `shap`, 并设置 `num_shap` 参数。这使用基于 Shapley 的解释, 你可以在 here 阅读更多信息。最后, 还可以将自己的解释函数传入 `interpretation` 参数。在Gradio的入门页面 here 中可以看到一个例子。

这结束了我们对Gradio的`Interface`类的深入研究。正如我们所看到的, 这个类使用几行Python代码创建机器学习演示变得简单。然而, 有时你会想通过改变布局或链接多个预测函数来定制你的demo。如果我们能以某种方式将 `接口` 分成可定制的 “块”, 那不是很好吗? 幸运的是, 有! 这是最后一部分的主题。