PyTorch可以構建複雜的AI模型,但一旦研究變得複雜,就很可能會引入錯誤。PyTorch Lightning完全解決了這個問題。本文譯自Pytorch官方團隊,介紹了PyTorch Lightning V1.0.0的九大特點。 >>加入極市CV技術交流群,走在計算機視覺的最前沿
在過去的幾個月裡,我們一直在努力工作,微調 API,改進文檔,錄製教程,現在終於是時候與大家分享 PyTorch Lightning 的 V1.0.0版了。想要雲上縮放模型的極速方案嗎?請繼續閱讀。AI 研究的發展速度遠遠超過任何單一框架所能跟上的速度。深度學習的領域不斷發展,主要是在複雜性和規模。Lightning 提供了一個為複雜模型交互世界設計的用戶體驗,同時抽象出所有令人分心的工程細節,如多 GPU 和多 TPU 訓練,early stopping,日誌等.像 PyTorch 這樣的框架是為 AI 研究主要關注網絡架構的時代而設計的。nn.Module 模塊可以定義操作順序。這些框架在為研究或生產提供極其複雜的模型所需的所有部件方面做出了令人難以置信的工作。但是一旦模型開始相互作用,比如 GAN,BERT,或者自動編碼器,這種模式就會打破,巨大的靈活性很快就會變成樣板,項目上了規模就很難維護。與之前出現的框架不同,PyTorch Lightning 被設計成封裝一系列相互作用的模型,我們稱之為深度學習系統(deep learning systems)。Lightning 是為當今世界更複雜的研究和生產案例而設計的,在這些案例中,許多模型使用複雜的規則相互作用。autoencoder = LitAutoEncoder()torch.jit.save(autoencoder.to_torchscript(), "model.pt")os.path.isfile("model.pt")
with tempfile.NamedTemporaryFile(suffix='.onnx', delete=False) as tmpfile: autoencoder = LitAutoEncoder() input_sample = torch.randn((1, 28 * 28)) autoencoder.to_onnx(tmpfile.name, input_sample, export_params=True) os.path.isfile(tmpfile.name)因此,這意味著你的數據科學家、研究人員等團隊現在還可以成為將模型投入生產的人。他們不需要龐大的機器學習工程師團隊。
這是領先的公司使用 Lightning 的一個主要原因: 作為一種幫助他們大大縮短生產時間而不失去任何研究所需的靈活性的方法。這正是我們企業級服務提供的: Grid AI 是我們在雲上進行規模訓練的原生平臺。Grid 允許任何構建深度學習模型的人在大規模計算資源上迭代,然後立即將這些模型部署到一個可伸縮的環境中,能夠處理你扔給深度學習系統的最大流量。你還會注意到,我們已經整合了所有的博客文章,極速的視頻教程,社區項目和其他資源在我們的全新主頁下,展示所有的東西快如閃電!pytorch_lightning.metrics 是一個為了在 PyTorch 和 PyTorch Lightning 中方便度量開發和使用而創建的度量 API。更新的 API 提供了一種內置方法,可以跨多個 GPU (進程)計算每步的度量,同時存儲統計信息,允許你在一個 epoch 結束時計算度量,而不必擔心與分布式後端相關的任何複雜性。它對所有的邊緣情況都進行了嚴格的測試,並且包含了越來越多的常用度量實現,比如 Accuracy、 Precision、 Recall、 Fbeta、 MeanSquaredError 等等。
class LitModel(pl.LightningModule): def __init__(self): ... self.train_acc = pl.metrics.Accuracy() self.valid_acc = pl.metrics.Accuracy()
def training_step(self, batch, batch_idx): logits = self(x) ... self.train_acc(logits, y) self.log('train_acc_step', self.train_acc)
def validation_step(self, batch, batch_idx): logits = self(x) ... self.valid_acc(logits, y) self.log('valid_acc', self.valid_acc)要實現自定義度量,只需子類化基本 Metric 類並實現 __init__()、 update() 和 compute()方法。你所需要做的就是正確調用 add _ state () ,以便使用 DDP 實現自定義度量。使用 add_state()添加的度量狀態變量調用 reset()。from pytorch_lightning.metrics import Metric
class MyAccuracy(Metric):
def __init__(self, dist_sync_on_step=False): super().__init__(dist_sync_on_step=dist_sync_on_step) self.add_state("correct", default=torch.tensor(0), dist_reduce_fx="sum") self.add_state("total", default=torch.tensor(0), dist_reduce_fx="sum") def update(self, preds: torch.Tensor, target: torch.Tensor): preds, target = self._input_format(preds, target) assert preds.shape == target.shape self.correct += torch.sum(preds == target) self.total += target.numel() def compute(self): return self.correct.float() / self.total使用 Lightning,你不需要擔心什麼時候啟用/禁用梯度,做一個後向傳播,或者更新優化器,只要你從 training_step 返回一個附加圖(graph),Lightning 將自動優化。def training_step(self, batch, batch_idx): loss = self.encoder(batch[0]) return loss然而,對於某些研究,比如 GAN、強化學習或者有多個優化器或者內部循環的東西,你可以關閉自動優化,自己完全控制訓練循環。trainer = Trainer(automatic_optimization=False)from pytorch_lightning.metrics import Metric
class MyAccuracy(Metric):
def __init__(self, dist_sync_on_step=False): super().__init__(dist_sync_on_step=dist_sync_on_step) self.add_state("correct", default=torch.tensor(0), dist_reduce_fx="sum") self.add_state("total", default=torch.tensor(0), dist_reduce_fx="sum") def update(self, preds: torch.Tensor, target: torch.Tensor): preds, target = self._input_format(preds, target) assert preds.shape == target.shape self.correct += torch.sum(preds == target) self.total += target.numel() def compute(self): return self.correct.float() / self.totalLightning 使得 loggers 的集成變得非常簡單——只需在 LightningModule 的任何地方調用 log()方法,它就會將記錄的數量發送到你選擇的 logger。默認情況下我們使用 Tensorboard,但是你可以選擇任何你想用的支持的 logger。def training_step(self, batch, batch_idx): self.log('my_metric', x)根據 .log () 的調用位置,Lightning 自動確定何時應該進行日誌記錄(每步或每個epoch) ,但是當然你可以通過手動使用 on_step 和 on_epoch 選項來覆蓋默認行為。設置為 on_epoch = True 將在整個訓練 epoch 期間累積你的日誌值。def training_step(self, batch, batch_idx): self.log('my_loss', loss, on_step=True, on_epoch=True, prog_bar=True, logger=True)我們 deprecate 了 EvalResult 和 TrainResult,這有利於簡化數據流,並在訓練和驗證循環中將日誌與數據解耦。每個循環(訓練、驗證、測試)都有三個可以實現的鉤子(hooks):x_step
x_step_end
x_epoch_end
為了說明數據是如何流動的,我們將使用訓練循環(即: x = training)outs = []for batch in data: out = training_step(batch) outs.append(out)training_epoch_end(outs)你在 training_step 中返回的任何東西都可以作為 training_epoch_end 的輸入。def training_step(self, batch, batch_idx): prediction = … return {'loss': loss, 'preds': prediction}
def training_epoch_end(self, training_step_outputs): for out in training_step_outputs: prediction = out['preds'] 驗證和測試步驟也是如此: validation_step 或 test_step 中返回的任何內容都可以用作{ validation/test }_step_end 或{ validation/test }_epoch_end 的輸入。如果你使用 DP 或 DDP2分布式模式(即: 拆分 batch 到不同的 GPU) ,請使用 x_step_end 手動聚合(或者不實現它,讓 lightning 自動聚合)。Lightning 現在自動為你保存一個 checkpoint 在你的當前工作目錄,還有你的最後一個訓練 epoch 的狀態。這樣可以確保在訓練被中斷的情況下繼續進行訓練。你可以自定義 checkpointing 行為來監控任意數量的訓練或驗證步驟。例如,如果你想根據驗證損失更新checkpoint:計算你希望監控的任何指標或其他數量,例如驗證集損失。
使用 log() 方法記錄數量,並用一個鍵如 val_loss。
初始化 ModelCheckpoint 回調,並設置監視器為你的數量的鍵。
回調傳遞給 checkpoint_callback Trainer flag。
from pytorch_lightning.callbacks import ModelCheckpoint
class LitAutoEncoder(pl.LightningModule): def validation_step(self, batch, batch_idx): x, y = batch y_hat = self.backbone(x)
loss = F.cross_entropy(y_hat, y)
self.log('val_loss', loss)
# 3. Init ModelCheckpoint callback, monitoring 'val_loss'checkpoint_callback = ModelCheckpoint(monitor='val_loss')
# 4. Pass your callback to checkpoint_callback trainer flagtrainer = Trainer(checkpoint_callback=checkpoint_callback)請在我們的 release notes (https://github.com/PyTorchLightning/pytorch-lightning/releases)中閱讀所有的 API 變化,其中包括很多 bug 的修復。來源:https://medium.com/pytorch/pytorch-lightning-1-0-from-0-600k-80fc65e2fab0推薦閱讀
ACCV 2020國際細粒度網絡圖像識別競賽正式開賽!
添加極市小助手微信(ID : cvmart2),備註:姓名-學校/公司-研究方向-城市(如:小極-北大-目標檢測-深圳),即可申請加入極市目標檢測/圖像分割/工業檢測/人臉/醫學影像/3D/SLAM/自動駕駛/超解析度/姿態估計/ReID/GAN/圖像增強/OCR/視頻理解等技術交流群:每月大咖直播分享、真實項目需求對接、求職內推、算法競賽、乾貨資訊匯總、與 10000+來自港科大、北大、清華、中科院、CMU、騰訊、百度等名校名企視覺開發者互動交流~
覺得有用麻煩給個在看啦~