I want to use it in c ++.
I want to learn new network by reusing previously learned data, but I do not know what to do.
Do you have the network defined in C++ frontend?
Yes. I Have a network
I saw your other post in How to load the prebuilt Resnet models weight ?(or any other prebuilt models), did you resolve this problem?
Yes. this problem Resolve
Can you tell me how you solved this problem?
I built the resnet50 network in C++, and I have the pre-training weight of resnet50 under Python. How can I load this weight into resnet50 in C++ and continue training?
This is one way to share pre-trained weights from Python to C++:
- Convert Python model to TorchScript, and save the model to file using
model.save(filename)
. - Create a C++ frontend model with the exact same model structure.
- Load the parameters and buffers from TorchScript model to C++ frontend model using
torch::load(cpp_module, file_path_to_torchscript_model)
This is a minimal example:
JIT model:
import torch
class Model(torch.jit.ScriptModule):
def __init__(self):
super(Model, self).__init__()
self.linear = torch.nn.Linear(2, 2)
model = Model()
print(model.linear.weight) # For comparison
model.save('model1.pt')
C++ frontend model:
struct Net : torch::nn::Module {
Net() {
linear = register_module("linear", torch::nn::Linear(2, 2)); // Exactly match the Python model
}
torch::nn::Linear linear{nullptr};
};
Load parameters of JIT model into C++ frontend model:
int main(int argc, const char* argv[]) {
auto module = std::make_shared<Net>();
std::cout << module->linear->named_parameters()["weight"] << "\n"; // before loading pre-trained params
torch::load(module, argv[1]);
std::cout << module->linear->named_parameters()["weight"] << "\n"; // after loading pre-trained params
return 0;
}
For converting your existing Python model to TorchScript (i.e. step 1), you can also use tracing (https://pytorch.org/tutorials/advanced/cpp_export.html#converting-to-torch-script-via-tracing). However you still need to manually define the same model structure in C++ API before loading the parameters in C++.
This example is very simple, but it works well. If you want more information. Check this Repository.
There is also a way to not use JIT.
If it does not work, talk to me. I’ll tell you another way.
I hope you can share another method with me, thank you.
I hope you can share another method with me, thank you.
you See here.
The method is as
- Python Model State JSON File Dump
- Load libtorch JSON to parameter
JSON file Dump Like that
import torch
import torchvision
import torch.nn as nn
import torchvision.models as models
import json
resnet18 = torchvision.models.resnet18(True)
raw_state_dict = {}
for k, v in resnet18.state_dict().items():
if isinstance(v, torch.Tensor):
raw_state_dict[k] = (list(v.size()), v.numpy().tolist())
else:
print("State parameter type error : {}".format(k))
exit(-1)
with open('resnet18.json', 'w') as outfile:
json.dump(raw_state_dict, outfile,indent= "\t")
Load JSON model c++
//you defined model
Network model;
LoadStateDictJson(model, "JSON File Path");
torch::save(model, "File path");
Caution you doing for Define Network.
All networks should be in Impl so that torch :: save works normally.
use to TORCH_MODULE
In a similar way to
#ifndef ALEXNET_H
#define ALEXNET_H
#include <torch/torch.h>
namespace vision {
namespace models {
// AlexNet model architecture from the
// "One weird trick..." <https://arxiv.org/abs/1404.5997> paper.
struct AlexNetImpl : torch::nn::Module {
torch::nn::Sequential features{nullptr}, classifier{nullptr};
AlexNetImpl(int64_t num_classes = 1000);
torch::Tensor forward(torch::Tensor x);
};
TORCH_MODULE(AlexNet);
} // namespace models
} // namespace vision
#endif // ALEXNET_H