用pytorch计算预测函数的损失

2024-04-27 18:45:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个卷积神经网络,可以预测3个量:Ux,Uy和p。它们是x速度,y速度和压力场。它们都是[100,60]大小的2D数组,我的批量大小是10

我想通过计算预测速度的旋度和目标速度的旋度来计算损耗和更新网络。我有一个函数可以这样做:v=curl(Ux_pred,Uy_pred)。给定预测的Ux和Uy,我想通过将其与我拥有的地面真值目标进行比较来计算损耗:true\u curl=curl(Ux\u true,Uy\u true)-我已经计算了真值curl,并将其添加到我的Y数据中,作为第四个通道

但是,我希望我的网络只预测Ux、Uy和p。我希望我的NN参数根据卷曲的丢失进行更新,以提高Ux和Uy的准确性。旋度的损失必须以Ux和Uy为单位。我一直在尝试使用Pytorch autograd来实现这一点,并且已经阅读了许多类似的问题,但我就是无法让它发挥作用。这是我目前的代码:

        print("pred_Curl shape:", np.shape(pred_curl))
        print("pred_Ux shape:", np.shape(pred[:,0,:,:]))
        print("pred_Uy shape:", np.shape(pred[:,1,:,:]))
        true_curl = torch.from_numpy(y[:,3,:,:]) # not sure where to use the true curl?

        pred_curl = Variable(pred_curl, requires_grad=True)
        
        pred_ux = pred[:,0,:,:]
        pred_uy = pred[:,1,:,:]

        pred_ux = Variable(pred_ux, requires_grad=True)
        pred_uy = Variable(pred_uy, requires_grad=True)

        grad_tensor = torch.autograd.grad(outputs=pred_curl, inputs=(pred_ux, pred_uy), 
                       grad_outputs=torch.ones_like(pred_curl), 
                       retain_graph=True,create_graph=True)

        loss = torch.sum(grad_tensor)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

它具有以下输出:

pred_Curl shape: torch.Size([10, 100, 60])
pred_Ux shape: torch.Size([10, 100, 60])
pred_Uy shape: torch.Size([10, 100, 60])

RuntimeError: One of the differentiated Tensors appears to not have been used in the graph. 
Set allow_unused=True if this is the desired behavior.

任何帮助都将不胜感激

编辑:这是我的卷曲函数:

    def discrete_curl(self,x,y,new_arr):
            for m in range(100):
                for n in range(60):
                    if n <= 58:
                        if m <= 98:
                            if x[m,n] != 0 and y[m,n] != 0:
                                new_arr[m,n] = ((y[m+1,n] - y[m-1,n]) / 2*1) - ((x[m,n+1] - x[m,n-1]) / 2*1)
            return new_arr 

其中x和y是Ux ad Uy,new_arr是旋度输出


Tags: thetrueiftorchcurl速度shapepred
1条回答
网友
1楼 · 发布于 2024-04-27 18:45:53

您可以尝试以下方法:

def discrete_curl(self, pred):
        new_arr = torch.zeros((pred.shape[0],100,60))
        for pred_idx in range(pred.shape[0]):
            for m in range(100):
                for n in range(60):
                    if n <= 58:
                        if m <= 98:
                            if pred[pred_idx,0,m,n] != 0 and pred[pred_idx,1,m,n] != 0:
                                new_arr[pred_idx,m,n] = ((pred[pred_idx,1,m+1,n] - pred[pred_idx,1,m-1,n]) / 2*1) - ((pred[pred_idx,0,m,n+1] - pred[pred_idx,0,m,n-1]) / 2*1)
        return new_arr 

pred_curl = discrete_curl(pred)
true_curl = torch.from_numpy(y[:,3,:,:])
loss = torch.nn.functional.mse_loss(pred_curl, true_curl)
optimizer.zero_grad()
loss.backward()
optimizer.step()

我认为旋度计算是可以优化的,但我尽量坚持你的结构

相关问题 更多 >