自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

優(yōu)化Pytorch模型訓(xùn)練的小技巧

人工智能 深度學(xué)習(xí)
在本文中,我將描述并展示4種不同的Pytorch訓(xùn)練技巧的代碼,這些技巧是我個(gè)人發(fā)現(xiàn)的,用于改進(jìn)我的深度學(xué)習(xí)模型的訓(xùn)練。

 在本文中,我將描述并展示4種不同的Pytorch訓(xùn)練技巧的代碼,這些技巧是我個(gè)人發(fā)現(xiàn)的,用于改進(jìn)我的深度學(xué)習(xí)模型的訓(xùn)練。

[[389579]]

混合精度

在一個(gè)常規(guī)的訓(xùn)練循環(huán)中,PyTorch以32位精度存儲(chǔ)所有浮點(diǎn)數(shù)變量。對(duì)于那些在嚴(yán)格的約束下訓(xùn)練模型的人來說,這有時(shí)會(huì)導(dǎo)致他們的模型占用過多的內(nèi)存,迫使他們使用更小的模型和更小的批處理大小進(jìn)行更慢的訓(xùn)練過程。所以在模型中以16位精度存儲(chǔ)所有變量/數(shù)字可以改善并修復(fù)大部分這些問題,比如顯著減少模型的內(nèi)存消耗,加速訓(xùn)練循環(huán),同時(shí)仍然保持模型的性能/精度。

在Pytorch中將所有計(jì)算轉(zhuǎn)換為16位精度非常簡(jiǎn)單,只需要幾行代碼。這里是:

 

  1. scaler = torch.cuda.amp.GradScaler() 

上面的方法創(chuàng)建一個(gè)梯度縮放標(biāo)量,以最大程度避免使用fp16進(jìn)行運(yùn)算時(shí)的梯度下溢。

 

  1. optimizer.zero_grad() 
  2. with torch.cuda.amp.autocast(): 
  3.    output = model(input).to(device) 
  4.    loss = criterion(output, correct_answer).to(device) 
  5. scaler.scale(loss).backward() 
  6. scaler.step(optimizer) 
  7. scaler.update() 

 

當(dāng)使用loss和優(yōu)化器進(jìn)行反向傳播時(shí),您需要使用scale .scale(loss),而不是使用loss.backward()和optimizer.step()。使用scaler.step(optimizer)來更新優(yōu)化器。這允許你的標(biāo)量轉(zhuǎn)換所有的梯度,并在16位精度做所有的計(jì)算,最后用scaler.update()來更新縮放標(biāo)量以使其適應(yīng)訓(xùn)練的梯度。

當(dāng)以16位精度做所有事情時(shí),可能會(huì)有一些數(shù)值不穩(wěn)定,導(dǎo)致您可能使用的一些函數(shù)不能正常工作。只有某些操作在16位精度下才能正常工作。具體可參考官方的文檔。

進(jìn)度條

有一個(gè)進(jìn)度條來表示每個(gè)階段的訓(xùn)練完成的百分比是非常有用的。為了獲得進(jìn)度條,我們將使用tqdm庫(kù)。以下是如何下載并導(dǎo)入它:

 

  1. pip install tqdm 
  2. from tqdm import tqdm 

 

在你的訓(xùn)練和驗(yàn)證循環(huán)中,你必須這樣做:

 

  1. for index, batch in tqdm(enumerate(loader), total = len(loader), position = 0, leave = True): 

訓(xùn)練和驗(yàn)證循環(huán)添加tqdm代碼后將得到一個(gè)進(jìn)度條,它表示您的模型完成的訓(xùn)練的百分比。它應(yīng)該是這樣的:

 

優(yōu)化Pytorch模型訓(xùn)練的小技巧

 

在圖中,691代表我的模型需要完成多少批,7:28代表我的模型在691批上的總時(shí)間,1.54 it/s代表我的模型在每批上花費(fèi)的平均時(shí)間。

梯度積累

如果您遇到CUDA內(nèi)存不足的錯(cuò)誤,這意味著您已經(jīng)超出了您的計(jì)算資源。為了解決這個(gè)問題,你可以做幾件事,包括把所有東西都轉(zhuǎn)換成16位精度,減少模型的批處理大小,更換更小的模型等等。

但是有時(shí)切換到16位精度并不能完全解決問題。解決這個(gè)問題最直接的方法是減少批處理大小,但是假設(shè)您不想減少批處理大小可以使用梯度累積來模擬所需的批大小。請(qǐng)注意,CUDA內(nèi)存不足問題的另一個(gè)解決方案是簡(jiǎn)單地使用多個(gè)GPU,但這是一個(gè)很多人無法使用的選項(xiàng)。

假設(shè)你的機(jī)器/模型只能支持16的批處理大小,增加它會(huì)導(dǎo)致CUDA內(nèi)存不足錯(cuò)誤,并且您希望批處理大小為32。梯度累加的工作原理是:以16個(gè)批的規(guī)模運(yùn)行模型兩次,將計(jì)算出的每個(gè)批的梯度累加起來,最后在這兩次前向傳播和梯度累加之后執(zhí)行一個(gè)優(yōu)化步驟。

要理解梯度積累,重要的是要理解在訓(xùn)練神經(jīng)網(wǎng)絡(luò)時(shí)所做的具體功能。假設(shè)你有以下訓(xùn)練循環(huán):

 

  1. model = model.train() 
  2. for index, batch in enumerate(train_loader): 
  3.     input = batch[0].to(device) 
  4.     correct_answer = batch[1].to(device) 
  5.     optimizer.zero_grad() 
  6.     output = model(input).to(device) 
  7.     loss = criterion(output, correct_answer).to(device) 
  8.     loss.backward() 
  9.     optimizer.step() 

 

看看上面的代碼,需要記住的關(guān)鍵是loss.backward()為模型創(chuàng)建并存儲(chǔ)梯度,而optimizer.step()實(shí)際上更新權(quán)重。在如果在調(diào)用優(yōu)化器之前兩次調(diào)用loss.backward()就會(huì)對(duì)梯度進(jìn)行累加。下面是如何在PyTorch中實(shí)現(xiàn)梯度累加:

 

  1. model = model.train() 
  2. optimizer.zero_grad() 
  3. for index, batch in enumerate(train_loader): 
  4.     input = batch[0].to(device) 
  5.     correct_answer = batch[1].to(device) 
  6.     output = model(input).to(device) 
  7.     loss = criterion(output, correct_answer).to(device) 
  8.     loss.backward() 
  9.     if (index+1) % 2 == 0: 
  10.        optimizer.step() 
  11.        optimizer.zero_grad() 

 

在上面的例子中,我們的機(jī)器只能支持16批大小的批量,我們想要32批大小的批量,我們本質(zhì)上計(jì)算2批的梯度,然后更新實(shí)際權(quán)重。這導(dǎo)致有效批大小為32。

譯者注:梯度累加只是一個(gè)折中方案,經(jīng)過我們的測(cè)試,如果對(duì)梯度進(jìn)行累加,那么最后一次loss.backward()的梯度會(huì)比前幾次反向傳播的權(quán)重高,具體為什么我們也不清楚,哈。雖然有這樣的問題,但是使用這種方式進(jìn)行訓(xùn)練還是有效果的。

16位精度的梯度累加非常類似。

 

  1. model = model.train() 
  2. optimizer.zero_grad() 
  3. for index, batch in enumerate(train_loader): 
  4.     input = batch[0].to(device) 
  5.     correct_answer = batch[1].to(device) 
  6.     with torch.cuda.amp.autocast(): 
  7.          output = model(input).to(device) 
  8.          loss = criterion(output, correct_answer).to(device) 
  9.     scaler.scale(loss).backward() 
  10.     if (index+1) % 2 == 0: 
  11.        scaler.step(optimizer) 
  12.        scaler.update() 
  13.        optimizer.zero_grad() 

 

結(jié)果評(píng)估

在大多數(shù)機(jī)器學(xué)習(xí)項(xiàng)目中,人們傾向于手動(dòng)計(jì)算用于評(píng)估的指標(biāo)。盡管計(jì)算準(zhǔn)確率、精度、召回率和F1等指標(biāo)并不困難,但在某些情況下,您可能希望擁有這些指標(biāo)的某些變體,如加權(quán)精度、召回率和F1。計(jì)算這些可能需要更多的工作,如果你的實(shí)現(xiàn)可能不正確、高效、快速且無錯(cuò)誤地計(jì)算所有這些指標(biāo),可以使用sklearns classification_report庫(kù)。這是一個(gè)專門為計(jì)算這些指標(biāo)而設(shè)計(jì)的庫(kù)。

 

  1. from sklearn.metrics import classification_report 
  2. y_pred = [0, 1, 0, 0, 1] 
  3. y_correct = [1, 1, 0, 1, 1]print(classification_report(y_correct, y_pred)) 

 

上面的代碼用于二進(jìn)制分類。你可以為更多的目的配置這個(gè)函數(shù)。第一個(gè)列表表示模型的預(yù)測(cè),第二個(gè)列表表示正確數(shù)值。上面的代碼將輸出:

 

優(yōu)化Pytorch模型訓(xùn)練的小技巧

 

結(jié)論

在這篇文章中,我討論了4種pytorch中優(yōu)化深度神經(jīng)網(wǎng)絡(luò)訓(xùn)練的方法。16位精度減少內(nèi)存消耗,梯度積累可以通過模擬使用更大的批大小,tqdm進(jìn)度條和sklearns的classification_report兩個(gè)方便的庫(kù),可以輕松地跟蹤模型的訓(xùn)練和評(píng)估模型的性能。就我個(gè)人而言,我總是用上面所有的訓(xùn)練技巧來訓(xùn)練我的神經(jīng)網(wǎng)絡(luò),并且在必要的時(shí)候我使用梯度積累。

最后,如果你使用的是pytorch或者是pytorch的初學(xué)者,可以使用這個(gè)庫(kù):

github/deephub-ai/torch-handle

他會(huì)對(duì)你有很大的幫助。

責(zé)任編輯:華軒 來源: 今日頭條
相關(guān)推薦

2024-07-25 08:25:35

2023-12-29 14:13:41

PyTorch模型開發(fā)

2020-11-20 10:40:20

PyTorch神經(jīng)網(wǎng)絡(luò)代碼

2021-01-27 10:46:07

Pytorch深度學(xué)習(xí)模型訓(xùn)練

2009-06-18 11:12:42

Hibernate S優(yōu)化

2015-09-15 08:30:23

Android代碼優(yōu)化

2022-07-04 08:51:43

條件語句JavaScript

2022-11-24 10:34:05

CSS前端

2021-05-07 16:02:54

Python代碼優(yōu)化

2021-06-16 10:50:16

Python代碼優(yōu)化

2022-03-10 08:01:06

CSS技巧選擇器

2021-11-10 18:52:42

SQL技巧優(yōu)化

2024-06-21 08:21:44

2024-10-14 08:19:15

2011-05-10 17:06:05

SEO

2015-09-16 14:47:14

Android性能優(yōu)化代碼

2021-07-02 09:45:13

Python優(yōu)化代碼

2022-05-24 14:07:53

OpenFeignSpring開源

2021-09-06 10:25:27

Python代碼優(yōu)化

2024-10-28 08:34:06

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)