如何在PyTorch中使用多重处理?

时间:2019-05-16 18:48:58

标签: pytorch

我正在尝试使用具有复杂损失功能的PyTorch。为了加速代码,我希望我可以使用PyTorch多处理程序包。

第一次试用,我将10x1的功能放入NN并获得10x4的输出。

之后,我想将10x4参数传递给函数进行一些计算。 (将来的计算将很复杂。)

计算后,该函数将总共返回一个10x1数组。该数组将设置为NN_energy并计算损失函数。

此外,我还想知道是否还有另一种方法来创建可向后存储的数组来存储NN_energy数组,而不是使用

NN_energy = net(Data_in)[0:10,0]

非常感谢。

完整代码:

import torch
import numpy as np
from torch.autograd import Variable 
from torch import multiprocessing

def func(msg,BOP):
    ans = (BOP[msg][0]+BOP[msg][1]/BOP[msg][2])*BOP[msg][3]
    return ans

class Net(torch.nn.Module):
    def __init__(self, n_feature, n_hidden_1, n_hidden_2, n_output):
        super(Net, self).__init__()
        self.hidden_1 = torch.nn.Linear(n_feature , n_hidden_1)  # hidden layer
        self.hidden_2 = torch.nn.Linear(n_hidden_1, n_hidden_2)  # hidden layer
        self.predict  = torch.nn.Linear(n_hidden_2, n_output  )  # output layer

    def forward(self, x):
        x = torch.tanh(self.hidden_1(x))      # activation function for hidden layer
        x = torch.tanh(self.hidden_2(x))      # activation function for hidden layer
        x = self.predict(x)                   # linear output
        return x

if __name__ == '__main__': # apply_async
    Data_in      = Variable( torch.from_numpy( np.asarray(list(range( 0,10))).reshape(10,1) ).float() )
    Ground_truth = Variable( torch.from_numpy( np.asarray(list(range(20,30))).reshape(10,1) ).float() )

    net = Net( n_feature=1 , n_hidden_1=15 , n_hidden_2=15 , n_output=4 )     # define the network
    optimizer = torch.optim.Rprop( net.parameters() )
    loss_func = torch.nn.MSELoss()  # this is for regression mean squared loss 
    NN_output = net(Data_in)   
    args = range(0,10)
    pool = multiprocessing.Pool()
    return_data = pool.map( func, zip(args, NN_output) )
    pool.close()
    pool.join()

    NN_energy = net(Data_in)[0:10,0]  
    for i in range(0,10):
        NN_energy[i] = return_data[i]

    loss = torch.sqrt( loss_func( NN_energy , Ground_truth ) )     # must be (1. nn output, 2. target) 
    print(loss)

错误消息:

  

文件   “ C:\ ProgramData \ Anaconda3 \ lib \ site-packages \ torch \ multiprocessing \ reductions.py”,   第126行,在reduce_tensor中       引发RuntimeError(“怯ward地拒绝序列化require_grad的非叶张量,”

     

RuntimeError:怯ward地拒绝序列化非叶张量   require_grad,因为autograd不支持穿越过程   边界。如果您只想传输数据,请在   序列化之前的张量(例如,将其放在队列中)。

1 个答案:

答案 0 :(得分:-1)

首先,由于很长一段时间不推荐使用Torch Variable API,只是不要使用它。

接下来,torch.from_numpy( np.asarray(list(range( 0,10))).reshape(10,1) ).float()在许多级别上都是错误的:np.asarray中的list是无用的,因为无论如何都会执行复制,并且np.arraylist用作通过设计输入。然后,np.arange可用于将范围返回为numpy数组,并且在Torch上也可用。接下来,为reshape指定两个维度都是没有用的,并且容易出错,您可以简单地执行reshape((-1, 1))甚至更好的unsqueeze(-1)。 这是简化的表达式torch.arange(10, dtype=torch.float32, requires_grad=True).unsqueeze(-1)

如果可以使用批处理,则使用多处理池是一种不好的做法。它将更加高效和易读。实际上,并行执行N个小代数运算总是较慢,而单个代数运算较大,在GPU上甚至更多。更重要的是,多重处理不支持计算梯度,因此会得到错误。但是,这在一定程度上是正确的,因为从1.6.0开始它就支持cpu上的张量。看看official release changelog

您能否发布一个更具代表性的示例,说明哪种func方法可以确保您确实需要它?

NB:Pytorch现在提供了您正在寻找的分布式自动分级功能,此功能自1.6.0起已在Beta中提供。看看official documentation