在 Panel 中构建交互式 ML 仪表板

Demo of Panel image classification app

HoloViz Panel 是一个通用的 Python 库,它使开发人员和数据科学家能够轻松构建交互式可视化。 无论您是在进行机器学习项目、开发 Web 应用程序还是设计数据仪表板,Panel 都提供了一套强大的工具和功能来增强您的数据探索和演示能力。 在这篇博文中,我们将深入研究 HoloViz Panel 的令人兴奋的功能,探索它如何彻底改变您的数据可视化工作流程,并演示如何使用大约 100 行代码制作像这样的应用程序。

试用该应用程序并查看代码

利用 ML/AI 的强大功能

ML/AI 已成为数据分析和决策过程不可或缺的一部分。 借助 Panel,您可以将 ML 模型和结果无缝集成到可视化中。 在这篇博文中,我们将探讨如何使用 OpenAI CLIP 模型进行图像分类任务。

CLIP 在大量的图像-文本对数据集上进行了预训练,使其能够理解图像和相应的文本描述,并适用于各种下游任务,例如图像分类。

我们使用了两个与 ML 相关的函数来执行图像分类任务。 第一个函数 load_processor_model 使我们能够从 Hugging Face 加载预训练的 CLIP 模型。 第二个函数 get_similarity_score 计算图像与提供的类标签列表之间的相似度。

@pn.cache
def load_processor_model(
    processor_name: str, model_name: str
) -> Tuple[CLIPProcessor, CLIPModel]:
    processor = CLIPProcessor.from_pretrained(processor_name)
    model = CLIPModel.from_pretrained(model_name)
    return processor, model

def get_similarity_scores(class_items: List[str], image: Image) -> List[float]:
    processor, model = load_processor_model(
        "openai/clip-vit-base-patch32", "openai/clip-vit-base-patch32"
    )
    inputs = processor(
        text=class_items,
        images=[image],
        return_tensors="pt",  # pytorch tensors
    )
    outputs = model(**inputs)
    logits_per_image = outputs.logits_per_image
    class_likelihoods = logits_per_image.softmax(dim=1).detach().numpy()
    return class_likelihoods[0]

绑定小部件以实现交互性

Panel 的主要优势之一是它能够将小部件绑定到函数。 此功能为用户提供了一个直观的界面,用于操作底层数据并通过交互获得更深入的见解。

Python 函数

在我们的示例中,我们有一个 process_input 函数,该函数将我们从图像分类模型获得的相似度分数格式化为具有良好 UI 的 Panel 对象。 实际函数使用了 async;如果您不熟悉 async,请不要担心! 我们将在后面的章节中进行解释,但请注意 async 不是 使用 Panel 的要求——Panel 只是支持它!

async def process_inputs(class_names: List[str], image_url: str):
    """
    High level function that takes in the user inputs and returns the
    classification results as panel objects.
    """
    ...
    yield results

Panel 小部件

我们使用两个小部件与此函数进行交互。

  1. image_url 是一个 TextInput 小部件,允许输入任何字符串作为图像 URL。
  2. class_names 是另一个 TextInput 小部件,它接受模型可以分类的可能的类名。
image_url = pn.widgets.TextInput(
    name="Image URL to classify",
    value=pn.bind(random_url, randomize_url),
)
class_names = pn.widgets.TextInput(
    name="Comma separated class names",
    placeholder="Enter possible class names, e.g. cat, dog",
    value="cat, dog, parrot",
)

将小部件绑定到函数

根据 process_inputs 函数签名,它接受两个参数: class_names 和 image_url。 我们可以使用 pn.bind 将每个 arg/kwarg 绑定到一个小部件,如下所示

interactive_result = pn.panel(
    pn.bind(process_inputs, image_url=image_url, class_names=class_names),
    height=600,
)
  • 第一个位置参数是函数名称。
  • 之后的关键字参数与函数的签名匹配,因此小部件的值绑定到函数的关键字参数。

为了澄清,如果小部件被命名为 image_url_input 而不是 image_url,那么调用将是

pn.bind(process_inputs, image_url=image_url_input, ...)

添加模板设计样式

应用程序和仪表板的美观性在吸引受众方面起着至关重要的作用。 Panel 使您能够根据 Material 或 Fast 等流行的设计为可视化添加样式,从而使您能够创建具有视觉吸引力和专业外观的界面。

在此示例中,我们使用了 bootstrap 模板,我们可以在其中控制我们想要在多个区域(例如 title 和 main)中显示的内容,并且我们可以为各种组件指定大小和颜色

pn.extension(design="bootstrap", sizing_mode="stretch_width")

我们还将 Progress 栏设计设置为 Material

row_bar = pn.indicators.Progress(
    ...
    design=pn.theme.Material,
)

请注意,您也可以使用 styles 和 stylesheets

为昂贵的任务进行缓存

某些数据处理任务可能在计算上很昂贵,从而导致性能迟缓。 Panel 提供了缓存机制,使您可以存储昂贵计算的结果并在需要时重用它们,从而显着提高应用程序的响应速度。

在我们的示例中,我们使用 pn.cache 装饰器缓存了 load_processor_model 的输出。 这意味着我们不需要多次下载和加载模型。 此步骤将使您的应用程序感觉更灵敏!

附加说明:为了进一步提高响应速度,还有 defer_loading 和 加载指示器

@pn.cache
def load_processor_model(
    processor_name: str, model_name: str
) -> Tuple[CLIPProcessor, CLIPModel]:
    processor = CLIPProcessor.from_pretrained(processor_name)
    model = CLIPModel.from_pretrained(model_name)
    return processor, model

使用 JavaScript 桥接功能

虽然 Panel 提供了丰富的一组交互式功能,但您有时可能需要可以通过 JavaScript 实现的其他功能。 将 JavaScript 代码与 Panel 可视化集成以扩展其功能非常容易。 通过弥合 Python 和 JavaScript 之间的差距,您可以创建高级可视化并添加超出 Panel 本机功能范围的交互式元素。

在我们的应用程序底部,您可能已经观察到一组代表 Panel 社交媒体帐户的图标,包括 LinkedIn 和 Twitter。 当您单击这些图标中的任何一个时,您将被自动重定向到相应的社交媒体个人资料。 这种无缝的点击和重定向功能是通过 Panel 的 JavaScript 与 js_on_click 方法集成实现的

footer_row = pn.Row(pn.Spacer(), align="center")
for icon, url in ICON_URLS.items():
    href_button = pn.widgets.Button(icon=icon, width=35, height=35)
    href_button.js_on_click(code=f"window.open('{url}')")
    footer_row.append(href_button)
footer_row.append(pn.Spacer())

理解同步与异步支持

异步编程因其高效处理并发任务的能力而广受欢迎。 我们将讨论同步执行和异步执行之间的差异,并探讨 Panel 对异步操作的支持。 理解这些概念将使您能够在 Panel 中利用异步功能,从而在应用程序中提供增强的性能和响应能力。

在函数中使用 async 允许在单个线程中进行协作式多任务处理,并允许 IO 任务在后台发生。 例如,当我们从互联网获取随机图像时,我们不知道需要等待多久,并且我们不想在等待时停止程序。 Async 启用并发执行,允许我们在等待时执行其他任务,并确保应用程序具有响应性。 请务必添加相应的 awaits。

async def open_image_url(image_url: str) -> Image:
    async with aiohttp.ClientSession() as session:
        async with session.get(image_url) as resp:
            return Image.open(io.BytesIO(await resp.read()))

如果您不熟悉 async,也可以用同步方式重写它! async 不是 使用 Panel 的要求!

def open_image_url(image_url: str) -> Image:
    with requests.get(image_url) as resp:
        return Image.open(io.BytesIO(resp.read()))

其他可以尝试的想法

这里我们只探索了一个想法;您还可以尝试更多

  • 交互式文本生成:利用 Hugging Face 强大的语言模型,例如 GPT 或 Transformer,来生成交互式文本。 将 Panel 的小部件绑定功能与 Hugging Face 模型结合使用,以创建动态界面,用户可以在其中输入提示或调整参数以生成自定义文本输出。
  • 情感分析和文本分类:使用 Hugging Face 的预训练情感分析或文本分类模型构建交互式仪表板。 借助 Panel,用户可以输入文本样本,可视化预测的情感或类别概率,并通过交互式可视化探索模型预测。
  • 语言翻译:利用 Hugging Face 的翻译模型创建交互式语言翻译界面。 借助 Panel,用户可以用一种语言输入文本并可视化翻译后的输出,从而可以轻松地进行实验和探索翻译质量。
  • 命名实体识别 (NER):将 Hugging Face 的 NER 模型与 Panel 结合使用,以构建交互式 NER 可视化。 用户可以输入文本并可视化识别的实体、突出显示实体跨度,并通过直观的界面探索模型预测。
  • 聊天机器人和对话式 AI:借助 Hugging Face 的对话式模型,您可以创建交互式聊天机器人或对话式代理。 Panel 使户能够与聊天机器人进行交互式对话、可视化响应,并通过交互式小部件自定义聊天机器人的行为。
  • 模型微调和评估:使用 Panel 创建用于微调和评估 Hugging Face 模型的交互式界面。 用户可以输入自定义训练数据、调整超参数、可视化训练进度,并通过交互式可视化评估模型性能。
  • 模型比较和基准测试:使用 Panel 构建交互式界面,以比较和基准测试用于特定 NLP 任务的不同 Hugging Face 模型。 用户可以输入样本输入、比较模型预测、可视化性能指标,并探索不同模型之间的权衡。

查看我们的应用程序库以获取其他想法! 祝您实验愉快!

加入我们的社区

Panel 社区充满活力且提供支持,经验丰富的开发人员和数据科学家渴望提供帮助并分享他们的知识。 加入我们并与我们联系

与专家交谈

与我们的专家之一交谈,为您的 AI 之旅找到解决方案。

与专家交谈