Tensorflow工程化记录,使用C++调用模型,摒弃Python等依赖环境

大多数情况下,训练模型是在Python环境下,需要安装一大堆环境,非常繁琐,且无法交给别人使用。在Python环境下模型训练完成后,如何供别人使用是一个大问题。

最近,项目需要,实现了Tensorflow的工程化。期间,有太多的坑要填。在此,作简单记录。

环境:

1.VS2015 (一定是VS2015,过高、过低都不行);

2.CMake3.8(正常的话,3.5以上就可以,需要看Tensorflow的CMake文件所需的最小版本);

3.Tensoseflow版本:1.8(建议),刚开始用的版本是1.4,session在run的时候会出错;

首先,编译Tensorflow。没有什么注意的,如图:

这里要注意,修改PREFIX为非C盘,否则,可能会因为权限问题,无法写入文件,而出错。

Generate后生成tensorflow.sln文件,用vs2015打开,生成ALLBUILD项目,等待1个多小时生成结束后,再次,单独生成tf_core_kernels,等待生成结束,再次单独编译tensorflow_static,生成结束后,最后单独生成tensorflow。便可获得tensorflow.lib和tensorflow.dll。到此,完成编译。

其次,固化模型:

固化模型可在Python环境中进行。


def freeze_graph():
    dir = os.path.dirname(os.path.realpath(__file__))
    checkpoint = tf.train.get_checkpoint_state(dir + '/experiments/OutModel')
    input_checkpoint = checkpoint.model_checkpoint_path
    print(input_checkpoint)
    input_checkpoint = checkpoint.model_checkpoint_path

    absolute_model = '/'.join(input_checkpoint.split('/')[:-1])
    print(absolute_model)

    output_grap = absolute_model + "/frozen_model.pb"

    with tf.Session(graph=tf.Graph()) as sess:
        saver = tf.train.import_meta_graph(input_checkpoint + '.meta',
                                           clear_devices=True)

        saver.restore(sess, input_checkpoint)

        # 打印图中的变量,查看要保存的
        for op in tf.get_default_graph().get_operations():
            print(op.name + '\t' + str(op.values()))
        
        output_grap_def = tf.graph_util.convert_variables_to_constants(sess,                                                                       tf.get_default_graph().as_graph_def(),                                                                     output_node_names=['output'])

        with tf.gfile.GFile(output_grap, 'wb') as f:
            f.write(output_grap_def.SerializeToString())
        print("%d ops in the final graph." % len(output_grap_def.node))

其中,输出节点必须定义,而这个节点在网络里很难找。办法是通过tensorboard去分析和寻找,从而生成*.pb文件,也就是固化模型。

最后,需要通过第三方库读取图像,转化为Tensor,在VS中创建工程,读取Tensor作为输入。

void CVMatToTensor(cv::Mat img, Tensor* output_tensor, int input_rows, int input_cols)
{
	resize(img, img, cv::Size(input_cols, input_rows));
	
	img.convertTo(img, CV_32FC3);

	float *pTensor = output_tensor->flat<float>().data();

	cv::Mat tempMat(input_rows, input_cols, CV_32FC3, pTensor);
	img.convertTo(tempMat, CV_32FC3);
}

创建Graph,设定输入和输出,session->run()即可获得结果;run()函数有四个参数,输入节点、张量,输出节点、{}、输出。

备注:在这个过程中,一定会遇到无数坑的,需要一点一点填平。这里可以说明的是,工程化一定可以实现,不同的网络可能会遇到不同的问题。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值