Press "Enter" to skip to content

在一小时内构建你的第一个深度学习应用程序

使用HuggingFace Spaces和Gradio部署图像分类模型

Thought Catalog在Unsplash上的照片

我从事数据分析工作已经将近十年了。我时常使用机器学习技术从数据中获取洞见,并且对于使用经典的机器学习方法感到很舒服。

虽然我参加过几门关于神经网络和深度学习的慕课,但我从未在工作中使用过它们,而且这个领域对我来说似乎相当具有挑战性。我有以下这些偏见:

  • 要开始使用深度学习,你需要学习很多东西:数学,不同的框架(我至少听说过三个:PyTorch、TensorFlow和Keras)和网络架构。
  • 需要大量的数据集来训练模型。
  • 没有强大的计算机(还必须具有Nvidia GPU)几乎无法取得良好的结果,所以很难进行设置。
  • 要建立一个以机器学习为动力的服务,需要处理前端和后端。

我相信分析的主要目标是帮助产品团队基于数据做出正确的决策。现如今,神经网络肯定可以改进我们的分析,例如NLP可以从文本中获取更多的洞见。因此,我决定再次尝试利用深度学习的力量。

这就是我开始Fast.AI课程的原因(该课程在2022年初进行了更新,所以我认为内容已经有所改变,与此前在TDS上的评论不同)。我意识到使用深度学习解决任务并不那么困难。

这门课程采用自上而下的方法。所以你是从构建一个可工作的系统开始的,只有在之后才会深入了解所有所需的基础知识和细节。

在第二周,我制作了我的第一个以机器学习为动力的应用(你可以在这里尝试一下)。它是一个图像分类模型,可以识别我最喜欢的狗品种。令人惊讶的是,即使我的数据集中只有几千张图像,它也工作得很好。对我来说,我们现在可以轻松构建一个在十年前还是完全神奇的服务,这真是令人鼓舞。

Shakti Rajpurohit在Unsplash上的照片

因此,在本文中,您将找到一个初学者级别的教程,教您如何构建和部署第一个由机器学习驱动的服务。

什么是深度学习?

深度学习是机器学习的一个特定应用案例,我们使用多层神经网络作为模型。

神经网络非常强大。根据通用逼近定理,神经网络可以逼近任何函数,这意味着它们能够解决任何任务。

目前,您可以将这个模型简单地看作是一个黑盒子,它接受输入(在我们的例子中是一张狗的图像)并返回输出(在我们的例子中是一个标签)。

作者照片

构建模型

您可以在Kaggle上找到此阶段的完整代码。

我们将使用Kaggle Notebooks来构建我们的深度学习模型。如果您还没有Kaggle账号,建议您先完成注册流程。Kaggle是一个流行的数据科学家平台,您可以在上面找到数据集、参加竞赛并运行和分享您的代码。

您可以在Kaggle上创建一个Notebook,并像在本地的Jupyter Notebook一样执行代码。Kaggle甚至提供GPU,因此我们将能够快速训练神经网络模型。

作者提供的图片

让我们首先导入所有的包,因为我们将使用许多Fast.AI工具。

from fastcore.all import *from fastai.vision.all import *from fastai.vision.widgets import *from fastdownload import download_url

加载数据

毋庸置疑,我们需要一个数据集来训练我们的模型。获取一组图像的最简单方法是使用搜索引擎。

DuckDuckGo搜索引擎有一个易于使用的API和方便的Python包duckduckgo_search(更多信息),所以我们将使用它。

让我们试着搜索一张狗的图片。我们已经指定license_image = any以仅使用具有Creative Commons许可的图像。

from duckduckgo_search import DDGSimport itertoolswith DDGS() as ddgs:    res = list(itertools.islice(ddgs.images('photo samoyed happy',                                 license_image = 'any'), 1))

在输出中,我们得到了关于图像的所有信息:名称、URL和大小。

{   "title": "Happy Samoyed dog photo and wallpaper. Beautiful Happy Samoyed dog picture",    "image": "http://www.dogwallpapers.net/wallpapers/happy-samoyed-dog-wallpaper.jpg",    "thumbnail": "https://tse2.mm.bing.net/th?id=OIP.BqTE8dYqO-W9qcCXdGcF6QHaFL&pid=Api",    "url": "http://www.dogwallpapers.net/samoyed-dog/happy-samoyed-dog-wallpaper.html",    "height": 834, "width": 1193, "source": "Bing"}

现在我们可以使用Fast.AI工具下载图像并显示缩略图。

Photo by Barcs Tamás on Unsplash

我们看到了一只快乐的萨摩耶,这意味着它正在工作。所以让我们加载更多的照片。

我打算识别五种不同的狗品种(我最喜欢的品种)。我将为每个品种加载图片并将它们存储在单独的目录中。

breeds = ['siberian husky', 'corgi', 'pomeranian', 'retriever', 'samoyed']path = Path('dogs_breeds') # 定义路径for b in tqdm.tqdm(breeds):    dest = (path/b)    dest.mkdir(exist_ok=True, parents=True)         download_images(dest, urls=search_images(f'photo {b}'))    sleep(10)     download_images(dest, urls=search_images(f'photo {b} puppy'))    sleep(10)     download_images(dest, urls=search_images(f'photo {b} sleep'))    sleep(10)     resize_images(path/b, max_size=400, dest=path/b)

运行这段代码后,您将在Kaggle的右侧面板上看到所有加载的照片。

Image by author

下一步是将数据转换为适合Fast.AI模型的格式 – DataBlock

有一些参数您需要为此对象指定,但我只会强调最重要的几个:

  • splitter=RandomSplitter(valid_pct=0.2, seed=18):Fast.AI要求您选择一个验证集。验证集是一个保留数据,用于估计模型质量。验证数据在训练过程中不使用,以防止过拟合。在我们的案例中,验证集是我们数据集的随机20%。我们指定了seed参数,以便下次能够精确重现相同的拆分。
  • item_tfms=[Resize(256, method=’squish’)]:神经网络以批处理方式处理图像。这就是为什么我们必须有相同大小的图片。有不同的图像调整大小方法,我们现在使用的是squish,但我们将在后面详细讨论它。

我们定义了一个数据块。函数show_batch可以显示带有标签的随机图像集。

Unsplash上的Angel Luciano的照片 | Unsplash上的Brigitta Botrágyi的照片 | Unsplash上的Charlotte Freeman的照片

数据看起来还不错,所以让我们继续进行训练。

训练模型

你可能会感到惊讶,但下面的两行代码将完成所有工作。

在一小时内构建你的第一个深度学习应用程序 四海 第8张

我们使用了一个预训练模型(具有18个深层的卷积神经网络——Resnet18)。这就是为什么我们调用了函数fine_tune

我们将模型训练了三个周期,这意味着模型看到了整个数据集三次。

我们还指定了指标——accuracy(正确标记图片的比例)。您可以在每个周期后的结果中看到这个指标(它仅使用验证集计算,以免结果偏差)。然而,它不参与优化过程,仅供您参考。

整个过程大约花了30分钟,现在我们的模型可以以94.45%的准确率预测狗的品种。干得好!但我们能提高这个结果吗?

提高模型的准确率:数据清理和增强

如果您想尽快看到您的第一个模型工作,请随时将本节留给以后再看,继续进行模型的部署。

首先,让我们看看模型的错误:它能否将柯基与哈士奇或博美与金毛区分开来。我们可以使用confusion_matrix来进行计算。注意,混淆矩阵也仅使用验证集计算。

在一小时内构建你的第一个深度学习应用程序 四海 第9张

Fast.AI课程中还分享了另一个技巧,即模型可以用来清理我们的数据。为此,我们可以查看损失最高的图像:这可能是模型以高置信度错误或以低置信度正确的情况。

Unsplash上的Benjamin Vang的照片 | Unsplash上的Xennie Moore的照片 | Unsplash上的Alvan Nee的照片

显然,第一张图片的标签是错误的,而第二张图片包含了哈士奇和柯基。所以还有改进的空间。

幸运的是,Fast.AI提供了一个方便的ImageClassifierCleaner小部件,可以帮助我们快速解决数据问题。您可以在笔记本中初始化它,然后就能够更改数据集中的标签。

cleaner = ImageClassifierCleaner(learn)cleaner

在每个类别之后,您可以运行以下代码来修复问题:删除图片或将其移动到正确的文件夹中。

for idx in cleaner.delete(): cleaner.fns[idx].unlink()for idx,breed in cleaner.change(): shutil.move(str(cleaner.fns[idx]), path/breed)

现在我们可以再次训练我们的模型,并看到准确率提高了:95.4%对比94.5%。

在一小时内构建你的第一个深度学习应用程序 四海 第11张

正确识别柯基的比例已经从88%增加到96%。真是太棒了!

在一小时内构建你的第一个深度学习应用程序 四海 第12张

改进我们的模型的另一种方法是改变我们的调整大小方法。我们使用的是压缩方法,但是正如你所见,它会改变自然物体的比例。让我们试着更有想象力一些,使用增强功能。

增强功能是对图像进行的更改(例如,对比度改进,旋转或裁剪)。这将为我们的模型提供更多变量的数据,希望能提高其质量。

像往常一样,使用Fast.AI,您只需要更改一些参数即可添加增强功能。

Photo by FLOUFFY on Unsplash

此外,由于在每个时期,通过增强功能,模型将看到略有不同的图像,我们可以增加时期的数量。经过六个时期,我们获得了95.65%的准确率-稍微好一点的结果。整个过程大约需要一个小时。

下载模型

最后一步是下载我们的模型。这非常简单。

learn.export('cuttest_dogs_model.pkl')

然后,您将获得一个标准的pickle文件(常见的Python格式,用于存储对象)。只需在Kaggle笔记本的右侧面板上选择文件旁边的更多操作,即可将模型下载到计算机上。

在一小时内构建你的第一个深度学习应用程序 四海 第14张

现在我们有了训练好的模型,让我们部署它,以便与世界分享结果。

部署您的模型

我们将使用HuggingFace Spaces和Gradio来构建我们的Web应用程序。

设置HuggingFace Space

HuggingFace是一家提供便利工具的公司,例如,流行的transformers库或共享模型和数据集的工具。今天,我们将使用他们的Spaces来托管我们的应用程序。

首先,如果您还没有注册,请创建一个帐户。这只需要几分钟的时间。请按照此链接。

现在是时候创建一个新的Space了。转到Spaces选项卡,点击“创建”按钮。您可以在文档中找到更详细的说明。

然后,您需要指定以下参数:

  • 名称(它将用于您的应用程序URL,所以请谨慎选择),
  • 许可证(我选择了开源Apache 2.0许可证),
  • SDK(在此示例中,我将使用Gradio)。

在一小时内构建你的第一个深度学习应用程序 四海 第15张

然后,用户友好的HuggingFace会向您显示说明。 TL;DR现在您有了一个Git存储库,您需要将代码提交到那里。

Git有一个细微之处。由于您的模型很可能很大,最好设置Git LFS(大文件存储),这样Git就不会跟踪此文件的所有更改。有关安装,请按照网站上的说明进行操作。

-- 克隆存储库git clone https://huggingface.co/spaces/<your_login>/<your_app_name>cd <your_app_name>-- 设置git-lfsgit lfs installgit lfs track "*.pkl"git add .gitattributesgit commit -m "update gitattributes to use lfs for pkl files"

Gradio

Gradio是一个允许您仅使用Python构建令人愉快和友好的Web应用程序的框架。这就是为什么它对于原型设计非常有价值的工具(特别是对于像我这样没有深入的JavaScript知识的人)。

在Gradio中,我们将定义我们的接口,指定以下参数:

  • input — 一个图像,
  • output — 具有五个可能类别的标签,
  • titledescription 和一组示例图像(我们还需要将它们提交到代码库中),
  • enable_queue=True 可以帮助应用程序处理大量的流量,如果它变得非常受欢迎,
  • function 用于处理输入图像。

为了获取输入图像的标签,我们需要定义预测函数,该函数加载我们的模型并返回每个类别的概率字典。

最终,我们将在 app.py 中使用以下代码:

import gradio as grfrom fastai.vision.all import *learn = load_learner('cuttest_dogs_model.pkl')labels = learn.dls.vocab # 模型类别的列表def predict(img):    img = PILImage.create(img)    pred,pred_idx,probs = learn.predict(img)    return {labels[i]: float(probs[i]) for i in range(len(labels))}gr.Interface(    fn=predict,    inputs=gr.inputs.Image(shape=(512, 512)),    outputs=gr.outputs.Label(num_top_classes=5),    title="最可爱的狗狗分类器 🐶🐕🦮🐕‍🦺",    description="使用 HuggingFace Spaces 和 Gradio 创建的深度学习应用的演示。分类器训练于哈士奇、金毛犬、博美犬、柯基和萨摩耶的图像。",    examples=['husky.jpg', 'retriever.jpg', 'corgi.jpg', 'pomeranian.jpg', 'samoyed.jpg'],    enable_queue=True).launch()

如果您想了解更多关于 Gradio 的内容,请阅读文档。

我们还需要创建一个 requirements.txt 文件,并在其中添加 fastai,这样该库就会在我们的服务器上安装。

所以现在只剩下将所有内容推送到 HuggingFace Git 仓库。

git add * git commit -am 'Cuttest Dogs 应用的第一个版本'git push

您可以在 GitHub 上找到完整的代码。

在推送文件之后,返回到 HuggingFace Space,您将看到类似的图片显示构建过程。如果一切正常,您的应用程序将在几分钟内运行起来。

在一小时内构建你的第一个深度学习应用程序 四海 第16张

如果出现任何问题,您将看到一个堆栈跟踪。然后您需要返回到您的代码中,修复错误,推送一个新版本,并等待几分钟。

它正在运行

现在我们可以使用真实的照片来使用这个模型,例如,验证我的家人的狗是否真的是柯基犬。

作者照片

今天我们经历了构建深度学习应用的整个过程:从获取数据集和训练模型到编写和部署 Web 应用程序。希望您能够完成本教程,并且现在可以在生产环境中测试您的精彩模型。

非常感谢您阅读本文。希望对您有所启发。如果您有任何后续问题或评论,请在评论区留言。同时,欢迎分享您的应用链接。

Leave a Reply

Your email address will not be published. Required fields are marked *