Open dongliya opened 7 years ago
看了好几天还是没有找到保存模型的方法
+1
+1 @Yangqing @bwasti @aaronmarkham
I try to use FetchBlob and FeedBlob for a temporarily weight saving. At least it works...
@jimmyoic do you have any sample code for that? Are you able to then use it with the predictor?
I use pickle to serialize the weight, which is a dictionary of blobName-Weight pair, then dump it into files. Once I need to load the model, I can recover the weight by pickle, and call FeedBlob to put the weight into the model. It's a dumb way that I think somehow we may easily reload the model like what we did in Caffe later.
@jimmyoic do you have sample code for that? +1
@jimmyoic wow! Could you share your code?
def GetCheckpointParams(train_model):
params = [str(p) for p in train_model.GetParams()]
#params.extend([str(p) + "_momentum" for p in params])
params.extend([str(p) for p in train_model.GetComputedParams()])
assert len(params) > 0
return params
def SaveModel(args, train_model, epoch):
predictor_export_meta = pred_exp.PredictorExportMeta(
predict_net=train_model.net.Proto(),
parameters=GetCheckpointParams(train_model),
#inputs=["data"],
inputs=[],
#outputs=["softmax"],
outputs=[],
shapes={
#"data": (args.num_channels, args.image_size, args.image_size)
#"softmax": (1, args.num_labels)
}
)
model_path = "%s/%s_%d.mdl" % (
args.models_dir,
train_model.net.Proto().name,
epoch,
)
pred_exp.save_to_db(
db_type="minidb",
db_destination=model_path,
predictor_export_meta=predictor_export_meta,
)
def LoadModel(path, model):
meta_net_def = pred_exp.load_from_db(path, 'minidb')
init_net = core.Net(pred_utils.GetNet(
meta_net_def, predictor_constants.GLOBAL_INIT_NET_TYPE))
predict_init_net = core.Net(pred_utils.GetNet(
meta_net_def, predictor_constants.PREDICT_INIT_NET_TYPE))
predict_init_net.RunAllOnGPU()
init_net.RunAllOnGPU()
assert workspace.RunNetOnce(predict_init_net)
assert workspace.RunNetOnce(init_net)
@jimmyoic Hi,did you save the model to init_net.pb and predict_init_net.pb ? I am trying to use the caffe2 model on mobilephone.
@zhoushipin how to predict?
@dongliya
from caffe2.python import workspace
predictor = workspace.Predictor(init_net, predict_init_net)
inputs = [np.zeros((1, 3, 32, 32), dtype='f')] #or load image use cv2.imread
outputs = predictor.run(inputs)
@zhoushipin I know this method of use python, but do you know how to predict use C++ ?
@dongliya
static bool read_binary_file(const std::string &filename,
std::vector<char> &buffer)
{
std::ifstream file(filename, std::ios::binary | std::ios::ate);
if (!file)
{
return false;
}
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
buffer.resize(size);
return file.read(buffer.data(), size);
}
std::vector<char> init_net_buffer;
std::vector<char> predict_net_buffer;
read_binary_file("init_net.pb", init_net_buffer);
read_binary_file("predict_init_net.pb", predict_net_buffer);
caffe2::NetDef init_net;
caffe2::NetDef predict_net;
init_net.ParseFromArray(init_net_buffer.data(), init_net_buffer.size());
predict_net.ParseFromArray(predict_net_buffer.data(), predict_net_buffer.size());
std::unique_ptr<caffe2::Predictor> predictor =
std::make_unique<caffe2::Predictor>(init_net, predict_net);
const int H = 32;
const int W = 32;
const int C = 3;
if (predictor)
{
cv::Mat img = cv::imread("xxx.jpg");
// preprocess the image
// img = ...;
caffe2::TensorCPU input(std::vector<int>({H, W, C}));
memcpy(input.mutable_data<float>(), img.data, H * W * C * sizeof(float));
caffe2::Predictor::TensorVector input_vec{&input};
caffe2::Predictor::TensorVector output_vec;
predictor->run(input_vec, &output_vec);
// process the result in output_vec
// ...
}
@zhoushipin Thank you for your patience, but the problem still exists terminate called after throwing an instance of 'caffe2::EnforceNotMet' what(): [enforce fail at conv_op_impl.h:24] X.ndim() == filter.ndim(). 3 vs 4 Error from operator: input: "data" input: "conv1_w" input: "conv1_b" output: "conv1" type: "Conv" arg { name: "stride" i: 2 } arg { name: "pad" i: 0 } arg { name: "kernel" i: 3 } Aborted at 1495010251 (unix time) try "date -d @1495010251" if you are using GNU date PC: @ 0x7f03e2f3b428 gsignal SIGABRT (@0x3e800002542) received by PID 9538 (TID 0x7f03e63dc800) from PID 9538; stack trace: @ 0x7f03e2f3b4b0 (unknown) @ 0x7f03e2f3b428 gsignal @ 0x7f03e2f3d02a abort @ 0x7f03e335e84d gnu_cxx::verbose_terminate_handler() @ 0x7f03e335c6b6 (unknown) @ 0x7f03e335c701 std::terminate() @ 0x7f03e335c969 cxa_rethrow @ 0x7f03e5a4b594 caffe2::Operator<>::Run() @ 0x7f03e5a5d572 caffe2::SimpleNet::Run() @ 0x7f03e5aa9807 caffe2::Workspace::RunNet() @ 0x7f03e5a9e3a2 caffe2::Predictor::run() @ 0x40971a main @ 0x7f03e2f26830 libc_start_main @ 0x40a0c9 _start @ 0x0 (unknown) Aborted (core dumped)
@dongliya
//caffe2::TensorCPU input(std::vector<int>({H, W, C}));
//memcpy(input.mutable_data<float>(), img.data, H * W * C * sizeof(float));
caffe2::TensorCPU input(std::vector<int>({1, C, H, W}));
to_tensorcpu(img, input);
static void to_tensorcpu(cv::Mat &img, caffe2::TensorCPU &tensor)
{
const int num_channel = tensor.dim(1);
const int height = tensor.dim(2);
const int width = tensor.dim(3);
assert(img.channels() == num_channel);
assert(img.cols == width);
assert(img.rows == height);
assert(img.type() == CV_32F);
float* tensor_data = tensor.mutable_data<float>();
std::vector<cv::Mat> bgr;
for (int i = 0; i < num_channel; ++i)
{
bgr.push_back(cv::Mat(height, width, CV_32FC1, tensor_data));
tensor_data += width * height;
}
// HWC to CHW
cv::split(img, bgr);
}
This one might also help:
from caffe2.python.predictor import mobile_exporter
Anybody else who wants to save to a .pb file take a look at the unofficial C++ Caffe2 tutorial: https://github.com/leonardvandriel/caffe2_cpp_tutorial
The guy who created it has an example of writing to .PB files in the mnist tutorial and also has an example of reading it in through c++ in his pretrained tutorial.
I want to know how to generate init_net.pb and predict_net.pb?