gpt4 book ai didi

python - 在没有安装 pytorch 的情况下使用 RNN 训练模型

转载 作者:行者123 更新时间:2023-12-05 01:53:14 37 4
gpt4 key购买 nike

我用 pytorch 训练了一个 RNN 模型。由于 glibc 存在一些奇怪的依赖性问题,我需要在无法安装 pytorch 的环境中使用该模型进行预测。但是,我可以安装 numpy 和 scipy 等库。所以,我想使用经过训练的模型,使用网络定义,而不使用 pytorch。

我有模型的权重,因为我将模型及其状态字典和权重保存在 the standard way 中。 ,但我也可以仅使用 json/pickle 文件或类似文件来保存它。

我还有网络定义,它在很多方面都依赖于 pytorch。这是我的 RNN 网络定义。

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import random

torch.manual_seed(1)
random.seed(1)
device = torch.device('cpu')

class RNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size,num_layers, matching_in_out=False, batch_size=1):
super(RNN, self).__init__()
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
self.num_layers = num_layers
self.batch_size = batch_size
self.matching_in_out = matching_in_out #length of input vector matches the length of output vector
self.lstm = nn.LSTM(input_size, hidden_size,num_layers)
self.hidden2out = nn.Linear(hidden_size, output_size)
self.hidden = self.init_hidden()
def forward(self, feature_list):
feature_list=torch.tensor(feature_list)

if self.matching_in_out:
lstm_out, _ = self.lstm( feature_list.view(len( feature_list), 1, -1))
output_space = self.hidden2out(lstm_out.view(len( feature_list), -1))
output_scores = torch.sigmoid(output_space) #we'll need to check if we need this sigmoid
return output_scores #output_scores
else:
for i in range(len(feature_list)):
cur_ft_tensor=feature_list[i]#.view([1,1,self.input_size])
cur_ft_tensor=cur_ft_tensor.view([1,1,self.input_size])
lstm_out, self.hidden = self.lstm(cur_ft_tensor, self.hidden)
outs=self.hidden2out(lstm_out)
return outs
def init_hidden(self):
#return torch.rand(self.num_layers, self.batch_size, self.hidden_size)
return (torch.rand(self.num_layers, self.batch_size, self.hidden_size).to(device),
torch.rand(self.num_layers, self.batch_size, self.hidden_size).to(device))

我知道 this question ,但我愿意尽可能降低水平。我可以使用 numpy 数组而不是张量, reshape 而不是 View ,而且我不需要设备设置。

根据上面的类定义,我在这里可以看到,我只需要 torch 中的以下组件即可从 forward 函数获取输出:

  • 神经网络.LSTM
  • nn.线性
  • 手电筒.sigmoid

我想我可以很容易地implement the sigmoid function using numpy .但是,我可以使用不涉及 pytorch 的东西来实现 nn.LSTM 和 nn.Linear 吗?另外,我将如何将状态指令中的权重用于新类?

所以,问题是,我怎样才能将这个 RNN 定义“翻译”成一个不需要 pytorch 的类,以及如何为它使用状态字典权重?或者,是否有 pytorch 的“轻量级”版本,我可以使用它来运行模型并产生结果?

编辑

我认为为 nn.LSTMnn.linear 添加 numpy/scipy 等价物可能会有用。它将帮助我们比较相同代码的 numpy 输出和 torch 输出,并为我们提供一些模块化代码/函数供我们使用。具体来说,以下的 numpy 等价物会很棒:

rnn = nn.LSTM(10, 20, 2)
input = torch.randn(5, 3, 10)
h0 = torch.randn(2, 3, 20)
c0 = torch.randn(2, 3, 20)
output, (hn, cn) = rnn(input, (h0, c0))

还有线性的:

m = nn.Linear(20, 30)
input = torch.randn(128, 20)
output = m(input)

最佳答案

您应该尝试使用 torch.onnx 导出模型.该页面为您提供了一个示例,您可以从中着手。

另一种方法是使用 TorchScript ,但这需要 torch 库。

这两个都可以在没有 python 的情况下运行。您可以在 C++ 应用程序中加载 torchscript https://pytorch.org/tutorials/advanced/cpp_export.html

ONNX 更具可移植性,您可以使用 C#、Java 或 Javascript 等语言 https://onnxruntime.ai/ (甚至在浏览器上)

运行示例

只需稍微修改您的示例以解决我发现的错误

注意通过跟踪任何 if/elif/else、for、while 将展开

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import random

torch.manual_seed(1)
random.seed(1)
device = torch.device('cpu')

class RNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size,num_layers, matching_in_out=False, batch_size=1):
super(RNN, self).__init__()
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
self.num_layers = num_layers
self.batch_size = batch_size
self.matching_in_out = matching_in_out #length of input vector matches the length of output vector
self.lstm = nn.LSTM(input_size, hidden_size,num_layers)
self.hidden2out = nn.Linear(hidden_size, output_size)
def forward(self, x, h0, c0):
lstm_out, (hidden_a, hidden_b) = self.lstm(x, (h0, c0))
outs=self.hidden2out(lstm_out)
return outs, (hidden_a, hidden_b)
def init_hidden(self):
#return torch.rand(self.num_layers, self.batch_size, self.hidden_size)
return (torch.rand(self.num_layers, self.batch_size, self.hidden_size).to(device).detach(),
torch.rand(self.num_layers, self.batch_size, self.hidden_size).to(device).detach())

# convert the arguments passed during onnx.export call
class MWrapper(nn.Module):
def __init__(self, model):
super(MWrapper, self).__init__()
self.model = model;
def forward(self, kwargs):
return self.model(**kwargs)

运行一个例子

rnn = RNN(10, 10, 10, 3)
X = torch.randn(3,1,10)
h0,c0 = rnn.init_hidden()
print(rnn(X, h0, c0)[0])

使用相同的输入来跟踪模型并导出 onnx 文件


torch.onnx.export(MWrapper(rnn), {'x':X,'h0':h0,'c0':c0}, 'rnn.onnx',
dynamic_axes={'x':{1:'N'},
'c0':{1: 'N'},
'h0':{1: 'N'}
},
input_names=['x', 'h0', 'c0'],
output_names=['y', 'hn', 'cn']
)

请注意,您可以对某些输入的某些轴的维度使用符号值。未指定的尺寸将固定为跟踪输入的值。默认 LSTM使用维度 1 作为批处理。

接下来我们加载 ONNX 模型并传递相同的输入

import onnxruntime
ort_model = onnxruntime.InferenceSession('rnn.onnx')
print(ort_model.run(['y'], {'x':X.numpy(), 'c0':c0.numpy(), 'h0':h0.numpy()}))

关于python - 在没有安装 pytorch 的情况下使用 RNN 训练模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71146140/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com