#
Расширенные возможности Interface

Теперь, когда мы можем создать базовый интерфейс и поделиться им, давайте изучим некоторые более продвинутые возможности, такие как состояние и интерпретации.

###
Использование состояния для сохранения данных

Gradio поддерживает состояние сеанса, когда данные сохраняются при нескольких отправках в рамках загруженной страницы. Состояние сессии полезно для создания демо, например, чат-ботов, где необходимо сохранять данные по мере того, как пользователь взаимодействует с моделью. Обратите внимание, что состояние сессии не позволяет обмениваться данными между разными пользователями вашей модели.

Чтобы хранить данные о состоянии сеанса, необходимо выполнить три действия:

1. Передайте в вашу функцию дополнительный параметр, который представляет собой состояние интерфейса.
2. В завершении работы функции верните обновленное значение состояния в качестве дополнительного возвращаемого значения.
3. Добавьте входной компонент ‘state’ и выходной компонент ‘state’ при создании вашего `Interface`.

Посмотрите пример чатбота ниже:

    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 можно передать значение по умолчанию, которое используется в качестве начального значения состояния.

###
Использование интерпретации для понимания прогнозов

Большинство моделей машинного обучения представляют собой “черные ящики”, и внутренняя логика функции скрыта от конечного пользователя. Чтобы стимулировать прозрачность, мы упростили добавление интерпретации в вашу модель, просто задав ключевое слово interpretation в классе Interface по умолчанию. Это позволит вашим пользователям понять, какие части входных данных отвечают за вывод. Взгляните на простой интерфейс ниже, который показывает классификатор изображений, также включающий интерпретацию:

    import requests
    import tensorflow as tf

    import gradio as gr

    inception_net = tf.keras.applications.MobileNetV2()  # загрузим модель

    # Загрузим человекочитаемые метки для 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 по умолчанию, вы также можете задать `shap` для параметра `interpretation` и установить параметр `num_shap`. При этом используется интерпретация на основе Шэпли, о которой вы можете подробнее прочитать здесь. Наконец, в параметр `interpretation` можно передать собственную функцию интерпретации. Пример можно посмотреть на странице Gradio, посвященной началу работы здесь.

На этом мы завершаем наше глубокое погружение в класс `Interface` в Gradio. Как мы уже видели, этот класс позволяет создавать демо машинного обучения в несколько строк кода на Python. Однако иногда возникает необходимость доработать демо, изменив его макет или соединив несколько функций предсказания в цепочку. Было бы здорово, если бы мы могли как-то разделить `Interface` на настраиваемые “блоки”? К счастью, такая возможность есть! Этой теме посвящен последний раздел.