日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

【深度学习】高效使用Pytorch的6个技巧:为你的训练Pipeline提供强大动力

發(fā)布時(shí)間:2025/3/8 pytorch 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【深度学习】高效使用Pytorch的6个技巧:为你的训练Pipeline提供强大动力 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者:Eugene Khvedchenya? ?編譯:ronghuaiyang

導(dǎo)讀

只報(bào)告模型的Top-1準(zhǔn)確率往往是不夠的。

將train.py腳本轉(zhuǎn)換為具有一些附加特性的強(qiáng)大pipeline

每一個(gè)深度學(xué)習(xí)項(xiàng)目的最終目標(biāo)都是為產(chǎn)品帶來價(jià)值。當(dāng)然,我們想要最好的模型。什么是“最好的” —— 取決于特定的用例,我將把這個(gè)討論放到這篇文章之外。我想談?wù)勅绾螐哪愕?strong>train.py腳本中得到最好的模型。

在這篇文章中,我們將介紹以下技巧:

  • 用高級(jí)框架代替自己寫的循環(huán)

  • 使用另外的度量標(biāo)準(zhǔn)監(jiān)控訓(xùn)練的進(jìn)展

  • 使用TensorBoard

  • 使模型的預(yù)測(cè)可視化

  • 使用Dict作為數(shù)據(jù)集和模型的返回值

  • 檢測(cè)異常和解決數(shù)值的不穩(wěn)定性

  • 免責(zé)聲明:在下一節(jié)中,我將引用一些源代碼。大多數(shù)都是為[Catalyst](https://github.com/catalysts -team/catalyst)框架(20.08版)定制的,可以在pytorch-toolbelt中使用。

    不要重復(fù)造輪子

    建議1 — 利用PyTorch生態(tài)系統(tǒng)的高級(jí)訓(xùn)練框架

    PyTorch在從頭開始編寫訓(xùn)練循環(huán)時(shí)提供了極佳的靈活性和自由度。理論上,這為編寫任何訓(xùn)練邏輯提供了無限可能。在實(shí)踐中,你很少會(huì)為訓(xùn)練CycleGAN、distilling BERT或3D物體檢測(cè)從頭開始實(shí)現(xiàn)編寫訓(xùn)練循環(huán)。

    從頭編寫一個(gè)完整的訓(xùn)練循環(huán)是學(xué)習(xí)PyTorch基本原理的一個(gè)很好的方法。不過,我強(qiáng)烈建議你在掌握了一些知識(shí)之后,轉(zhuǎn)向高級(jí)框架。有很多選擇:Catalyst, PyTorch-Lightning, Fast.AI, Ignite,以及其他。高級(jí)框架通過以下方式節(jié)省你的時(shí)間:

    • 提供經(jīng)過良好測(cè)試的訓(xùn)練循環(huán)

    • 支持配置文件

    • 支持多gpu和分布式訓(xùn)練

    • 管理檢查點(diǎn)/實(shí)驗(yàn)

    • 自動(dòng)記錄訓(xùn)練進(jìn)度

    從這些高級(jí)庫(kù)中獲得最大效果需要一些時(shí)間。然而,這種一次性的投資從長(zhǎng)期來看是有回報(bào)的。

    優(yōu)點(diǎn)

    • 訓(xùn)練pipeline變得更小 —— 代碼越少 —— 出錯(cuò)的機(jī)會(huì)就越少。

    • 易于進(jìn)行實(shí)驗(yàn)管理。

    • 簡(jiǎn)化分布式和混合精度訓(xùn)練。

    缺點(diǎn)

    • 通常,當(dāng)使用一個(gè)高級(jí)框架時(shí),我們必須在框架特定的設(shè)計(jì)原則和范例中編寫代碼。

    • 時(shí)間投資,學(xué)習(xí)額外的框架需要時(shí)間。

    給我看指標(biāo)

    建議2 —— 在訓(xùn)練期間查看其他指標(biāo)

    幾乎每一個(gè)用于在MNIST或CIFAR甚至ImageNet中對(duì)圖像進(jìn)行分類的快速啟動(dòng)示例項(xiàng)目都有一個(gè)共同點(diǎn) —— 它們?cè)谟?xùn)練期間和訓(xùn)練之后都報(bào)告了一組最精簡(jiǎn)的度量標(biāo)準(zhǔn)。通常情況下,包括Top-1和Top-5準(zhǔn)確度、錯(cuò)誤率、訓(xùn)練/驗(yàn)證損失,僅此而已。雖然這些指標(biāo)是必要的,但它只是冰山一角!

    現(xiàn)代圖像分類模型有數(shù)千萬個(gè)參數(shù)。你想只使用一個(gè)標(biāo)量值來計(jì)算它嗎?

    Top-1準(zhǔn)確率最好的CNN分類模型在泛化方面可能不是最好的。根據(jù)你的領(lǐng)域和需求,你可能希望保存具有最 false-positive/false-negative的模型,或者具有最高平均精度的模型。

    讓我給你一些建議,在訓(xùn)練過程中你可以記錄哪些數(shù)據(jù):

    • Grad-CAM heat-map —— 看看圖像的哪個(gè)部分對(duì)某一特定類的貢獻(xiàn)最大。

    可視化Grad-CAM heat-maps有助于識(shí)別模型是否基于真實(shí)病理或圖像偽影做出預(yù)測(cè)
    • Confusion Matrix — 顯示了對(duì)你的模型來說哪兩個(gè)類最具挑戰(zhàn)性。

    混淆矩陣揭示了一個(gè)模型對(duì)特定類型進(jìn)行不正確分類的頻率
    • Distribution of predictions — 讓你了解最優(yōu)決策邊界。

    該模型的negative和positive 預(yù)測(cè)的分布表明,有很大一部分?jǐn)?shù)據(jù)模型無法確定地分類
    • Minimum/Average/Maximum 跨所有層的梯度值,允許識(shí)別是否在模型中存在消失/爆炸的梯度或初始化不好的層。

    使用面板工具來監(jiān)控訓(xùn)練

    建議3 — 使用TensorBoard或任何其他解決方案來監(jiān)控訓(xùn)練進(jìn)度

    在訓(xùn)練模型時(shí),你可能最不愿意做的事情就是查看控制臺(tái)輸出。通過一個(gè)功能強(qiáng)大的儀表板,你可以在其中一次看到所有的度量標(biāo)準(zhǔn),這是檢查訓(xùn)練結(jié)果的更有效的方法。

    Tensorboard可以快速的檢查和比較你運(yùn)行的訓(xùn)練

    對(duì)于少量實(shí)驗(yàn)和非分布式環(huán)境,TensorBoard是一個(gè)黃金標(biāo)準(zhǔn)。自版本1.3以來,PyTorch就完全支持它,并提供了一組豐富的特性來管理試用版。還有一些更先進(jìn)的基于云的解決方案,比如Weights&Biases、[Alchemy](https://github.com/catalyst team/alchemy)和TensorBoard.dev,這些解決方案使得在多臺(tái)機(jī)器上監(jiān)控和比較訓(xùn)練變得更容易。

    當(dāng)使用Tensorboard時(shí),我通常記錄這樣一組指標(biāo):

    • 學(xué)習(xí)率和其他可能改變的優(yōu)化參數(shù)(動(dòng)量,重量衰減,等等)

    • 用于數(shù)據(jù)預(yù)處理和模型內(nèi)部的時(shí)間

    • 貫穿訓(xùn)練和驗(yàn)證的損失(每個(gè)batch和每個(gè)epoch的平均值)

    • 跨訓(xùn)練和驗(yàn)證的度量

    • 訓(xùn)練session的超參數(shù)最終值

    • 混淆矩陣,Precision-Recall曲線,AUC(如果適用)

    • 模型預(yù)測(cè)的可視化(如適用)

    一圖勝千言

    直觀地觀察模型的預(yù)測(cè)是非常重要的。有時(shí)訓(xùn)練數(shù)據(jù)是有噪聲的;有時(shí),模型會(huì)過擬合圖像的偽影。通過可視化最好的和最差的batch(基于損失或你感興趣的度量),你可以對(duì)模型執(zhí)行良好和糟糕的情況進(jìn)行有價(jià)值的洞察。

    建議5 — 可視化每個(gè)epoch中最好和最壞的batch。它可能會(huì)給你寶貴的見解。

    Catalyst用戶提示:這里是使用可視化回調(diào)的示例:https://github.com/BloodAxe/Catalyst-Inria-Segmentation-Example/blob/master/fit_predict.py#L258

    例如,在全球小麥檢測(cè)挑戰(zhàn)中,我們需要在圖像上檢測(cè)小麥頭。通過可視化最佳batch的圖片(基于mAP度量),我們看到模型在尋找小物體方面做得近乎完美。

    最佳模型預(yù)測(cè)的可視化顯示了模型在小物體上的良好表現(xiàn)

    相反,當(dāng)我們查看最差一批的第一個(gè)樣本時(shí),我們看到模型很難對(duì)大物體做出準(zhǔn)確的預(yù)測(cè)。可視化分析為任何數(shù)據(jù)科學(xué)家都提供了寶貴的見解。

    最差模型預(yù)測(cè)的可視化揭示了模型在大物體上的性能很差

    查看最差的batch也有助于發(fā)現(xiàn)數(shù)據(jù)標(biāo)記中的錯(cuò)誤。通常情況下,貼錯(cuò)標(biāo)簽的樣本損失更大,因此會(huì)成為最差的batch。通過在每個(gè)epoch對(duì)最糟糕的batch做一個(gè)視覺檢查,你可以消除這些錯(cuò)誤:

    標(biāo)記錯(cuò)誤的例子。綠色像素表示true positives,紅色像素表示false negative。在這個(gè)示例中,ground-truth掩模標(biāo)在了它實(shí)際上不存在的位置上。

    使用Dict作為Dataset和Model的返回值

    建議4 — 如果你的模型返回一個(gè)以上的值,使用Dict來返回結(jié)果,不要使用tuple

    在復(fù)雜的模型中,返回多個(gè)輸出并不少見。例如,目標(biāo)檢測(cè)模型通常返回邊界框及其標(biāo)簽,在圖像分割CNN-s中,我們經(jīng)常返回中間層的mask進(jìn)行深度監(jiān)督,多任務(wù)學(xué)習(xí)最近也很常用。

    在許多開源實(shí)現(xiàn)中,我經(jīng)常看到這樣的東西:

    #?Bad?practice,?don't?return?tuple class?RetinaNet(nn.Module):...def?forward(self,?image):x?=?self.encoder(image)x?=?self.decoder(x)bboxes,?scores?=?self.head(x)return?bboxes,?scores...

    對(duì)于作者來說,我認(rèn)為這是一種非常糟糕的從模型返回結(jié)果的方法。下面是我推薦的替代方法:

    class?RetinaNet(nn.Module):RETINA_NET_OUTPUT_BBOXES?=?"bboxes"RETINA_NET_OUTPUT_SCORES?=?"scores"...def?forward(self,?image):x?=?self.encoder(image)x?=?self.decoder(x)bboxes,?scores?=?self.head(x)return?{?RETINA_NET_OUTPUT_BBOXES:?bboxes,?RETINA_NET_OUTPUT_SCORES:?scores?}...

    這個(gè)建議在某種程度上與“The Zen of Python”的設(shè)定產(chǎn)生了共鳴 —— “明確的比含蓄的更好”。遵循這一規(guī)則將使你的代碼更清晰、更容易維護(hù)。

    那么為什么我認(rèn)為第二種選擇更好呢?有幾個(gè)原因:

    • 返回值有一個(gè)顯式的名稱與它關(guān)聯(lián)。你不需要記住元組中元素的確切順序。

    • 如果你需要訪問返回的字典的一個(gè)特定元素,你可以通過它的名字來訪問。

    • 從模型中添加新的輸出不會(huì)破壞代碼。

    使用Dict,你甚至可以更改模型的行為,以按需返回額外的輸出。例如,這里有一個(gè)簡(jiǎn)短的片段,演示了如何返回多個(gè)“主”輸出和兩個(gè)“輔助”輸出來進(jìn)行度量學(xué)習(xí):

    #?https://github.com/BloodAxe/Kaggle-2020-Alaska2/blob/master/alaska2/models/timm.py#L104def?forward(self,?**kwargs):x?=?kwargs[self.input_key]x?=?self.rgb_bn(x)x?=?self.encoder.forward_features(x)embedding?=?self.pool(x)result?=?{OUTPUT_PRED_MODIFICATION_FLAG:?self.flag_classifier(self.drop(embedding)),OUTPUT_PRED_MODIFICATION_TYPE:?self.type_classifier(self.drop(embedding)),}if?self.need_embedding:result[OUTPUT_PRED_EMBEDDING]?=?embeddingif?self.arc_margin?is?not?None:result[OUTPUT_PRED_EMBEDDING_ARC_MARGIN]?=?self.arc_margin(embedding)return?result

    同樣的建議也適用于Dataset類。對(duì)于Cifar-10玩具示例,可以將圖像及其對(duì)應(yīng)的標(biāo)簽作為元組返回。但當(dāng)處理多任務(wù)或多輸入模型,你想從數(shù)據(jù)集返回Dict類型的樣本:

    #?https://github.com/BloodAxe/Kaggle-2020-Alaska2/blob/master/alaska2/dataset.py#L373 class?TrainingValidationDataset(Dataset):def?__init__(self,images:?Union[List,?np.ndarray],targets:?Optional[Union[List,?np.ndarray]],quality:?Union[List,?np.ndarray],bits:?Optional[Union[List,?np.ndarray]],transform:?Union[A.Compose,?A.BasicTransform],features:?List[str],):""":param?obliterate?-?Augmentation?that?destroys?embedding."""if?targets?is?not?None:if?len(images)?!=?len(targets):raise?ValueError(f"Size?of?images?and?targets?does?not?match:?{len(images)}?{len(targets)}")self.images?=?imagesself.targets?=?targetsself.transform?=?transformself.features?=?featuresself.quality?=?qualityself.bits?=?bitsdef?__len__(self):return?len(self.images)def?__repr__(self):return?f"TrainingValidationDataset(len={len(self)},?targets_hist={np.bincount(self.targets)},?qf={np.bincount(self.quality)},?features={self.features})"def?__getitem__(self,?index):image_fname?=?self.images[index]try:image?=?cv2.imread(image_fname)if?image?is?None:raise?FileNotFoundError(image_fname)except?Exception?as?e:print("Cannot?read?image?",?image_fname,?"at?index",?index)print(e)qf?=?self.quality[index]data?=?{}data["image"]?=?imagedata.update(compute_features(image,?image_fname,?self.features))data?=?self.transform(**data)sample?=?{INPUT_IMAGE_ID_KEY:?os.path.basename(self.images[index]),?INPUT_IMAGE_QF_KEY:?int(qf)}if?self.bits?is?not?None:#?OKsample[INPUT_TRUE_PAYLOAD_BITS]?=?torch.tensor(self.bits[index],?dtype=torch.float32)if?self.targets?is?not?None:target?=?int(self.targets[index])sample[INPUT_TRUE_MODIFICATION_TYPE]?=?targetsample[INPUT_TRUE_MODIFICATION_FLAG]?=?torch.tensor([target?>?0]).float()for?key,?value?in?data.items():if?key?in?self.features:sample[key]?=?tensor_from_rgb_image(value)return?sample

    當(dāng)你的代碼中有Dictionaries時(shí),你可以在任何地方使用名稱常量引用輸入/輸出。遵循這條規(guī)則將使你的訓(xùn)練管道非常清晰和容易遵循:

    #?https://github.com/BloodAxe/Kaggle-2020-Alaska2callbacks?+=?[CriterionCallback(input_key=INPUT_TRUE_MODIFICATION_FLAG,output_key=OUTPUT_PRED_MODIFICATION_FLAG,criterion_key="bce"),CriterionCallback(input_key=INPUT_TRUE_MODIFICATION_TYPE,output_key=OUTPUT_PRED_MODIFICATION_TYPE,criterion_key="ce"),CompetitionMetricCallback(input_key=INPUT_TRUE_MODIFICATION_FLAG,output_key=OUTPUT_PRED_MODIFICATION_FLAG,prefix="auc",output_activation=binary_logits_to_probas,class_names=class_names,),OutputDistributionCallback(input_key=INPUT_TRUE_MODIFICATION_FLAG,output_key=OUTPUT_PRED_MODIFICATION_FLAG,output_activation=binary_logits_to_probas,prefix="distribution/binary",),BestMetricCheckpointCallback(target_metric="auc",?target_metric_minimize=False,?save_n_best=3), ]

    在訓(xùn)練中檢測(cè)異常

    就像人類可以閱讀含有許多錯(cuò)誤的文本一樣,深度學(xué)習(xí)模型也可以在訓(xùn)練過程中出現(xiàn)錯(cuò)誤時(shí)學(xué)習(xí)“一些合理的東西”。作為一名開發(fā)人員,你要負(fù)責(zé)搜索異常并對(duì)其表現(xiàn)進(jìn)行推理。

    建議5 — 在訓(xùn)練期間使用 torch.autograd.detect_anomaly()查找算術(shù)異常

    如果你在訓(xùn)練過程中在損失/度量中看到NaNs或Inf,你的腦海中就會(huì)響起一個(gè)警報(bào)。它是你的管道中有問題的指示器。通常情況下,它可能由以下原因引起:

    • 模型或特定層的初始化不好(你可以通過觀察梯度大小來檢查哪些層)

    • 數(shù)學(xué)上不正確的運(yùn)算(負(fù)數(shù)的torch.sqrt(),非正數(shù)的torch.log(),等等)

    • 不當(dāng)使用torch.mean()和torch.sum() 的reduction(zero-sized張量上的均值會(huì)得到nan,大張量上的sum容易導(dǎo)致溢出)

    • 在loss中使用x.sigmoid()(如果你需要在loss函數(shù)中使用概率,更好的方法是x.sigmoid().clamp(eps,1-eps )以防止梯度消失)

    • 在Adam-like的優(yōu)化器中的低epsilon值

    • 在使用fp16的訓(xùn)練的時(shí)候沒有使用動(dòng)態(tài)損失縮放

    為了找到你代碼中第一次出現(xiàn)Nan/Inf的確切位置,PyTorch提供了一個(gè)簡(jiǎn)單易用的方法torch. autograde .detect_anomaly()

    import?torchdef?main():torch.autograd.detect_anomaly()...#?Rest?of?the?training?code#?OR class?MyNumericallyUnstableLoss(nn.Module):def?forward(self,?input,?target):with?torch.autograd.set_detect_anomaly(True):loss?=?input?*?targetreturn?loss

    將其用于調(diào)試目的,否則就禁用它,異常檢測(cè)會(huì)帶來計(jì)算開銷,并將訓(xùn)練速度降低10-15% 。

    —END—

    英文原文:https://towardsdatascience.com/efficient-pytorch-supercharging-training-pipeline-19a26265adae

    往期精彩回顧適合初學(xué)者入門人工智能的路線及資料下載機(jī)器學(xué)習(xí)及深度學(xué)習(xí)筆記等資料打印機(jī)器學(xué)習(xí)在線手冊(cè)深度學(xué)習(xí)筆記專輯《統(tǒng)計(jì)學(xué)習(xí)方法》的代碼復(fù)現(xiàn)專輯 AI基礎(chǔ)下載機(jī)器學(xué)習(xí)的數(shù)學(xué)基礎(chǔ)專輯獲取一折本站知識(shí)星球優(yōu)惠券,復(fù)制鏈接直接打開:https://t.zsxq.com/662nyZF本站qq群1003271085。加入微信群請(qǐng)掃碼進(jìn)群(如果是博士或者準(zhǔn)備讀博士請(qǐng)說明): 與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

    總結(jié)

    以上是生活随笔為你收集整理的【深度学习】高效使用Pytorch的6个技巧:为你的训练Pipeline提供强大动力的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。