将Python脚本变成漂亮的ML工具
Devin hao Architect

将Python脚本变成漂亮的ML工具

Streamlit,这是专为ML工程师打造的应用程序框架
Adrien Treuille
image
在300行Python中使用实时神经网络推理对语义搜索引擎进行编码。

以我的经验,每个不平凡的机器学习项目最终都将使用漏洞缠身且无法维护的内部工具进行缝合。这些工具(通常是Jupyter笔记本和Flask应用程序的拼凑而成)难以部署,需要对客户端-服务器体系结构进行推理,并且无法与Tensorflow GPU会话等机器学习结构很好地集成。

我首先在卡内基·梅隆大学(Carnegie Mellon),然后在伯克利(Berkeley),谷歌X(Google X),以及后来在Zoox构建自动机器人时就看到了。这些工具通常是在Jupyter笔记本电脑中诞生的:传感器校准工具,模拟比较应用程序,LIDAR对准应用程序,场景重播工具等等。
随着工具重要性的提高,项目经理介入了。过程萌芽了。要求开花。这些单独的项目孕育成脚本,并逐渐成为繁琐的维护噩梦。

image
机器学习工程师的临时应用构建流程。

当工具变得至关重要时,我们召集了工具团队。他们写了流利的Vue和React。他们在笔记本电脑上贴上声明性框架的标签。他们有一个设计过程:

image
工具团队的应用程序构建流程整洁。

太棒了!但是这些工具都需要新功能,例如每周一次。工具团队正在支持其他十个项目。他们会说:“我们将在两个月内再次更新您的工具。”
因此,我们回到了构建自己的工具,部署Flask应用程序,编写HTML,CSS和JavaScript,以及尝试对从笔记本到样式表的所有内容进行版本控制的过程。因此,我的老Google X朋友Thiago Teixeira和我开始思考以下问题:如果我们能够使构建工具像编写Python脚本一样容易,该怎么办?
我们希望机器学习工程师无需工具团队就能创建精美的应用程序。这些内部工具应作为ML工作流程的自然副产品而出现。写这样的工具应该感觉像训练神经网络或Jupyter执行即席分析!同时,我们希望保留功能强大的应用程序框架的所有灵活性。我们想要创建工程师可以炫耀的漂亮,高性能的工具。基本上,我们想要这样:

image
Streamlit应用程序构建流程。

我们拥有一个了不起的Beta社区,其中包括来自Uber,Twitter,Stitch Fix和Dropbox的工程师,我们工作了一年的时间来创建Streamlit,这是一个针对ML工程师的完全免费和开源的应用程序框架。对于每个原型,Streamlit的核心原理变得越来越简单。他们是:
#1:拥抱Python脚本。Streamlit应用程序实际上只是从上到下运行的脚本。没有隐藏状态。您可以使用函数调用来分解代码。如果您知道如何编写Python脚本,则可以编写Streamlit应用程序。例如,这是您写入屏幕的方式:

导入streamlit为st 
st.write('Hello,world!')

image

很高兴见到你。
#2:将小部件视为变量。Streamlit中没有回调!每次交互都只是从上到下重新运行脚本。这种方法可以产生非常干净的代码:
导入streamlit为st

x = st.slider('x')
st.write(x,'squared is',x * x)

image
包含三行代码的交互式Streamlit应用程序。

#3:重用数据和计算。如果您下载大量数据或执行复杂的计算该怎么办?关键是跨运行安全地重用信息。Streamlit引入了一种缓存原语,其行为类似于持久的默认情况下不可变的数据存储,可让Streamlit应用程序安全,轻松地重用信息。例如,此代码下载数据一次从Udacity自驾车项目,得到一个简单,快捷的应用程序:

导入 streamlit as st
将熊猫作为 pd 导入

#重复使用这些数据!
read_and_cache_csv = st.cache(pd.read_csv)

BUCKET  =  “ https://streamlit-self-driving.s3-us-west-2.amazonaws.com/ ”
数据= read_and_cache_csv(BUCKET  +  “ labels.csv.gz ”,NROWS = 1000)
wanted_label = st.selectbox('过滤到:',[ ' car ',' truck ' ])
st.write(数据[数据。标签==所需标签])

原始代码查看:https://gist.github.com/treuille/c633dc8bc86efaa98eb8abe76478aa81/raw/2019640b6a9ff5da5ab6d5b11b3345ddc764b285/cache_example.py

使用st.cache在Streamlit运行中保留数据。要运行此代码,请按照以下说明进行操作。

image

运行上面的st.cache示例的输出。

简而言之,Streamlit的工作方式如下:

  1. 对于每个用户交互,整个脚本都是从头开始运行的。
    2.Streamlit在给定小部件状态的情况下为每个变量分配一个最新值。
    3.缓存允许Streamlit跳过冗余数据获取和计算。
    或在图片中:
    image
    用户事件触发Streamlit从头开始重新运行脚本。只有高速缓存在运行之间持续存在。

如果这听起来很有趣,那么您可以立即尝试!赶紧运行:

$ pip install --upgrade streamlit 
$ streamlit hello
现在,您可以在浏览器中查看Streamlit应用程序。
本地URL:
http://localhost:8501 
外网URL:
http://10.0.1.29:8501

这将自动弹出打开一个指向您本地Streamlit应用程序的Web浏览器。如果没有,只需单击链接。

image

要查看类似此分形动画的更多示例,请从命令行运行streamlit hello。


好。你从分形玩回来了吗?这些可能会令人着迷。
这些想法的简单性不会阻止您使用Streamlit创建令人难以置信的丰富实用的应用程序。在Zoox和Google X期间,我看着无人驾驶汽车项目激增为数以十亿计的视觉数据,需要对其进行搜索和理解,包括在图像上运行模型以比较性能。我见过的每个自动驾驶汽车项目最终都让整个团队都在使用这种工具。
在Streamlit中构建这样的工具很容易。这个Streamlit演示使您可以在整个Udacity自动驾驶汽车照片数据集中执行语义搜索,可视化人类注释的地面真相标签,并从应用程序内部实时运行完整的神经网络(YOLO) [1]。
image

这个300行的Streamlit演示结合了语义视觉搜索和交互式神经网络推理。

整个应用程序是一个完全自包含的300行Python脚本,其中大多数是机器学习代码。实际上,整个应用程序中只有23个Streamlit调用。您可以立即自己运行它!
$ pip install --upgrade streamlit opencv-python 
$ streamlit run
https://raw.githubusercontent.com/streamlit/demo-self-driving/master/app.py

在与机器学习团队合作进行自己的项目时,我们意识到这些简单的想法产生了许多重要的好处:
Streamlit应用程序是纯Python文件。因此,您可以在Streamlit中使用自己喜欢的编辑器和调试器。

image

我最喜欢的用于编写Streamlit应用程序的布局在左侧是VSCode,在右侧是Chrome。

纯Python脚本可与Git和其他源代码控制软件无缝配合,包括提交,拉取请求,问题和注释。因为Streamlit的基础语言是纯Python,所以您可以免费获得这些出色的协作工具的所有好处。

image

因为Streamlit应用程序只是Python脚本,所以您可以使用Git轻松地对其进行版本控制。

Streamlit提供了即时模式实时编码环境。当Streamlit检测到源文件更改时,只需单击始终重新运行。

image
单击“始终重新运行”以启用实时编码。

缓存简化了计算管道的设置。令人惊讶的是,链接缓存的功能会自动创建高效的计算管道!考虑以下代码,这些代码是从我们的Udacity演示改编而成的:

import streamlit as st
import pandas as pd

@st.cache
def load_metadata():
    DATA_URL = "https://streamlit-self-driving.s3-us-west-2.amazonaws.com/labels.csv.gz"
    return pd.read_csv(DATA_URL, nrows=1000)

@st.cache
def create_summary(metadata, summary_type):
    one_hot_encoded = pd.get_dummies(metadata[["frame", "label"]], columns=["label"])
    return getattr(one_hot_encoded.groupby(["frame"]), summary_type)()

# Piping one st.cache function into another forms a computation DAG.
summary_type = st.selectbox("Type of summary:", ["sum", "any"])
metadata = load_metadata()
summary = create_summary(metadata, summary_type)
st.write('## Metadata', metadata, '## Summary', summary)

源码来自:https://gist.github.com/treuille/ac7755eb37c63a78fac7dfef89f3517e/raw/568cc2d190c2f96b2a8a7aaf6fa444d68bde630e/caching_DAG_example.py

Streamlit中的简单计算管道。要运行此代码,请按照以下说明进行操作。
基本上,管道是load_metadata→create_summary。每次运行脚本时,Streamlit只会重新计算需要正确答案的管道子集。酷!

image
为了使应用程序具有高性能,Streamlit仅重新计算更新UI所需的任何内容。

Streamlit是为GPU构建的。Streamlit允许直接访问机器级原语,例如TensorFlow和PyTorch,并补充了这些库。例如,在此演示中,Streamlit的缓存存储了整个NVIDIA名人GAN [2]。当用户更新滑块时,这种方法几乎可以实现瞬时推断。

image
该Streamlit应用程序使用管韶博的TL-GAN [3] 演示了NVIDIA名人GAN [2]模型。

Streamlit是一个免费的开源库,而不是专有的Web应用程序。您可以在不与我们联系的情况下在本地提供Streamlit应用程序。您甚至可以在没有Internet连接的笔记本电脑上本地运行Streamlit!此外,现有项目可以逐步采用Streamlit。

image
有几种方法逐渐采用Streamlit。(图标由fullvector / Freepik提供。)
这只是您使用Streamlit可以做的事情的表面。

Streamlit最令人兴奋的方面之一是如何将这些原语轻松地组合成看起来像脚本的复杂应用程序。关于我们的架构如何工作以及我们计划的功能,我们还有很多话要说,但是我们将其保存下来以备将来之用。

image
Streamlit组件的框图。更多即将推出!

我们很高兴能最终与社区今天共享Streamlit,并看到你们所有人用它构建的东西。我们希望您会发现将Python脚本转换为漂亮的ML应用变得轻松而愉快。

感谢Amanda Kelly,Thiago Teixeira,TC Ricks,Seth Weidman,Regan Carey,Beverly Treuille,GenevièveWachtell和Barney Pell在本文中提供的有益帮助。

参考文献:
[1] J. Redmon and A. Farhadi, *YOLOv3: An Incremental Improvement *(2018), arXiv.
[2] T. Karras, T. Aila, S. Laine, and J. Lehtinen, Progressive Growing of GANs for Improved Quality, Stability, and Variation (2018), ICLR.
[3] S. Guan, *Controlled image synthesis and editing using a novel TL-GAN model *(2018), Insight Data Science Blog.

感谢TC Ricks ,Amanda Kelly 和Amanda Kelly 。