繁体   English   中英

使用 pytorch 计算预测的 function 的损失

[英]Computing the loss of a function of predictions with pytorch

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

我想通过计算预测速度的 CURL 和目标速度的 CURL 来计算损失并更新网络。 我有一个 function 这样做:v = curl(Ux_pred,Uy_pred)。 鉴于预测的 Ux 和 Uy,我想通过将其与我拥有的地面实况目标进行比较来计算损失:true_curl = curl(Ux_true, Uy_true) - 我已经计算出真正的 curl 并将其添加到我的 Y 数据中,如第四个频道。

但是,我希望我的网络只预测 Ux、Uy 和 P。我希望我的 NN 参数根据 curls 的 LOSS 进行更新,以提高 Ux 和 Uy 的准确性。 curl 的损耗必须以 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()

这有以下 output:

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.

任何帮助,将不胜感激!

编辑:这是我的 curl function:

    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 和 Uy,new_arr 是 curl output。

你可以尝试这样的事情:

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()

我认为 curl 计算可以优化,但我尽量坚持你的结构。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM