过了一周,又一次聊天10分钟,没有面试机会,就被相亲姑娘pass了,哎,人生啊。不知道还是不是化悲痛为力量了,只能练习一个算法,再缓解缓解忧愁?
前言
日常热身,每周几次10几分钟低难度力量训练,外加几次低难度HIIT有氧,保持充足的活力。岁数大了,不知道这些是不是在欺骗自己呢?总之,体重没减,力量略微增加,生活依旧,没有任何波澜起伏。
一、准备
环境配置,包安装,数据源和下载,程序地址直接看上一篇就好,链接如下:
https://blog.csdn.net/bjjoy2009/article/details/110311411
二、deep&cross
deep&cross,由两部分组成,deep部分就是单纯的DNN网络。cross部分是每个特征交叉计算。
由于这里采用新闻推荐为例子,新闻由tiny bert转换为128位向量,用户是点击新闻向量平均值,所以输入是:用户向量+新闻向量(+是向量拼接),label是否点击(0,1表示)。提前做好了Embedding,算法中省略了Sparse feature到Embedding vec步骤。
网络结构如下图所示:
左侧cross网络每层具体公式如下:
每个参数具体维度变换图如下:这部分略微重要了,在用tf2实现的时候,各种维度错误,调了好久。
给个cross网络代码示例,维度变变变,主要是注意都是向量乘法,初始化时候就明确了参数具体维度,即使1维也不省略。
class Cross(Model):
"""
cross网络
"""
def __init__(self, embed_dim, layer_num):
"""
:param embed_dim: 输入向量长度
:param layer_num: 网络层数
"""
super(Cross, self).__init__()
self.embed_dim = embed_dim
self.layer_num = layer_num
self.ws = []
self.bs = []
for i in range(layer_num):
# 变量加了不同的name,否则保存h5模型会报错
self.ws.append(tf.Variable(tf.random.truncated_normal(shape=(embed_dim, 1), stddev=0.01)))
self.bs.append(tf.Variable(tf.zeros(shape=(embed_dim, 1))))
def call(self, inputs, training=None, mask=None):
x0 = inputs
xl = x0
for w, b in zip(self.ws, self.bs):
xl_T = tf.reshape(xl, [-1, 1, self.embed_dim])
xlTw = tf.tensordot(xl_T, w, axes=1)
xl = x0 * xlTw + b + xl
return xl
DNN网络就不写了,代码里边给出,这个比较流程化。
代码结构说明
deep&cross,其实和上一篇一样一样的,就是换了网路结构,数据生成和数据加载完全一模一样,这次规范了一下代码结构
1、data文件夹(无改动)
(1)bert是tf1.14程序,利用bert将文本转换为向量,这里用的tiny bert,下载地址为,https://github.com/google-research/bert
(2)dev和train,是数据文件,上面数据源下载的
(3)bert_sentence_vector.py,调用bert向量化程序
(4)build_data_set.py,根据向量和用户点击行为,生成用户、新闻向量和中间用到的字典数据。从上到下各个函数,有to_csv和save保存文件的程序,跑一下就好了。
2、deep_and_cross文件夹
(1)model,模型文件保存文件夹。
(2)deep_cross_model,模型网络结构和创建。
(3)model_train,模型训练。
(4)dc_evaluate,模型验证。
说明:把模型、训练、验证拆分出来,为了减少代码重复。训练和验证只需要加载deep_cross_model里边构建好的网络,直接运行即可。避免了训练和验证重复构建网络部分代码,导致参数等错误导致模型加载无法运行。
总结
再次实现了一个算法,再一次相亲无果,这不会一直互相伴随着走下去吧,要不要这么悲哀啊,真是迷茫猿小明了。
这次利用tf2实现算法时候遇到了不少问题,特别是模型存储和加载,总结了一下,就不单独写博客了,记录到笔记中吧。