经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 大数据云AI » 人工智能基础 » 查看文章
使用C#把Tensorflow训练的.pb文件用在生产环境
来源:cnblogs  作者:bbird2018  时间:2018/11/14 9:43:53  对本文有异议

训练了很久的Tf模型,终于要到生产环境中去考研一番了。今天花费了一些时间去研究tf的模型如何在生产环境中去使用。大概整理了这些方法。

继续使用分步骤保存了的ckpt文件

这个貌似脱离不了tensorflow框架,而且生成的ckpt文件比较大,发布到生产环境的时候,还得把python的算法文件一起搞上去,如何和其他程序交互,可能还得自己去写服务。估计很少有人这么做,貌似性能也很一般。

使用tensorflow Serving

tf Serving貌似是大家都比较推崇的方法。需要编译tfServing,然后把模型导出来。直接执行tf Serving的进程,就可以对外提供服务了。具体调用的时候,还得自己写客户端,使用人gRPC去调用Serving,然后再对外提供服务,听上去比较麻烦。而且我今天没太多的时间去研究gRPC,网络上关于客户端很多都是用python写的,我感觉自己的python水平比较菜,没信心能写好。所以这个方式就先没研究。

生产.pb文件,然后写程序去调用.pb文件

生成了.pb文件以后,就可以被程序去直接调用,传入参数,然后就可以传出来参数,而且生成的.pb文件非常的小。而我又有比较丰富的.net开发经验。在想,是否可以用C#来解析.pb文件,然后做一个.net core的对外服务的API,这样貌似更加高效,关键是自己熟悉这款的开发,不用花费太多的时间去摸索。、

具体的思路

使用.net下面的TensorFlow框架tensorflowSharp(貌似还是没脱离了框架).去调用pb文件,然后做成.net core web API 对外提供服务。

具体的实现

直接上代码,非常简单,本身设计到tensorflowsharp的地方非常的少

  1. var graph = new TFGraph();
  2. //重点是下面的这句,把训练好的pb文件给读出来字节,然后导入
  3. var model = File.ReadAllBytes(model_file);
  4. graph.Import(model);
  5. Console.WriteLine("请输入一个图片的地址");
  6. var src = Console.ReadLine();
  7. var tensor = ImageUtil.CreateTensorFromImageFile(src);
  8. using (var sess = new TFSession(graph))
  9. {
  10. var runner = sess.GetRunner();
  11. runner.AddInput(graph["Cast_1"][0], tensor);
  12. var r = runner.Run(graph.softmax(graph["softmax_linear/softmax_linear"][0]));
  13. var v = (float[,])r.GetValue();
  14. Console.WriteLine(v[0,0]);
  15. Console.WriteLine(v[0, 1]);
  16. }

ImageUtil这个类库是tensorflowSharp官方的例子中一个把图片转成tensor的类库,我直接copy过来了,根据我的网络,修改了几个参数。

  1. public static class ImageUtil
  2. {
  3. public static TFTensor CreateTensorFromImageFile(byte[] contents, TFDataType destinationDataType = TFDataType.Float)
  4. {
  5. var tensor = TFTensor.CreateString(contents);
  6. TFOutput input, output;
  7. // Construct a graph to normalize the image
  8. using (var graph = ConstructGraphToNormalizeImage(out input, out output, destinationDataType))
  9. {
  10. // Execute that graph to normalize this one image
  11. using (var session = new TFSession(graph))
  12. {
  13. var normalized = session.Run(
  14. inputs: new[] { input },
  15. inputValues: new[] { tensor },
  16. outputs: new[] { output });
  17. return normalized[0];
  18. }
  19. }
  20. }
  21. // Convert the image in filename to a Tensor suitable as input to the Inception model.
  22. public static TFTensor CreateTensorFromImageFile(string file, TFDataType destinationDataType = TFDataType.Float)
  23. {
  24. var contents = File.ReadAllBytes(file);
  25. // DecodeJpeg uses a scalar String-valued tensor as input.
  26. var tensor = TFTensor.CreateString(contents);
  27. TFOutput input, output;
  28. // Construct a graph to normalize the image
  29. using (var graph = ConstructGraphToNormalizeImage(out input, out output, destinationDataType))
  30. {
  31. // Execute that graph to normalize this one image
  32. using (var session = new TFSession(graph))
  33. {
  34. var normalized = session.Run(
  35. inputs: new[] { input },
  36. inputValues: new[] { tensor },
  37. outputs: new[] { output });
  38. return normalized[0];
  39. }
  40. }
  41. }
  42. // The inception model takes as input the image described by a Tensor in a very
  43. // specific normalized format (a particular image size, shape of the input tensor,
  44. // normalized pixel values etc.).
  45. //
  46. // This function constructs a graph of TensorFlow operations which takes as
  47. // input a JPEG-encoded string and returns a tensor suitable as input to the
  48. // inception model.
  49. private static TFGraph ConstructGraphToNormalizeImage(out TFOutput input, out TFOutput output, TFDataType destinationDataType = TFDataType.Float)
  50. {
  51. // Some constants specific to the pre-trained model at:
  52. // https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip
  53. //
  54. // - The model was trained after with images scaled to 224x224 pixels.
  55. // - The colors, represented as R, G, B in 1-byte each were converted to
  56. // float using (value - Mean)/Scale.
  57. const int W = 128;
  58. const int H = 128;
  59. const float Mean = 0;
  60. const float Scale = 1f;
  61. var graph = new TFGraph();
  62. input = graph.Placeholder(TFDataType.String);
  63. output = graph.Cast(
  64. graph.Div(x: graph.Sub(x: graph.ResizeBilinear(images: graph.ExpandDims(input: graph.Cast(graph.DecodeJpeg(contents: input, channels: 3), DstT: TFDataType.Float),
  65. dim: graph.Const(0, "make_batch")),
  66. size: graph.Const(new int[] { W, H }, "size")),
  67. y: graph.Const(Mean, "mean")),
  68. y: graph.Const(Scale, "scale")), destinationDataType);
  69. return graph;
  70. }
  71. }

搞定

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号