通过迭代变量更新进行反向传播

Backpropagation with iterative variable update

提问人:ragradoth 提问时间:9/3/2023 最后编辑:ragradoth 更新时间:9/4/2023 访问量:45

问:

大家好,我是 PyTorch 的新手,我有一个简单的训练循环

for epoch in range(num_epochs):                   
    for i,data in enumerate(training_set):       
        optimizer.zero_grad()                             
        output_layer = PIAE_model(data)
        loss = criterion(output_layer,data)
        loss.backward()                            
        optimizer.step()                          
        loss_log.append(loss.item())

模型方法如下所示

   def inverter(self,x):
        x = self.up(self.act(self.bn1(self.conv1(x))))     # convolution, batch normalization... 
        x = self.up(self.act(self.bn2(self.conv2(x))))    
        x = self.up((self.bn3(torch.abs(self.conv3(x)))))   
        return x

   def findif(self,vel_model):
       for n in range(0,self.nt):
                d2 = []
                sourceINJ = []
                
                for i in range(self.nx):  # for all the grid points                    
                    d2.append((self.p[i + 1].detach() - 2 * self.p[i].detach() + self.p[i - 1].detach()) / self.dx ** 2 ) 
                    sourceINJ.append(self.p[i].detach())

                sourceINJ[1] = sourceINJ[1] + self.q[n]
                
                self.d2pdx2 = torch.stack(d2)
                self.p = torch.stack(sourceINJ)

            
           self.p = 2 * self.p.detach() + vel_model ** 2 * self.dt * self.d2pdx2.detach()
           self.traces[n] = self.p[1]
        return self.traces
    
    def forward(self, x):
        vel_model = self.inverter(x)
        seis_model = self.findif(vel_model)
        return seis_model

在 findif 方法中,我使用 list append 来避免就地操作 d2 list 计算第二个空间导数,而 sourceINJ 则计算。 变量一开始是火炬 0 张量,在第一次迭代后成为 的函数,并且是 的函数。并且是标量 1。self.p[1] = self.p[1]+self.q[n]self.pvel_modelself.d2pdx2self.pself.dt

所以这里的问题在于这条线,以这种形式,梯度没有正确计算,我在损失中得到 NaN,并且设置 torch.autograd.set_detect_anomaly(True) 引发“函数'CudnnBatchNormBackward0'在其第 0 个输出中返回 nan 值。self.p = 2 * self.p.detach() + vel_model ** 2 * self.dt * self.d2pdx2.detach()

将公式中的加号替换为乘法可以使训练顺利进行。 去掉 和 系数 2,这样也能顺利运行。2 * self.p.detach() * vel_model ** 2 * self.dt * self.d2pdx2.detach()self.d2pdx2self.p.detach() + vel_model ** 2 * self.dt

请帮我规避这个问题。

我尝试像以前一样使用列表追加

test = []
for i in range(self.nx):
    test.append(2 * self.p[i].detach() + vel_model[i] ** 2 * self.dt * self.d2pdx2[i].detach())
self.p = torch.stack(test)

但这没有帮助,我也尝试克隆了一些张量,但没有成功。

感谢您的阅读。

PyTorch 就地 Autograd

评论


答: 暂无答案