Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如果我只对一些示例执行forward,计算图什么时候会被释放?_Python_Backpropagation_Pytorch - Fatal编程技术网

Python 如果我只对一些示例执行forward,计算图什么时候会被释放?

Python 如果我只对一些示例执行forward,计算图什么时候会被释放?,python,backpropagation,pytorch,Python,Backpropagation,Pytorch,我有一个用例,在这个用例中,我对一批中的每个样本进行转发,并且仅根据样本的模型输出的某些条件对一些样本累积损失。这是一个说明代码 for batch_idx, (data, target) in enumerate(train_loader): optimizer.zero_grad() total_loss = 0 loss_count_local = 0 for i in range(len(target)): im = Variable(d

我有一个用例,在这个用例中,我对一批中的每个样本进行转发,并且仅根据样本的模型输出的某些条件对一些样本累积损失。这是一个说明代码

for batch_idx, (data, target) in enumerate(train_loader):
    optimizer.zero_grad()
    total_loss = 0

    loss_count_local = 0
    for i in range(len(target)):
        im = Variable(data[i].unsqueeze(0).cuda())
        y = Variable(torch.FloatTensor([target[i]]).cuda())

        out = model(im)

        # if out satisfy some condtion, we will calculate loss
        # for this sample, else proceed to next sample
        if some_condition(out):
            loss = criterion(out, y)
        else:
            continue

        total_loss += loss
        loss_count_local += 1

        if loss_count_local == 32 or i == (len(target)-1):
            total_loss /= loss_count_local
            total_loss.backward()
            total_loss = 0
            loss_count_local = 0

    optimizer.step()
我的问题是,正如我对所有样本所做的那样,我对所有样本都进行了正向处理,但对一些样本只进行了反向处理。什么时候将释放那些不造成损失的样本的图形?只有在for循环结束后,还是在我为下一个示例转发之后,这些图才会被释放?我在这里有点困惑


同样,对于那些确实导致
总损失的样本,在我们执行
总损失.backward()
之后,它们的图形将立即被释放。是这样吗?

让我们从PyTorch如何释放内存的一般性讨论开始:

首先,我们应该强调PyTorch使用隐式声明的图形,该图形存储在Python对象属性中。(记住,它是Python,所以所有东西都是对象)。更具体地说,
torch.autograd.Variable
s有一个
.grad\u fn
属性。该属性的类型定义了我们拥有的计算节点的类型(例如,加法)以及该节点的输入

这一点很重要,因为Pytorch只需使用标准的python垃圾收集器(如果相当积极的话)即可释放内存。在此上下文中,这意味着(隐式声明的)计算图将保持活动状态,只要当前范围中存在对持有它们的对象的引用

这意味着,如果你对样本s_1进行某种批处理。。。s_k,计算每个节点的损失,并在最后添加损失,该累积损失将包含对每个单独损失的引用,而每个单独损失又包含对计算它的每个计算节点的引用

因此,应用到代码中的问题更多地是关于Python(或者更具体地说是它的垃圾收集器)如何处理引用,而不是关于Pytorch。由于将丢失累积到一个对象中(
total_loss
),指针将保持活动状态,因此在外部循环中重新初始化该对象之前不会释放内存

应用于您的示例,这意味着您在向前传递中创建的计算图(在
out=model(im)
)仅由
out
对象及其任何未来计算引用。因此,如果您计算损失并求和,您将保留对
out
的引用,从而保留对计算图的引用。但是,如果您不使用它,垃圾收集器应该递归地收集
和它的计算图