在 Python 和其他操作系统中加载和保存 C++ 火炬模型

P0W*_*P0W 5 c++ python machine-learning torch pytorch

我在 C++ 中有一个自定义的LSTMpytorch模型。训练后,我使用保存模型

torch::save(lstmNetwork, 'model.pt'); 
Run Code Online (Sandbox Code Playgroud)

其中lstmNetworkstd::shared_ptr<LSTMNetwork>;

class LSTMNetwork : public torch::nn::Module {
public:
  LSTMNetwork(const torch::nn::LSTMOptions &lstmOpts1,
            const torch::nn::LSTMOptions &lstmOpts2,
            const torch::nn::LinearOptions &linearOpts);
  ~LSTMNetwork();

  torch::Tensor forward(const torch::Tensor &x);

private:
  torch::nn::LSTM lstm1;
  torch::nn::LSTM lstm2;
  torch::nn::Linear linear;
};

LSTMNetwork::LSTMNetwork(const torch::nn::LSTMOptions &lstmOpts1,
                     const torch::nn::LSTMOptions &lstmOpts2,
                     const torch::nn::LinearOptions &linearOpts)
    : torch::nn::Module(),
      lstm1(register_module("lstm1", torch::nn::LSTM(lstmOpts1))),
      lstm2(register_module("lstm2", torch::nn::LSTM(lstmOpts2))),
      linear(register_module("linear", torch::nn::Linear(linearOpts))) {}

LSTMNetwork::~LSTMNetwork() {}

torch::Tensor LSTMNetwork::forward(const torch::Tensor &input) {
  torch::nn::RNNOutput lstm_out = this->lstm1->forward(input);
  lstm_out = this->lstm2->forward(lstm_out.output);
  torch::Tensor y_pred = this->linear(lstm_out.output[-1]);
  return y_pred.view({-1});
}

// .....
  torch::nn::LSTMOptions lstmOpts1(input, hidden);
  torch::nn::LSTMOptions lstmOpts2(hidden, hidden);
  lstmOpts1.layers(numLayers)
      .dropout(NetworkConstants::klsmt1DropOut)
      .with_bias(NetworkConstants::kIncludeBias);
  lstmOpts2.layers(numLayers)
      .dropout(NetworkConstants::klsmt2DropOut)
      .with_bias(NetworkConstants::kIncludeBias);

  torch::nn::LinearOptions linearOpts(hidden, output);
  linearOpts.with_bias(false);
  lstmNetwork = std::make_shared<LSTMNetwork>(lstmOpts1, lstmOpts2, linearOpts);

  torch::optim::AdamOptions opts(learningRate);
  optimizer = std::make_shared<torch::optim::Adam>(
      torch::optim::Adam(lstmNetwork->parameters(), opts));

  if (gpuAvailable) {
    lstmNetwork->to(torch::kCUDA);
  }
//....
Run Code Online (Sandbox Code Playgroud)

我可以毫无问题地在 C++ 中重新加载经过训练的模型,使用:

 torch::load(lstmNetwork, 'model.pt');
Run Code Online (Sandbox Code Playgroud)

我有两个与上述片段相关的问题:

a) 训练后的模型操作系统是否独立?我可以在Windows 10上保存模型并在Ubuntu 18.04 LTS上重新加载它吗? (该应用程序在两个平台上均已编译)

b) 如何pytorch在 python 中打开保存的模型 ('model.pt')?

以下给出了一个错误:

lstmModel = torch.load('model.pt')
Run Code Online (Sandbox Code Playgroud)

错误: 出确切的型号名称

lstmModel = torch.load('stockData\BOM500570.pt') 回溯(最近一次调用最后一次):文件“C:\Python37\lib\tarfile.py”,第 187 行,在 nti n = int(s.strip()或 "0", 8) ValueError: 以 8 为基数的 int() 的无效文字:'ZZZZZZZZ'

在处理上述异常的过程中,又发生了一个异常:

回溯(最近一次调用):文件“C:\Python37\lib\tarfile.py”,第 2289 行,在下一个 tarinfo = self.tarinfo.fromtarfile(self) 文件“C:\Python37\lib\tarfile.py” ,第 1095 行,在 fromtarfile obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) 文件“C:\Python37\lib\tarfile.py”,第 1037 行,在 frombuf chksum = nti(buf[148:156 ]) File "C:\Python37\lib\tarfile.py", line 189, in nti raise InvalidHeaderError("invalid header") tarfile.InvalidHeaderError: invalid header

在处理上述异常的过程中,又发生了一个异常:

回溯(最近一次调用):文件“C:\Python37\lib\site-packages\torch\serialization.py”,第 591 行,在 _load 中返回 legacy_load(f) 文件“C:\Python37\lib\site-packages \torch\serialization.py”,第 502 行,在 legacy_load 中,关闭 (tarfile.open(fileobj=f, mode='r:', format=tarfile.PAX_FORMAT)) 作为 tar, \ File "C:\Python37\lib \tarfile.py", line 1591, in open return func(name, filemode, fileobj, **kwargs) File "C:\Python37\lib\tarfile.py", line 1621, in taropen return cls(name, mode, fileobj, **kwargs) 文件“C:\Python37\lib\tarfile.py”,第 1484 行,在init self.firstmember = self.next() 文件“C:\Python37\lib\tarfile.py”,第 2301 行, 在接下来引发 ReadError(str(e)) tarfile.ReadError:无效的标题

在处理上述异常的过程中,又发生了一个异常:

回溯(最近一次调用):文件“”,第 1 行,在文件“C:\Python37\lib\site-packages\torch\serialization.py”中,第 422 行,在负载返回 _load(f, map_location, pickle_module, **pickle_load_args) 文件 "C:\Python37\lib\site-packages\torch\serialization.py", line 595, in _load raise RuntimeError("{} is a zip archive (d you mean to use torch.jit.load ()?)".format(f.name)) RuntimeError: stockData\BOM500570.pt is a zip archive (你是想使用 torch.jit.load() 吗?)

但是以下正确执行:

lstmModel = torch.jit.load('model.pt')
Run Code Online (Sandbox Code Playgroud)

对于后一种情况,我不能使用python的forward()/ overloaded ()函数,我不确定如何使用加载的模型。

>>> lstmModel = torch.jit.load('stockData\BOM500570.pt')
>>> input = torch.arange(5)
>>> lstmModel.forward(input)
Run Code Online (Sandbox Code Playgroud)

回溯(最近一次调用):文件“”,第 1 行,在文件“C:\Python37\lib\site-packages\torch\jit__init__.py”中,第 1585 行,在getattr 中 return super(ScriptModule, self)。getattr (attr) 文件“C:\Python37\lib\site-packages\torch\nn\modules\module.py”,第 585 行,getattr 类型(self)。name , name)) AttributeError: 'ScriptModule' 对象没有属性 'forward'

>>> lstmModel(input)
Run Code Online (Sandbox Code Playgroud)

回溯(最近一次调用):文件“”,第 1 行,在文件“C:\Python37\lib\site-packages\torch\nn\modules\module.py”,第 541 行,调用 结果 = self.forward (*input, **kwargs) File "C:\Python37\lib\site-packages\torch\jit__init__.py", line 1585, in getattr return super(ScriptModule, self)。getattr (attr) 文件“C:\Python37\lib\site-packages\torch\nn\modules\module.py”,第 585 行,getattr 类型(self)。name , name)) AttributeError: 'ScriptModule' 对象没有属性 'forward'

>>> lstmModel

ScriptModule(
      original_name=Module
      (lstm1): ScriptModule(original_name=Module)
      (lstm2): ScriptModule(original_name=Module)
      (linear): ScriptModule(original_name=Module)
    )
Run Code Online (Sandbox Code Playgroud)