dask-使用PyTorch进行批量预测

使用PyTorch进行批量预测

%matplotlib inline 

此示例遵循Torch的迁移学习教程。我们会

  1. 对特定任务(蚂蚁与蜜蜂)微调预训练的卷积神经网络。

  2. 使用Dask群集对该模型进行批量预测。

主要重点是使用Dask群集进行批次预测。

请注意,examples.dask.org Binder上的基本环境不包括PyTorch或torchvision。要运行此示例,您需要运行

!conda install -y pytorch-cpu torchvision 

这将需要一些时间才能运行。

下载资料

PyTorch文档包含一小组数据。我们将在本地下载并解压缩。

import urllib.request import zipfile 
filename, _ = urllib.request.urlretrieve("https://download.pytorch.org/tutorial/hymenoptera_data.zip", "data.zip") zipfile.ZipFile(filename).extractall() 

目录看起来像

hymenoptera_data/ train/ ants/ 0013035.jpg ... 1030023514_aad5c608f9.jpg bees/ 1092977343_cb42b38d62.jpg ... 2486729079_62df0920be.jpg train/ ants/ 0013025.jpg ... 1030023514_aad5c606d9.jpg bees/ 1092977343_cb42b38e62.jpg ... 2486729079_62df0921be.jpg 

在学习完本教程之后,我们将对模型进行微调。

import torchvision from tutorial_helper import (imshow, train_model, visualize_model, dataloaders, class_names, finetune_model) 

微调模型

我们的基本模型是resnet18。它可以预测1,000种类别,而我们只预测2种(蚂蚁或蜜蜂)。为了使该模型在examples.dask.org上快速培训,我们仅使用几个纪元。

import dask 
%%time model = finetune_model() 
时代0/1 ---------- 火车损失:0.6196累积:0.6844 val损失:0.2042 Acc:0.9281 时代1/1 ---------- 火车损失:0.4517累积:0.7787 val损失:0.1458 Acc:0.9477 训练在0m 4s内完成 最佳增值值:0.947712 CPU时间:用户3.92 s,系统:2.03 s,总计:5.95 s 挂墙时间:6.33 s 

在一些随机图像上,事情似乎还可以:

visualize_model(model) 
../_images/machine-learning_torch-prediction_13_0.svg

使用Dask进行批量预测

现在是主要主题:在Dask集群上使用预训练的模型进行批量预测。有两个主要的复杂性,它们都涉及最小化移动的数据量:

  1. 将数据加载到工作程序上。。我们将用于dask.delayed将数据加载到工作程序上,而不是将数据加载到客户端上并将其发送给工作程序。

  2. PyTorch神经网络很大。我们不希望它们出现在Dask任务图中,我们只希望将它们移动一次。

from distributed import Client client = Client(n_workers=2, threads_per_worker=2) client 

客户

  • 工人数: 2
  • 核心数: 4
  • 内存: 100.00 GB

将数据加载到工作人员上

首先,我们将定义几个助手来加载数据并对神经网络进行预处理。我们将dask.delayed在这里使用它,以便执行是懒惰的,并且在集群上进行。有关使用的更多信息,请参见延迟的示例dask.delayed

import glob import toolz import dask import dask.array as da import torch from torchvision import transforms from PIL import Image @dask.delayed def load(path, fs=__builtins__): with fs.open(path, 'rb') as f: img = Image.open(f).convert("RGB") return img @dask.delayed def transform(img): trn = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) return trn(img) 
objs = [load(x) for x in glob.glob("hymenoptera_data/val/*/*.jpg")] 

要从云存储(例如Amazon S3)加载数据,您将使用

import s3fs fs = s3fs.S3FileSystem(...) objs = [load(x, fs=fs) for x in fs.glob(...)] 

PyTorch模型期望特定形状的张量,因此让我们对其进行转换。

tensors = [transform(x) for x in objs] 

而且该模型需要成批的输入,因此让我们将其堆叠在一起。

batches = [dask.delayed(torch.stack)(batch) for batch in toolz.partition_all(10, tensors)] batches[:5] 
[已延迟('stack-da59d324-464a-4dce-adfa-0dc99dc53299', 延迟的('stack-939f881b-58ba-4bb5-b4eb-1df6ccfa850f'), 延迟('stack-e3809d5d-84f2-4279-a1a6-71131f4d2c53'), 延迟的('stack-a172c545-7cdd-467f-a2bc-e5c5ae611d50'), 延迟('stack-8698c88b-6e05-442d-8346-8af67d0992ae')] 

最后,我们将编写一个小的predict帮助程序来预测输出类(0或1)。

@dask.delayed def predict(batch, model): with torch.no_grad(): out = model(batch) _, predicted = torch.max(out, 1) predicted = predicted.numpy() return predicted 

移动模型

PyTorch神经网络很大,因此我们不想在任务图中重复很多次(每批一次)。

import pickle dask.utils.format_bytes(len(pickle.dumps(model))) 
'44 .80 MB' 

相反,我们还将模型本身包装在中dask.delayed。这意味着该模型在Dask图中仅显示一次。

此外,由于我们在上面进行了微调(如果可以在GPU上运行,则可以在GPU上运行),因此我们应该将模型移回CPU。

dmodel = dask.delayed(model.cpu()) # ensuring model is on the CPU 

现在,我们将使用(延迟)predict方法来获得我们的预测。

predictions = [predict(batch, dmodel) for batch in batches] dask.visualize(predictions[:2]) 
../_images/machine-learning_torch-prediction_30_0.png

可视化有些混乱,但是大型的PyTorch模型是这两个predict任务的始祖。

现在,我们可以使用Dask集群执行所有工作了。由于我们正在使用的数据集很小,因此仅dask.compute将结果带回本地客户端是安全的。对于较大的数据集,您将要写入磁盘或云存储,或者继续处理集群上的预测。

predictions = dask.compute(*predictions) predictions 
(数组([1,1,1,0,1,0,1,1,1,1]), 数组([1,1,1,1,1,1,1,1,1,1,1]), 数组([1,1,1,1,1,1,1,1,1,1,1]), 数组([1,1,1,1,1,1,1,1,1,1,1]), 数组([1,1,1,1,1,1,1,1,1,1,1]), 数组([1,1,1,1,1,1,1,0,1,0]), 数组([1,1,1,1,1,1,1,1,1,1,1]), 数组([1,1,1,1,1,1,1,1,1,1,1]), array([1,1,1,0,0,0,0,0,0,0]), array([0,0,0,1,0,0,0,0,0,0]), 数组([1,0,0,0,0,0,0,0,0,0]), array([0,0,0,1,0,0,0,0,0,0]), array([0,0,0,1,0,0,0,0,0,0]), 数组([0,0,0,0,0,0,0,0,0,0]), 数组([0,0,0,0,0,0,0,0,0,0]), 数组([0,0,0])) 

概要

本示例说明了如何使用PyTorch和Dask对一组图像进行批量预测。我们非常小心地将数据远程加载到群集上,并且只对大型神经网络进行一次序列化。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章