深度学习在点击率预估中的实战(part 3)

part3 正文:

上文说到,tf model server 搭建完成,这时距离真正的应用可以说完事具备只差东风,本节主要讲述概要的第四部分,推荐系统sever对dnn model server的client。本文主要从TFrecords,数据结构,python对dnn model server的client,以及推荐系统server对model server的client,三个方面来进行阐述。

(1)准备知识点之TFrecords。

TensorFlow 提供了一种统一的格式来存储数据,这就是TFrecord。这样的好处就是避免了我们自己在trainmodel 和应用model时候使用自己定义的数据结构来通信,可维护性非常差。TFrecord文件中的数据都是通过tf.train.Example PB格式存储的,具体可以参见git clone --recurse-submodules https://github.com/tensorflow/serving后serving/tensorflow/core/example/example.proto,serving/tensorflow/core/example/feature.proto 这两个proto文件里面有Example数据结构的定义,以及具体的case。将两个文件里的定义merge一下,如下图1所示。也就是说构造一个Example 实例只需要构造一个Features,而构造Features只需要构造一个key是string,value 是Feature的map。而Feature就相对简单。就是BytesList,FloatList,Int64List其中之一,分别对应string类型的特征,float类型的特征,以及int型特征。同样BytesList,FloatList,Int64List的定义也在serving/tensorflow/core/example/feature.proto中。每一个Example就是一个训练的实例。大家要对这个概念清晰。说到这里可能大家依然不能知道,我用python怎么构造一个Example,或者我用java如何构造一个Example。下面会在讲述client时候直接上代码。图2附proto文件中Example的一个具体例子,看完之后相信就可以基本明白如何构造。featureMap里面value就是训练model时候每一维特征值。key就是这个特征对应的名字,可以随便取,只要能和train的时候对应好就可以。


图1 Example 定义


图2 Example 例子

(2)python 对Dnn model server的client。

在搭建tf model server的过程中,需要及时测一下,所搭的server是否是ok可用的,那么就需要client。为什么首先要讲python对model server的client,因为在搭建tf serving的时候,官网给出的tutorial 中,有一个简易的minist数字识别的server与client的 testcase。请参考https://www.tensorflow.org/serving/serving_basic。以及下图3.


图3 mnist tf server test case

在我将model export出,启动了服务后,通过/serving/tensorflow_serving/apis/prediction_service.proto, /serving/tensorflow_serving/apis/predict.proto查看到通信的Request需要构造,第一部分ModelSpec定义在/serving/tensorflow_serving/apis/predict.proto,不再粘贴有三个成员变量 1是modelname,和export时候对应就可以2.是model version可以不指定,默认最新的model version加载。3是signature_name这个和export时候一样就可以。第二部分key string,通过注释可以看到默认情况下都是“inputs”,value是TensorProto。TensorProto的定义在/serving/tensorflow/core/framework/tensor.proto中,这里也不再贴图而是简述一下.TensorProto有很多成员变量,但是有一些是不需要的下面只说一些必须的。1.DataType,需要说明这个Tensor的数据类型,这里用的string,是将上文介绍的Example序列化成的string。2.tensor_shape,因为tensor其实可以理解成一个list,所以这里就是list size,用算法的术语说就是有多少个训练实例。3.从定义的repeated的各种类型中,选取合理的一种类型,这里选repeated bytes string_val=8. 上述信息填充完整TensorProto就填充完整了。第三部分output_filter 通过看注释,说的是当不定义时候所有的input tensor 会被返回,这是符合我们的要求的。所以这里不用指定。

图3 predict.proto

解读完这个之后我们就可以写代码了。这里特别感谢大神https://github.com/MtDersvan/tf_playground/blob/master/wide_and_deep_tutorial/wide_and_deep_basic_serving.md,在这里简单写的model export的方法以及server client如果构造输入的request,还包括如何写到build文件里,供bazel的编译。在从github上看到这个的时候突然想到了姚明06年fiba世锦赛评价王治郅的话,“彷佛在沙漠里待了10天后的第一口水”。上面提到的git链接里只给出了预测一个实例的代码,下面截图给出多个实例预测的一个demo。feature_dict 也就是根据自己训练模型的时候使用的特征构造的feature。构造完就可以编译bazel build //tensorflow_serving/example:wide_and_deep_client,然后运行bazel-bin/tensorflow_serving/example/wide_and_deep_client --model=wide_and_deep --server=ip:port. 如果能返回正常的结果证明测试过程已经全部走通。另外关于grpc的python client与java client的通信细节与使用等这里不做阐述,默认都会。如需参考,请参考:https://grpc.io/。

图4.多实例request构造

(3)推荐server对tf model server的client。

由于我们的推荐引擎server是用java书写的,所以需要将/serving/目录下的所有proto文件全部生成java的api文件也就是从*.proto=>*.java, 然后将这些java导入我们的java 工程。当然还需要利用protoc-gen-grpc-java把 /server/tensorflow_serving/apis/prediction_service.proto 生成一个java的通信文件。来完成grpc的通信。具体步骤请参考下面。

1.由于tf server 是采用的grpc通信,所以需要编译protobuffer文件产出我们需要的client api,完成client代码的编写与通信。

2.因为在操作protoc 生成java过程中需要把 serving 目录下的文件夹文件夹移动,所以为了不破坏成产环境,可以cp 一份serving_bak,专门生成client端api,而且如果你是之前安装了tensorflow的话,可能这里你不运行/server/tensorflow/configure 等安装步骤,这个时候发现 有两层tensorflow目录 /server/tensorflow/tensorflow 直接拷贝出一层就可以,木啥大问题。

3.cp -r serving serving_bak

4.由于java 很多工程都是在特定的package下,比如我们的在compay_name.recommend 下,所以在运行protoc生成api之前,我们需要改变一下.proto 文件的java package.  所有的proto文件在"tensorflow_serving/apis/", "tensorflow/core/example/", "tensorflow/core/framework/", "tensorflow/core/protobuf/","tensorflow/core/lib/core/", 其中tensorflow_serving/apis/下的所有proto没有 option java_package = ""这一行。所以我们直接添加 option java_package = "compay_name.recommend.tensorflow.serving"。其余文件夹下的proto原来就有option java_package = ""这一行,所有在原来的基础上添加上这里的前缀compay_name.recommend就可以了。自己写个脚本就可以,我的脚本就不公布到这里了。这个过程不是壁垒。

5.运行一下由proto 生成java的脚本,见图5.最后将这些文件放倒java项目的目录结构见图6

6.运行生成通信文件protoc  --plugin=protoc-gen-grpc-java=插件路径   --grpc-java_out=hh --proto_path=. tensorflow_serving/apis/prediction_service.proto



图5 利用proto产出java api部分代码


图6  目录结构

番外介绍一下protoc和protoc-gen-grpc-java的安装,凌晨4点的北京也不是白见的。安装protobuf,按照这个网址https://github.com/google/protobuf/tree/master/src,首先clone下来源码问题然后一步步操作问题不大。安装的版本是3.3.0

然后是安装protoc-gen-grpc-java 首先clonehttps://github.com/grpc/grpc-java.git,其次cd  compiler, 然后../gradlew java_pluginExecutable 然后../gradlew test很容易就成功了。但是我在编译过程中出现了一个问题/usr/bin/ld: cannot find -lstdc++,然后搜百度,google,可能是软链坏了,然后重新ln -s,重新装gcc,g++,写Helloworld.cpp,换机器重新搞环境都不行,不知不觉搞了两个多小时,一看表。4点了。郁闷的睡了,第二天起来之后好好读了Build文件build.gradle,发现了是依赖的静态libstdc++。这才抱着试试看的态度,yum installlibstdc++48-static.x86_64,装了一下这个static,发现ok了。


图7 build.gradle

上述所有工作搞完之后就进入了代码的书写阶段,需要在maven项目中引入下图的一些依赖。这些从grpc的官网上都能看到。当然还有一个tensorflow的一些基础包。


图8 maven的一些依赖


从生成的java api可以看出,每一种数据结构,都是有一个builder。想生成这种数据结构需要先生成这个数据结构的builder。然后build一下就生成了相应的数据结构。话不多说。直接上代码。下图中是构建request的过程。tensorProto是由许多个实例序列化成string够成的。在图10中,我们看到docid,userid 和三个打了马赛克的特征是string类型的。也就是需要embeding的特征。不同的任务特征需要仔细筛选这里就不误导大家了所以打了马赛克。

图9 构建request


图10 构建一个Example

参考:

引用1。https://github.com/MtDersvan/tf_playground/blob/master/wide_and_deep_tutorial/wide_and_deep_basic_serving.md


完成于20170830,如转载请注明出处。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容