I have a custom LSTM pytorch model in C++. After training I save the model using
torch::save(lstmNetwork, 'model.pt');
where lstmNetwork is std::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);
}
//....
I can reload the trained model in C++ without issue, using:
torch::load(lstmNetwork, 'model.pt');
I have two questions related to the above snippets:
a) Is the trained model OS independent? Can I save the model on Windows 10 and reload it on Ubuntu 18.04 LTS? (The application is complied on both the platforms)
b) How do I open the saved pytorch model ('model.pt') in python?
Following gives an error:
lstmModel = torch.load('model.pt')
Error : (showing the exact model name)
lstmModel = torch.load('stockData\BOM500570.pt') Traceback (most recent call last): File "C:\Python37\lib\tarfile.py", line 187, in nti n = int(s.strip() or "0", 8) ValueError: invalid literal for int() with base 8: 'ZZZZZZZZ'
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "C:\Python37\lib\tarfile.py", line 2289, in next tarinfo = self.tarinfo.fromtarfile(self) File "C:\Python37\lib\tarfile.py", line 1095, in fromtarfile obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) File "C:\Python37\lib\tarfile.py", line 1037, in frombuf chksum = nti(buf[148:156]) File "C:\Python37\lib\tarfile.py", line 189, in nti raise InvalidHeaderError("invalid header") tarfile.InvalidHeaderError: invalid header
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "C:\Python37\lib\site-packages\torch\serialization.py", line 591, in _load return legacy_load(f) File "C:\Python37\lib\site-packages\torch\serialization.py", line 502, in legacy_load with closing(tarfile.open(fileobj=f, mode='r:', format=tarfile.PAX_FORMAT)) as 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) File "C:\Python37\lib\tarfile.py", line 1484, in init self.firstmember = self.next() File "C:\Python37\lib\tarfile.py", line 2301, in next raise ReadError(str(e)) tarfile.ReadError: invalid header
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "", line 1, in File "C:\Python37\lib\site-packages\torch\serialization.py", line 422, in load return _load(f, map_location, pickle_module, **pickle_load_args) File "C:\Python37\lib\site-packages\torch\serialization.py", line 595, in _load raise RuntimeError("{} is a zip archive (did you mean to use torch.jit.load()?)".format(f.name)) RuntimeError: stockData\BOM500570.pt is a zip archive (did you mean to use torch.jit.load()?)
However following executes correctly:
lstmModel = torch.jit.load('model.pt')
For the latter case, I cannot use python's forward()/ overloaded () function, and I'm not sure how to use the loaded model.
>>> lstmModel = torch.jit.load('stockData\BOM500570.pt')
>>> input = torch.arange(5)
>>> lstmModel.forward(input)
Traceback (most recent call last): File "", line 1, in File "C:\Python37\lib\site-packages\torch\jit__init__.py", line 1585, in getattr return super(ScriptModule, self).getattr(attr) File "C:\Python37\lib\site-packages\torch\nn\modules\module.py", line 585, in getattr type(self).name, name)) AttributeError: 'ScriptModule' object has no attribute 'forward'
>>> lstmModel(input)
Traceback (most recent call last): File "", line 1, in File "C:\Python37\lib\site-packages\torch\nn\modules\module.py", line 541, in call result = self.forward(*input, **kwargs) File "C:\Python37\lib\site-packages\torch\jit__init__.py", line 1585, in getattr return super(ScriptModule, self).getattr(attr) File "C:\Python37\lib\site-packages\torch\nn\modules\module.py", line 585, in getattr type(self).name, name)) AttributeError: 'ScriptModule' object has no attribute 'forward'
>>> lstmModel
ScriptModule(
original_name=Module
(lstm1): ScriptModule(original_name=Module)
(lstm2): ScriptModule(original_name=Module)
(linear): ScriptModule(original_name=Module)
)