做者|Chris Padwick
编译|Flin
来源|mediumhtml
农业对你今天的生活有什么影响?若是你住在城市里,你可能会以为你与生产你食物的农场和田地脱节了。农业是咱们生活的一个核心部分,咱们却经常认为这是理所固然的。python
今天的农民面临着一个巨大的挑战 —— 用更少的土地养活日益增加的全球人口。预计到2050年,世界人口将增加到近100亿,使全球粮食需求增长50%。git
随着粮食需求的增加,土地、水和其余资源将面临更大的压力。农业中固有的可变性,如气候条件的变化,以及杂草和害虫等威胁,也会对农民生产粮食的能力产生影响。在使用更少资源的同时生产更多粮食的惟一方法是经过智能机器,该机器能够帮助工做困难的农民,提供更高的一致性,准确性和效率。github
在蓝河科技,咱们正在制造下一代智能机器。农民使用咱们的工具来控制杂草和下降成本,以促进农业可持续发展。数组
咱们的除草机器人集成了摄像头、计算机视觉、机器学习和机器人技术,制造了一款智能喷雾器,能够在田间行驶(使用AutoTrac将驾驶员的负载降至最低),并快速锁定目标并喷洒杂草,使做物无缺无损。服务器
这台机器须要实时决定什么是庄稼什么是杂草。当机器在野外行驶时,高分辨率相机以高帧速率采集图像。网络
咱们开发了一个卷积神经网络(CNN),使用Pytorch分析每一帧,并生成一张像素精确的农做物和杂草所在的地图。一旦全部的植物都被识别出来,每一个杂草和做物都被映射到田间位置,机器人只喷洒杂草。app
整个过程在几毫秒内完成,由于效率很高,农民就能够覆盖尽量多的土地。dom
这是一个很棒的See&Spray视频,详细介绍了该过程。机器学习
为了支持机器学习(ML)和机器人技术,咱们基于NVIDIA Jetson AGX Xavier Edge AI平台构建了一个使人印象深入的计算单元。
由于咱们全部的推断都是实时进行的,上传到云端须要的时间太长,因此咱们将服务器场带到现场。
专门用于视觉推理和喷雾机器人的机器人的总计算能力与IBM的超级计算机Blue Gene(2007)至关。这使它成为全球移动机械中具备最高计算能力的机器!
个人研究人员和工程师团队负责训练识别做物和杂草的神经网络模型。这是一个具备挑战性的问题,由于许多杂草看起来就像庄稼。专业的农学家和杂草科学家训练咱们的标签工做人员正确地标记图像——你能发现下面哪些是杂草吗?
在下图中,棉花植物为绿色,杂草为红色。
在机器学习方面,咱们有一个复杂的堆栈。咱们用Pytorch训练咱们全部的模特。咱们在Pytorch上创建了一组内部库,容许咱们进行可重复的机器学习实验。个人团队职责分为三类:
创建生产模型以部署到机器人上
以不断提升模型性能为目标,进行机器学习实验和研究
与机器学习、A/B测试、流程改进、软件工程相关的数据分析/数据科学
咱们选择Pytorch是由于它很是灵活且易于调试。新的团队成员能够很快跟上进度,并且文档很是详尽。
在使用PyTorch以前,咱们的团队普遍使用Caffe和Tensorflow。2019年,咱们决定改用Pytorch,过渡顺利。同时也为工做流的研究提供了支持。
例如,咱们使用Torchvision库进行图像变换和张量变换。它包含了一些基本的功能,而且与像imgauge这样的复杂的加强包进行了很好的集成。torchvision 中的变换对象与imgauge的集成就是小菜一碟。
下面是一个使用Fashion MNIST数据集(https://github.com/zalandoresearch/fashion-mnist) 的代码示例。
名为CustomAugmentor的类将初始化构造函数中的iaa.Sequential对象,而后在__call__方法中调用invoke_image()。而后,在ToTensor()以前,将CustomAugmentor()添加到对transforms.Compose()的调用中。
如今,当加载批次进行训练和验证时,train和val数据加载器将应用CustomAugmentor()中定义的加强。
from imgaug import augmenters as iaa import numpy as np import os import torch from torch.utils.data import DataLoader, random_split from torchvision.datasets import FashionMNIST from torchvision import datasets, transforms DATA_DIR = './fashionMNIST/' class CustomAugmentor: def __init__(self): self.aug = iaa.Sequential([iaa.flip.Fliplr(p=0.5), iaa.GaussianBlur(sigma=(0.0, 0.1)), iaa.Multiply((0.9, 1.1)), iaa.Dropout((0, 0.05)), iaa.AdditiveGaussianNoise(scale=(0, 0.05*255)) ]) def __call__(self, img): img = np.array(img) # 在此处返回一个副本以解决错误:ValueError:至少一个步幅 #在给定的numpy数组中为负,张量为负跨度 #当前不支持。 return self.aug.augment_image(img).copy() # 转换图像 transform=transforms.Compose([CustomAugmentor(), transforms.ToTensor()]) fmnist_train = FashionMNIST(DATA_DIR, train=True, download=True, transform=transform) fmnist_test = FashionMNIST(DATA_DIR, train=False, download=True, transform=transforms.ToTensor()) fmnist_train, fmnist_val = random_split(fmnist_train, [55000, 5000]) train_dl = DataLoader(fmnist_train, batch_size=64) val_dl = DataLoader(fmnist_val, batch_size=64) test_dl = DataLoader(fmnist_test, batch_size=64)
此外,PyTorch已成为计算机视觉生态系统中最喜欢的工具(请参阅https://paperswithcode.com/,PyTorch是常见的提交)。这样一来,咱们就能够轻松地尝试诸如Debiased Contrastive Learning之类的新技术进行半监督式训练。
在模型训练方面,咱们有两个正常的工做流程:生产和研究。
对于研究应用程序,咱们的团队在内部本地计算群集上运行PyTorch。在本地群集上执行的做业由Slurm管理,Slurm是基于HPC批处理做业的调度程序。它是免费的,易于设置和维护的,而且提供了咱们小组运行数千个机器学习做业所需的全部功能。
对于基于生产的工做流程,咱们在AWS托管的Kubernetes(K8s)集群之上利用Argo工做流程。咱们的PyTorch训练代码是使用Docker部署到云中的。
对于生产部署,咱们的首要任务之一是在边缘计算设备上进行高速推理。若是机器人须要开得慢一点来等待推断,它在田间的效率就不可能那么高了。
为此,咱们使用TensorRT将网络转换为NVIDIA Jetson AGX Xavier优化模型。TensorRT不接受JIT模型做为输入,所以咱们使用ONNX从JIT转换为ONNX格式,而后使用TensorRT转换为直接部署到设备上的TensorRT引擎文件。
随着工具栈的发展,咱们指望这个过程也会获得改进。咱们的模型使用Jenkins构建过程部署到Artifactory,并经过从Artifactory中提取将它们部署到现场的远程机器上。
为了监控和评估咱们的机器学习运行,咱们发现 http://wandb.com/ 平台是最好的解决方案。他们的API使得将W&B日志集成到现有的代码库中变得更快。咱们使用W&B监控正在进行的训练,包括训练的实时曲线和验证损失。
做为使用Pytorch和W&B的一个例子,我将运行一个实验,并比较在Pytorch中使用不一样求解器的结果。Pytorch中有许多不一样的求解器——很明显的问题是你应该选择哪种?
Adam 是一个很受欢迎的解决方案。它一般在不须要设置任何参数的状况下给出良好的结果,而且是咱们一般会选择的模型。该求解器位于 https://pytorch.org/docs/stable/optim.html#torch.optim.Adam 下
对于机器学习研究人员来讲,另外一个流行的求解器选择是随机梯度降低(SGD)。此求解器在Pytorch中可用 https://pytorch.org/docs/stable/optim.html#torch.optim.SGD 得到
若是你是不知道二者之间的差别,或者若是你须要复习,我建议你把这两个的区别写下来。动量是机器学习中的一个重要概念,它能够避免陷入优化空间中的局部最小值,从而找到更好的解决方案。使用SGD和动量的问题是:我能找到击败Adam的SGD的动量设置吗?
实验装置以下。我对每次运行使用相同的训练数据,并在同一个测试集中评估结果。我要比较一下F1 score在不一样的运行中的得分。我用SGD做为求解器设置了许屡次运行,并从0–0.99扫描动量值(当使用动量时,大于1.0的任何值都会致使求解器发散)。
我设置了运行10次,动量值从0到0.9,增量为0.1。接下来,我又运行了10次,此次动量值在0.90到0.99之间,增量为0.01。在看了这些结果以后,我还进行了一组动量值为0.999和0.9999的实验。每次运行都使用不一样的随机种子,并在W&B中被赋予“SGD扫描”标签。结果如图1所示。
从图1很是清楚,动量值越大,f1分数越高。最佳值0.9447在动量值0.999时出现,在动量值0.9999时降低到0.9394。数值以下表所示。
表1:每次运行在上表中显示为一行。最后一栏是运行的动量设置。显示了第2类(庄稼)的F1得分,准确性和召回率。
这些结果与Adam相好比何?为了测试这一点,我仅用默认参数来使用 torch.optim.Adam 。我用W&B中的“Adam runs”标签来标识这些运行记录。我还标记了每一组SGD运行以进行比较。
因为每次运行使用不一样的随机种子,求解器每次初始化都会不一样,并在最后一个epoch使用不一样的权重。这会在每次运行的测试集中给出稍微不一样的结果。为了比较它们,我须要测量Adam和SGD运行值的分布。使用W&B中按标签分组的箱形图能够轻松作到这一点。
结果在图2中以图表形式显示,在表2中以表格形式显示。完整的报告也能够在线得到。
你能够看到,仅经过SGD调整动量值就没法击败Adam。动量设置为0.999能够获得很是类似的结果,但Adam运行的方差更小,平均值也更高。所以,Adam彷佛是解决咱们的植物分割问题的一个好选择!
经过集成Pytorch,W&B能够在每一层获取梯度,让咱们在训练期间检查网络。
W&B实验跟踪还可使Pytorch模型在训练期间更容易可视化,所以你能够在中央仪表板上实时查看损失曲线。咱们在团队会议中使用这些可视化效果来讨论最新结果并共享更新。
当图像经过Pytorch模型时,咱们将预测记录到 Weights & Biases 中,以可视化模型训练的结果。在这里咱们能够看到预测、正确标注和标签。这样能够轻松地肯定模型性能未达到咱们指望的状况。
在这里,咱们能够快速浏览正确标注,预测以及二者之间的差别。咱们将农做物标记为绿色,将杂草标记为红色。如你所见,该模型在识别图像中的农做物和杂草方面作得至关合理。
如下是如何在W&B中使用数据帧的简短代码示例:
# Per-sample dataframe with images. data = [] # Loop through the mini-batches. Each batch is a dictionary. For batch in batches: image = batch[“image”].astype(np.uint8) label = batch[“label”] pred = batch[“prediction”] zeros = np.zeros_like(image) diff = np.zeros_like(pred) diff[np.where(pred != label)] = 255.0 datapoint = {} datapoint['image'] = wandb.Image(image) # colorize_segmentation is a method which alpha-blends the class colors into an image. datapoint['pred'] = wandb.Image(colorize_segmentation(zeros, pred, alpha=1.0)) datapoint['label'] = wandb.Image(colorize_segmentation(zeros, label, alpha=1.0)) datapoint['diff'] = wandb.Image(diff) data.append(datapoint) # Convert the list of datapoints to a pandas dataframe and log it to W&B. log_df = pd.DataFrame(data) wandb.run.summary['my_awesome_dataframe’'] = log_df
再现性和可追溯性是任何ML系统的关键特性,并且很可贵到正确的结果。当比较不一样的网络体系结构和超参数时,输入数据必须相同才能使运行具备可比性。
一般ML团队中的个体实践者都会保存YAML或JSON配置文件——要找到团队成员的运行记录并仔细查看他们的配置文件以找出使用了什么训练集和超参数,这是一件很是痛苦的事情。咱们都作过,咱们都讨厌。
W&B刚刚发布的一个新特性解决了这个问题。工件(Artifact)容许咱们跟踪训练和评估运行的输入和输出。这对咱们的可重复性和可追溯性有很大帮助。我能够知道使用了哪些数据集来训练模型,生成了哪些模型(来自屡次运行)以及模型评估的结果。
典型的用例以下。数据暂存过程将下载最新和最大的数据,并将其暂存到磁盘上进行训练和测试(每一个数据集都是单独的)。这些数据集被指定为工件(Artifact)。
训练运行将训练集工件(Artifact)做为输入,并将通过训练的模型输出为输出工件(Artifact)。评估过程将测试集工件(Artifact)与训练的模型工件(Artifact)一块儿做为输入,并输出可能包含一组度量或图像的评估。
有向无环图(DAG)是在W&B中造成和可视化的。这是颇有帮助的,由于跟踪将机器学习模型发布到生产中所涉及的工件(Artifact)很是重要。这样的DAG很容易造成:
Artifacts特性的一大优势是能够选择上载全部工件(Artifact)(数据集、模型、评估),也能够选择只上载对工件(Artifact)的引用。这是一个很好的特性,由于移动大量数据既耗时又慢。对于数据集工件(Artifact),咱们只需在W&B中存储对这些工件(Artifact)的引用,这就容许咱们保持对数据的控制(并避免长时间的传输),而且在机器学习中仍然能够得到可追溯性和再现性。
# 初始化 wandb. wandb_run = wandb.init(job_type="train", reinit=True, project=”blog-post”, tags=[“SGD Sweep”], tensorboard=False) # 指定用于训练运行的工件(Artifact)。在这里咱们指定一个训练数据集和测试数据集。 artifact_list = [{“name”: “blueriver/blog-post/train-dataset:latest”, “type”: “dataset”}, {“name”: “blueriver/blog-post/test-dataset:latest”, “type”: “dataset”}] # 遍历列表,并告诉wandb使用工件(Artifact)。 for elem in artifact_list: artifact = wandb_run.use_artifact(elem[“name”], elem[“type”])
回顾我领导机器学习工程师团队的这些年,我看到了一些常见的挑战:
效率:当咱们开发新模型时,咱们须要快速试验并分享结果。Pytorch使咱们很容易快速添加新特性,W&B为咱们提供了调试和改进模型所需的可见性。
灵活性:与咱们的客户合做,天天都会带来新的挑战。咱们的团队须要可以知足咱们不断变化的需求的工具,这就是为何咱们选择Pytorch做为其蓬勃发展的生态系统,选择W&B做为轻量级的模块化集成。
性能:归根结底,咱们须要为咱们的农业机器人创建最精确和最快的模型。Pytorch使咱们可以快速迭代,而后将模型产品化并部署到现场。咱们在W&B的开发过程当中具备彻底的可视性和透明度,使咱们很容易肯定性能最好的模型。
原文连接:https://medium.com/pytorch/ai-for-ag-production-machine-learning-for-agriculture-e8cfdb9849a1
欢迎关注磐创AI博客站:
http://panchuang.net/
sklearn机器学习中文官方文档:
http://sklearn123.com/
欢迎关注磐创博客资源汇总站:
http://docs.panchuang.net/