我写信给due,因为我处理以下情况:在训练期间,我需要pytorch的forward函数中的for循环。下面是我的代码示例:
def forward(self, input_sinogram, sos):
[variables declaration...]
# stack = torch.zeros(batch_size, self.nb_elements * self.nb_elements,
for tx_id in range(0, self.nb_elements, self.decimation_factor):
[variables declaration...]
ima = self.netFeaturesExtractor(ima)
stack[:, id_stack, :, :] = ima
id_stack += 1
这样做,pytorch计算为每次迭代构建计算图,并填充内存。如果有太多的迭代,它会占用太多的内存。因此,我尝试了以下实现:
def forward(self, input_sinogram, sos):
[variables declaration...]
# stack = torch.zeros(batch_size, self.nb_elements * self.nb_elements,
for tx_id in range(0, self.nb_elements, self.decimation_factor):
if tx_id == self.id_no_frz:
self.auto_grad(True)
else:
self.auto_grad(False)
[variables declaration...]
ima = self.netFeaturesExtractor(ima)
stack[:, id_stack, :, :] = ima
id_stack += 1
def auto_grad(self, freeze):
""" Freeze network."""
for param in self.netFeaturesExtractor.parameters():
param.requires_grad = freeze
我的想法是为一些迭代构建一个计算图。在实践中,它不起作用,模型在几个时代后收敛。
我想知道是否有可能平均每次迭代的计算图?这样,反向传播将更快,并考虑到所有的数据。它还可以避免内存问题。我没有找到任何关于这个话题的资料。
谢谢你的帮助!
我认为对于什么是"计算图"存在一些混淆。在PyTorch中。这实际上是一个形式化在一组算子上进行推理并通过它进行反向传播的过程的概念。可以把它看作是从输入和参数到输出模型的不同结果所执行的操作流。
这个图不是保存在内存中的特定位置。相反,它是动态构建的,在每个操作之后,PyTorch都会缓存一些张量,并在这些张量节点上引入回调函数,以便稍后对它们执行梯度计算。该回调函数采用torch.Tensor.grad_fn
属性的形式。这种设计的重点是使其具有可伸缩性,并且在进行推理之前不必依赖于预先计算的图。
即使你能接触到这种图,我也不确定"图累加"。过程对你来说很清楚。请记住,此时还没有在该模型的节点上执行任何传播操作。你会用这些节点做什么?
你只能对梯度或权重本身做这样的操作:
-
梯度积累允许权重在更新这些权重和清除梯度缓存之前在几个推理迭代中积累梯度。
-
平均重量这个进入模型合奏,你的平均重量值模型跨多个培训。