提问人:ragradoth 提问时间:9/3/2023 最后编辑:ragradoth 更新时间:9/4/2023 访问量:45
通过迭代变量更新进行反向传播
Backpropagation with iterative variable update
问:
大家好,我是 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.p
vel_model
self.d2pdx2
self.p
self.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.d2pdx2
self.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)
但这没有帮助,我也尝试克隆了一些张量,但没有成功。
感谢您的阅读。
答: 暂无答案
评论