FNN 网络介绍与源码浅析
前言
周五晚上分享 paper !!! 感动自己一把~ ? 感觉本周看的 Paper 还挺多的, 打算尽可能都做下记录, 方便日后查阅.
广而告之
可以在微信中搜索 “珍妮的算法之路” 或者 “world4458” 关注我的微信公众号;另外可以看看知乎专栏 PoorMemory-机器学习, 以后文章也会发在知乎专栏中;
文章信息
- 论文标题: Deep Learning over Multi-field Categorical Data – A Case Study on User Response Prediction
- 论文地址: https://arxiv.org/abs/1601.02376
- 代码地址: https://github.com/wnzhang/deep-ctr, 这是作者提供的基于 Theano 的代码; 另外我在 https://github.com/Atomu2014/product-nets/blob/master/python/models.py (PNN 作者的实现) 以及 https://github.com/shenweichen/DeepCTR/blob/master/deepctr/models/fnn.py (浅梦的实现) 看到了基于 TF 的实现, 所有后续关于代码介绍采用的 PNN 作者的实现. (关于 PNN 的介绍, 可以查看我的博客 Product-based Neural Network (PNN) 介绍与源码浅析
- 发表时间: European Conference on Information Retrieval, 2016
- 论文作者: Weinan Zhang, Tianming Du, and Jun Wang
- 作者单位: University College London
核心观点
核心观点介绍
FNN 的网络结构图如下:
可以发现, 主要还是经典的 Embedding + MLP 结构. 其核心在于设计 Embedding Layer 时, 按照 FM 的思路来设置. 回忆 FM 的公式是:
y F M ( x ) : = sigmoid ( w 0 + ∑ i = 1 N w i x i + ∑ i = 1 N ∑ j = i + 1 N ⟨ v i , v j ⟩ x i x j ) y_{\mathrm{FM}}(\boldsymbol{x}):=\operatorname{sigmoid}\left(w_{0}+\sum_{i=1}^{N} w_{i} x_{i}+\sum_{i=1}^{N} \sum_{j=i+1}^{N}\left\langle\boldsymbol{v}_{i}, \boldsymbol{v}_{j}\right\rangle x_{i} x_{j}\right) yFM(x):=sigmoid(w0+i=1∑Nwixi+i=1∑Nj=i+1∑N⟨vi,vj⟩xixj)
那么 FNN 在设计 Embedding 时, 设置每个 Field 对应的 Embedding 权重为 W i ∈ R ( K + 1 ) × ( e n d i − s t a r t i + 1 ) \bm{W}^i\in\mathbb{R}^{(K + 1)\times (\mathrm{end}_i – \mathrm{start}_i + 1)} Wi∈R(K+1)×(endi−starti+1), 其中 s t a r t i \mathrm{start}_i starti 和 e n d i \mathrm{end}_i endi 是第 i i i 个 Field 下的特征的起始和结束索引值. 注意到每个特征的 emb z i \bm{z}_i zi 大小为 K + 1 K + 1 K+1, 它表示为:
z i = W i ⋅ x [ start i : end i ] = ( w i , v i 1 , v i 2 , … , v i K ) \boldsymbol{z}_{i}=\boldsymbol{W}^{i} \cdot \boldsymbol{x}\left[\operatorname{start}_{i}: \operatorname{end}_{i}\right]=\left(w_{i}, v_{i}^{1}, v_{i}^{2}, \ldots, v_{i}^{K}\right) zi=Wi⋅x[starti:endi]=(wi,vi1,vi2,…,viK)
它可以看成由两部分组成, 其中 w i w_{i} wi 正好和 FM 中的一阶特征对应的权重对应起来, 而 ( v i 1 , v i 2 , … , v i K ) \left(v_{i}^{1}, v_{i}^{2}, \ldots, v_{i}^{K}\right) (vi1,vi2,…,viK) 和 FM 中每个特征对应的隐向量对应起来了. 这样的话. 另外注意到网络结构图中还有一个 w 0 w_0 w0, 可以认为是偏置. 这样的, Embedding Layer 中的权重和 FM 中的权重参数一致, 因此可以使用预训练的 FM 中的权重来初始化网络的 Embedding Layer.
在 https://github.com/Atomu2014/product-nets/blob/master/python/models.py 中实现了 FNN: (这个代码是 PNN 的作者实现的, 有的细节可以查看 Product-based Neural Network (PNN) 介绍与源码浅析, 哈哈, 随时随地打广告 ? ? ?, 原作者的代码基于 Theano 实现, 不太想看~~)
核心代码如下, 非常简单:
num_inputs 是 Field 的个数 for i in range(num_inputs): init_vars.append(('embed_%d' % i, [field_sizes[i], embed_size], 'xavier', dtype)) node_in = num_inputs * embed_size for i in range(len(layer_sizes)): init_vars.append(('w%d' % i, [node_in, layer_sizes[i]], 'xavier', dtype)) init_vars.append(('b%d' % i, [layer_sizes[i]], 'zero', dtype)) node_in = layer_sizes[i] xw 就是 W * x, 得到每个特征对应的 Embedding, 然后 Concat 起来 最后输入到 MLP 中 w0 = [self.vars['embed_%d' % i] for i in range(num_inputs)] xw = tf.concat([tf.sparse_tensor_dense_matmul(self.X[i], w0[i]) for i in range(num_inputs)], 1) l = xw for i in range(len(layer_sizes)): wi = self.vars['w%d' % i] bi = self.vars['b%d' % i] print(l.shape, wi.shape, bi.shape) l = tf.nn.dropout( utils.activate( tf.matmul(l, wi) + bi, layer_acts[i]), self.layer_keeps[i]) l = tf.squeeze(l) self.y_prob = tf.sigmoid(l)
结论
夜里 12:06, 收摊喽~~ ?
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/219881.html原文链接:https://javaforall.net
