做者|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/