<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Pytorch基礎 | eval()的用法比較

          共 4401字,需瀏覽 9分鐘

           ·

          2021-04-24 22:07

          點擊上方機器學習與生成對抗網絡”,關注星標

          獲取有趣、好玩的前沿干貨!


          作者:知乎 初識CV
          https://www.zhihu.com/people/AI_team-WSF

          01

          model.train()和model.eval()用法和區(qū)別

          1.1 model.train()

          model.train()的作用是啟用 Batch Normalization 和 Dropout。
          如果模型中有BN層(Batch Normalization)和Dropout,需要在訓練時添加model.train()。model.train()是保證BN層能夠用到每一批數據的均值和方差。對于Dropout,model.train()是隨機取一部分網絡連接來訓練更新參數。

          1.2 model.eval()

          model.eval()的作用是不啟用 Batch Normalization 和 Dropout。
          如果模型中有BN層(Batch Normalization)和Dropout,在測試時添加model.eval()。model.eval()是保證BN層能夠用全部訓練數據的均值和方差,即測試過程中要保證BN層的均值和方差不變。對于Dropout,model.eval()是利用到了所有網絡連接,即不進行隨機舍棄神經元。
          訓練完train樣本后,生成的模型model要用來測試樣本。在model(test)之前,需要加上model.eval(),否則的話,有輸入數據,即使不訓練,它也會改變權值。這是model中含有BN層和Dropout所帶來的的性質。
          在做one classification的時候,訓練集和測試集的樣本分布是不一樣的,尤其需要注意這一點。

          1.3 分析原因

          使用PyTorch進行訓練和測試時一定注意要把實例化的model指定train/eval。model.eval()時,框架會自動把BN和Dropout固定住,不會取平均,而是用訓練好的值,不然的話,一旦test的batch_size過小,很容易就會被BN層導致生成圖片顏色失真極大!?。。。?!
          # 定義一個網絡class Net(nn.Module):    def __init__(self, l1=120, l2=84):        super(Net, self).__init__()        self.conv1 = nn.Conv2d(3, 6, 5)        self.pool = nn.MaxPool2d(2, 2)        self.conv2 = nn.Conv2d(6, 16, 5)        self.fc1 = nn.Linear(16 * 5 * 5, l1)        self.fc2 = nn.Linear(l1, l2)        self.fc3 = nn.Linear(l2, 10)
          def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = x.view(-1, 16 * 5 * 5) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x
          # 實例化這個網絡 Model = Net()
          # 訓練模式使用.train() Model.train(mode=True)
          # 測試模型使用.eval() Model.eval()
          為什么PyTorch會關注我們是訓練還是評估模型?最大的原因是dropout和BN層(以dropout為例)。這項技術在訓練中隨機去除神經元。
          dropout
          想象一下,如果右邊被刪除的神經元(叉號)是唯一促成正確結果的神經元。一旦我們移除了被刪除的神經元,它就迫使其他神經元訓練和學習如何在沒有被刪除神經元的情況下保持準確。這種dropout提高了最終測試的性能,但它對訓練期間的性能產生了負面影響,因為網絡是不全的。
          下面我們看一個我們寫代碼的時候常遇見的錯誤寫法:
          在這個特定的例子中,似乎每50次迭代就會降低準確度。
          如果我們檢查一下代碼, 我們看到確實在train函數中設置了訓練模式。
          def train(model, optimizer, epoch, train_loader, validation_loader):    model.train() # ???????????? 錯誤的位置    for batch_idx, (data, target) in experiment.batch_loop(iterable=train_loader):      # model.train() # 正確的位置,保證每一個batch都能進入model.train()的模式        data, target = Variable(data), Variable(target)        # Inference        output = model(data)        loss_t = F.nll_loss(output, target)        # The iconic grad-back-step trio        optimizer.zero_grad()        loss_t.backward()        optimizer.step()        if batch_idx % args.log_interval == 0:            train_loss = loss_t.item()            train_accuracy = get_correct_count(output, target) * 100.0 / len(target)            experiment.add_metric(LOSS_METRIC, train_loss)            experiment.add_metric(ACC_METRIC, train_accuracy)            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(                epoch, batch_idx, len(train_loader),                100. * batch_idx / len(train_loader), train_loss))            with experiment.validation():                val_loss, val_accuracy = test(model, validation_loader) # ????????????                experiment.add_metric(LOSS_METRIC, val_loss)                experiment.add_metric(ACC_METRIC, val_accuracy)
          這個問題不太容易注意到,在循環(huán)中我們調用了test函數。
          def test(model, test_loader):    model.eval()    # ...
          在test函數內部,我們將模式設置為eval。這意味著,如果我們在訓練過程中調用了test函數,我們就會進eval模式,直到下一次train函數被調用。這就導致了每一個epoch中只有一個batch使用了dropout ,這就導致了我們看到的性能下降。
          修復很簡單我們將model.train() 向下移動一行,讓其在訓練循環(huán)中。理想的模式設置是盡可能接近推理步驟,以避免忘記設置它。修正后,我們的訓練過程看起來更合理,沒有中間的峰值出現。

          02

          model.eval()和torch.no_grad()的區(qū)別
          在PyTorch中進行validation/test時,會使用model.eval()切換到測試模式,在該模式下:
          1. 主要用于通知dropout層和BN層在train和validation/test模式間切換:
          • 在train模式下,dropout網絡層會按照設定的參數p設置保留激活單元的概率(保留概率=p); BN層會繼續(xù)計算數據的mean和var等參數并更新。

          • 在eval模式下,dropout層會讓所有的激活單元都通過,而BN層會停止計算和更新mean和var,直接使用在訓練階段已經學出的mean和var值。

          2. 該模式不會影響各層的gradient計算行為,即gradient計算和存儲與training模式一樣,只是不進行反向傳播(back probagation)。
          而with torch.no_grad()則主要是用于停止autograd模塊的工作,以起到加速和節(jié)省顯存的作用。它的作用是將該with語句包裹起來的部分停止梯度的更新,從而節(jié)省了GPU算力和顯存,但是并不會影響dropout和BN層的行為。
          如果不在意顯存大小和計算時間的話,僅僅使用model.eval()已足夠得到正確的validation/test的結果;而with torch.no_grad()則是更進一步加速和節(jié)省gpu空間(因為不用計算和存儲梯度),從而可以更快計算,也可以跑更大的batch來測試。


          猜您喜歡:


          等你著陸!【GAN生成對抗網絡】知識星球!

          超100篇!CVPR 2020最全GAN論文梳理匯總!

          附下載 | 《Python進階》中文版

          附下載 | 經典《Think Python》中文版

          附下載 | 《Pytorch模型訓練實用教程》

          附下載 | 最新2020李沐《動手學深度學習》

          附下載 | 《可解釋的機器學習》中文版

          附下載 |《TensorFlow 2.0 深度學習算法實戰(zhàn)》

          附下載 | 超100篇!CVPR 2020最全GAN論文梳理匯總!

          附下載 |《計算機視覺中的數學方法》分享

          瀏覽 98
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  五月天婷婷精品视频 | 久久日大香蕉 | 淫荡在线| 精品人妻无码一区 | 欧美肏屄视频 |