हमें PyTorch में zero_grad () कॉल करने की आवश्यकता क्यों है?


112

zero_grad()प्रशिक्षण के दौरान विधि को बुलाया जाना चाहिए। लेकिन प्रलेखन बहुत उपयोगी नहीं है

|  zero_grad(self)
|      Sets gradients of all model parameters to zero.

हमें इस पद्धति को कॉल करने की आवश्यकता क्यों है?

जवाबों:


144

में PyTorch, हम backpropragation करने के लिए शुरू करने क्योंकि PyTorch से पहले शून्य करने के लिए ढ़ाल निर्धारित करने की आवश्यकता ढ़ाल जम जाता है बाद में पिछड़े गुजरता पर। यह RNN को प्रशिक्षित करते समय सुविधाजनक है। इसलिए, डिफ़ॉल्ट कार्रवाई हर कॉल पर ग्रेडिएटर्स (यानी योग) को जमा करना हैloss.backward()

इस वजह से, जब आप अपना प्रशिक्षण पाश शुरू करते हैं, तो आदर्श रूप से आपको zero out the gradientsऐसा करना चाहिए ताकि आप पैरामीटर अपडेट को सही तरीके से कर सकें। ग्रेडिएंट न्यूनतम (या अधिकतम , अधिकतम उद्देश्यों के मामले में) की दिशा में इच्छित दिशा की तुलना में किसी अन्य दिशा में इंगित करेगा ।

ये रहा एक सरल उदाहरण:

import torch
from torch.autograd import Variable
import torch.optim as optim

def linear_model(x, W, b):
    return torch.matmul(x, W) + b

data, targets = ...

W = Variable(torch.randn(4, 3), requires_grad=True)
b = Variable(torch.randn(3), requires_grad=True)

optimizer = optim.Adam([W, b])

for sample, target in zip(data, targets):
    # clear out the gradients of all Variables 
    # in this optimizer (i.e. W, b)
    optimizer.zero_grad()
    output = linear_model(sample, W, b)
    loss = (output - target) ** 2
    loss.backward()
    optimizer.step()

वैकल्पिक रूप से, यदि आप एक वेनिला ढाल मूल कर रहे हैं , तो:

W = Variable(torch.randn(4, 3), requires_grad=True)
b = Variable(torch.randn(3), requires_grad=True)

for sample, target in zip(data, targets):
    # clear out the gradients of Variables 
    # (i.e. W, b)
    W.grad.data.zero_()
    b.grad.data.zero_()

    output = linear_model(sample, W, b)
    loss = (output - target) ** 2
    loss.backward()

    W -= learning_rate * W.grad.data
    b -= learning_rate * b.grad.data

नोट : ग्रेडिएंट्स का संचय (अर्थात योग ) तब होता है जब टेंसर .backward()पर बुलाया जाता हैloss


3
बहुत बहुत धन्यवाद, यह वास्तव में उपयोगी है! क्या आपको पता है कि टेंसफ्लो का व्यवहार है?
लेसर

बस सुनिश्चित करने के लिए .. यदि आप ऐसा नहीं करते हैं, तो आप एक विस्फोट ढाल समस्या में चलेंगे, है ना?
zwep

2
@zwep यदि हम ढ़ाल का संचय करते हैं, तो इसका मतलब यह नहीं है कि उनका परिमाण बढ़ जाता है: एक उदाहरण यह होगा कि यदि ग्रेडिएंट का चिह्न दिखाई दे रहा है। इसलिए यह गारंटी नहीं होगी कि आप विस्फोट की समस्या में भाग लेंगे। इसके अलावा, अगर आप सही ढंग से शून्य करते हैं, तो भी धमाकेदार ग्रेडिएंट मौजूद हैं।
टॉम रोथ

जब आप वेनिला ग्रैडिएंट वंश चलाते हैं तो क्या आपको "लीफ वैरिएबल नहीं मिलता है जो वेट को अपडेट करने की कोशिश करते समय इन-प्लेस ऑपरेशन में त्रुटि का उपयोग किया जाता है?"
MUAS

1

यदि आप त्रुटि (या हानि) को कम करने के लिए ढाल विधि का उपयोग करते हैं, तो शून्य_ग्रेड (अंतिम चरण से नुकसान के बिना लूपिंग को पुनरारंभ करना है)

यदि आप शून्य_ग्रेड () का उपयोग नहीं करते हैं तो नुकसान में कमी होगी और आवश्यकता के अनुसार वृद्धि नहीं होगी

उदाहरण के लिए यदि आप शून्य_ग्रेड () का उपयोग करते हैं तो आपको निम्नलिखित आउटपुट मिलेंगे:

model training loss is 1.5
model training loss is 1.4
model training loss is 1.3
model training loss is 1.2

यदि आप शून्य_ग्रेड () का उपयोग नहीं करते हैं, तो आपको निम्नलिखित आउटपुट मिलेंगे:

model training loss is 1.4
model training loss is 1.9
model training loss is 2
model training loss is 2.8
model training loss is 3.5
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.