我正在尝试使用具有复杂损失功能的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不支持穿越过程 边界。如果您只想传输数据,请在 序列化之前的张量(例如,将其放在队列中)。
答案 0 :(得分:-1)
首先,由于很长一段时间不推荐使用Torch Variable
API,只是不要使用它。
接下来,torch.from_numpy( np.asarray(list(range( 0,10))).reshape(10,1) ).float()
在许多级别上都是错误的:np.asarray
中的list
是无用的,因为无论如何都会执行复制,并且np.array
将list
用作通过设计输入。然后,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。