申请专栏作者 参展
投稿发布
您的当前位置:主页 > 机器学习 > 正文

推荐系统遇上深度学习 (八)--AFM 模型理论和实践

来源: 时间:2019-09-22
请支持本站,点击下面的广告后浏览!

?

1、引言

在 CTR 预估中,为了解决稀疏特征的问题,学者们提出了 FM 模型来建模特征之间的交互关系。但是 FM 模型只能表达特征之间两两组合之间的关系,无法建模两个特征之间深层次的关系或者说多个特征之间的交互关系,因此学者们通过 Deep Network 来建模更高阶的特征之间的关系。 本文来自可思数据(sykv.com),转载请联系本站及注明出处

因此 FM 和深度网络 DNN 的结合也就成为了 CTR 预估问题中主流的方法。有关 FM 和 DNN 的结合有两种主流的方法,并行结构和串行结构。两种结构的理解以及实现如下表所示: 本文来自可思数据(sykv.com),转载请联系本站及注明出处

016dc1bfb01f4b939f50a0a54d02bbc9.png 可思数据sykv.com,sykv.cn

今天介绍的 AFM 模型 (Attentional Factorization Machine),便是串行结构中一种网络模型。 本文来自可思数据(sykv.com),转载请联系本站及注明出处

2、AFM 模型介绍

我们首先来回顾一下 FM 模型,FM 模型用 n 个隐变量来刻画特征之间的交互关系。这里要强调的一点是,n 是特征的总数,是 one-hot 展开之后的,比如有三组特征,两个连续特征,一个离散特征有 5 个取值,那么 n=7 而不是 n=3.
43518589fa29480c9d9da1fb62979a6c.png 可思数据-数据挖掘,智慧医疗,机器视觉,机器人sykv.com

顺便回顾一下化简过程:
ef1776f620fa47a7a22e1c23d141dd6a.png

可思数据-AI,sykv.com正版天机报图库,深度学习,机器学习,神经网络

可以看到,不考虑最外层的求和,我们可以得到一个 K 维的向量。 可思数据-AI,sykv.com智能驾驶,人脸识别,区块链,大数据

不难发现,在进行预测时,FM 会让一个特征固定一个特定的向量,当这个特征与其他特征做交叉时,都是用同样的向量去做计算。这个是很不合理的,因为不同的特征之间的交叉,重要程度是不一样的。如何体现这种重要程度,之前介绍的 FFM 模型是一个方案。另外,结合了 attention 机制的 AFM 模型,也是一种解决方案。

可思数据-正版天机报图库资讯平台sykv.com

关于什么是 attention model?本文不打算详细赘述,我们这里只需要知道的是,attention 机制相当于一个加权平均,attention 的值就是其中权重,判断不同特征之间交互的重要性。

可思数据-AI,sykv.com智能驾驶,人脸识别,区块链,大数据

刚才提到了,attention 相等于加权的过程,因此我们的预测公式变为:
e2548ab4417f437abb52b1cb03a87b54.png
圆圈中有个点的符号代表的含义是 element-wise product,即:
350374dc88fd4ef08af8385def9a4a2e.png

可思数据-AI,sykv.com正版天机报图库,深度学习,机器学习,神经网络

因此,我们在求和之后得到的是一个 K 维的向量,还需要跟一个向量 p 相乘,得到一个具体的数值。

可思数据-AI,sykv.com智能驾驶,人脸识别,区块链,大数据

可以看到,AFM 的前两部分和 FM 相同,后面的一项经由如下的网络得到:
e5ba770d79f6496590a630968a133a28.png

可思数据sykv.com,sykv.cn

图中的前三部分:sparse iput,embedding layer,pair-wise interaction layer,都和 FM 是一样的。而后面的两部分,则是 AFM 的创新所在,也就是我们的 Attention net。Attention 背后的数学公式如下:
c36dbcc7a7f24a1298c98a07e5b2834e.png

可思数据-正版天机报图库资讯平台sykv.com

总结一下,不难看出 AFM 只是在 FM 的基础上添加了 attention 的机制,但是实际上,由于最后的加权累加,二次项并没有进行更深的网络去学习非线性交叉特征,所以 AFM 并没有发挥出 DNN 的优势,也许结合 DNN 可以达到更好的结果。 可思数据sykv.com

3、代码实现

终于到了激动人心的代码实战环节了,本文的代码有不对的的地方或者改进之处还望大家多多指正。 本文来自可思数据(sykv.com),转载请联系本站及注明出处

本文的 github 地址为: 可思数据-数据挖掘,智慧医疗,机器视觉,机器人sykv.com

https://github.com/princewen/tensorflow_practice/tree/master/recommendation/Basic-AFM-Demo 可思数据sykv.com

本文的代码根据之前 DeepFM 的代码进行改进,我们只介绍模型的实现部分,其他数据处理的细节大家可以参考我的 github 上的代码. 可思数据-数据挖掘,智慧医疗,机器视觉,机器人sykv.com

在介绍之前,我们先定义几个维度,方便下面的介绍: 可思数据sykv.com

Embedding Size:K

可思数据-正版天机报图库资讯平台sykv.com

Batch Size:N 可思数据-正版天机报图库资讯平台sykv.com

Attention Size :A 可思数据-www.sykv.cn,sykv.com

Field Size ( 这里是 field size 不是 feature size!!!!): F 可思数据-www.sykv.cn,sykv.com

模型输入 可思数据-AI,sykv.com智能驾驶,人脸识别,区块链,大数据

模型的输入主要有下面几个部分: 可思数据-AI,sykv.com正版天机报图库,深度学习,机器学习,神经网络


  • 本文地址:http://www.6aiq.com/article/1547806920160
  • 本文版权归作者和AIQ共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
  • 知乎专栏 点击关注

self.feat_index = tf.placeholder(tf.int32,
 shape=[None,None],
 name='feat_index')
self.feat_value = tf.placeholder(tf.float32,
 shape=[None,None],
 name='feat_value')

self.label = tf.placeholder(tf.float32,shape=[None,1],name='label')
self.dropout_keep_deep = tf.placeholder(tf.float32,shape=[None],name='dropout_deep_deep')

 
可思数据-AI,sykv.com智能驾驶,人脸识别,区块链,大数据

feat_index是特征的一个序号,主要用于通过 embedding_lookup 选择我们的 embedding。feat_value是对应的特征值,如果是离散特征的话,就是 1,如果不是离散特征的话,就保留原来的特征值。label 是实际值。还定义了 dropout 来防止过拟合。

可思数据sykv.com

权重构建 可思数据-AI,sykv.com智能驾驶,人脸识别,区块链,大数据

权重主要分以下几部分,偏置项,一次项权重,embeddings,以及 Attention 部分的权重。除 Attention 部分的权重如下:

可思数据-www.sykv.cn,sykv.com

def _initialize_weights(self):
 weights = dict()

 #embeddings
 weights['feature_embeddings'] = tf.Variable(
 tf.random_normal([self.feature_size,self.embedding_size],0.0,0.01),
 name='feature_embeddings')
 weights['feature_bias'] = tf.Variable(tf.random_normal([self.feature_size,1],0.0,1.0),name='feature_bias')
 weights['bias'] = tf.Variable(tf.constant(0.1),name='bias')

 可思数据sykv.com 

Attention 部分的权重我们详细介绍一下,这里共有四个部分,分别对应公式中的 w,b,h 和 p。

可思数据sykv.com,sykv.cn

weights[‘attention_w’] 的维度为 K * A, 内容来自可思数据sykv.com

weights[‘attention_b’] 的维度为 A,

可思数据sykv.com,sykv.cn

weights[‘attention_h’] 的维度为 A, 可思数据-AI,sykv.com正版天机报图库,深度学习,机器学习,神经网络

weights[‘attention_p’] 的维度为 K * 1

可思数据sykv.com,sykv.cn

# attention part
glorot = np.sqrt(2.0 / (self.attention_size + self.embedding_size))

weights['attention_w'] = tf.Variable(np.random.normal(loc=0,scale=glorot,size=(self.embedding_size,self.attention_size)),
                                     dtype=tf.float32,name='attention_w')

weights['attention_b'] = tf.Variable(np.random.normal(loc=0,scale=glorot,size=(self.attention_size,)),
                                     dtype=tf.float32,name='attention_b')

weights['attention_h'] = tf.Variable(np.random.normal(loc=0,scale=1,size=(self.attention_size,)),
                                     dtype=tf.float32,name='attention_h')


weights['attention_p'] = tf.Variable(np.ones((self.embedding_size,1)),dtype=np.float32)
 
可思数据-AI,sykv.com正版天机报图库,深度学习,机器学习,神经网络

Embedding Layer
这个部分很简单啦,是根据 feat_index 选择对应的 weights[‘feature_embeddings’] 中的 embedding 值,然后再与对应的 feat_value 相乘就可以了: 可思数据-数据挖掘,智慧医疗,机器视觉,机器人sykv.com

# Embeddings
self.embeddings = tf.nn.embedding_lookup(self.weights['feature_embeddings'],self.feat_index) # N * F * K
feat_value = tf.reshape(self.feat_value,shape=[-1,self.field_size,1])
self.embeddings = tf.multiply(self.embeddings,feat_value) # N * F * K

 
可思数据-AI,sykv.com正版天机报图库,深度学习,机器学习,神经网络

Attention Net
Attention 部分的实现严格按照上面给出的数学公式:

内容来自可思数据sykv.com

d4b0a62014314a8489a1243cece35d85.png
这里我们一步步来实现。 可思数据-AI,sykv.com智能驾驶,人脸识别,区块链,大数据

对于得到的 embedding 向量,我们首先需要两两计算其 element-wise-product。即: 可思数据-数据挖掘,智慧医疗,机器视觉,机器人sykv.com

210074809d7547dc9882d8fcafcb154e.png

内容来自可思数据sykv.com

通过嵌套循环的方式得到的结果需要通过 stack 将其变为一个 tenser,此时的维度为 (F * F - 1 / 2) * N* K,因此我们需要一个转置操作,来得到维度为 N * (F * F - 1 / 2) * K 的 element-wize-product 结果。

可思数据-数据挖掘,智慧医疗,机器视觉,机器人sykv.com

element_wise_product_list = []
for i in range(self.field_size):
    for j in range(i+1,self.field_size):
        element_wise_product_list.append(tf.multiply(self.embeddings[:,i,:],self.embeddings[:,j,:])) # None * K

self.element_wise_product = tf.stack(element_wise_product_list) # (F * F - 1 / 2) * None * K
self.element_wise_product = tf.transpose(self.element_wise_product,perm=[1,0,2],name='element_wise_product') # None * (F * F - 1 / 2) *  K

 

可思数据-www.sykv.cn,sykv.com

得到了 element-wise-product 之后,我们接下来计算:
355ac9336b074bdcbde429d7482b9cbc.png
计算之前,我们需要先对 element-wise-product 进行 reshape,将其变为二维的 tensor,在计算完之后再变换回三维 tensor,此时的维度为 N * (F * F - 1 / 2) * A: 内容来自可思数据sykv.com

self.attention_wx_plus_b = tf.reshape(tf.add(tf.matmul(tf.reshape(self.element_wise_product,shape=(-1,self.embedding_size)),
 self.weights['attention_w']),
 self.weights['attention_b']),
 shape=[-1,num_interactions,self.attention_size]) # N * ( F * F - 1 / 2) * A

 
本文来自可思数据(sykv.com),转载请联系本站及注明出处

然后我们计算: 可思数据-正版天机报图库资讯平台sykv.com

本文来自可思数据(sykv.com),转载请联系本站及注明出处

此时的维度为 N * (F * F - 1 / 2) * 1

内容来自可思数据sykv.com

self.attention_exp = tf.exp(tf.reduce_sum(tf.multiply(tf.nn.relu(self.attention_wx_plus_b),
 self.weights['attention_h']),
 axis=2,keep_dims=True)) # N * ( F * F - 1 / 2) * 1
 本文来自可思数据(sykv.com),转载请联系本站及注明出处 

然后计算: 可思数据-AI,sykv.com智能驾驶,人脸识别,区块链,大数据

可思数据-正版天机报图库资讯平台sykv.com

这一层相当于 softmax 了,不过我们还是用基本的方式写出来:

可思数据sykv.com,sykv.cn
self.attention_exp_sum = tf.reduce_sum(self.attention_exp,axis=1,keep_dims=True) # N * 1 * 1

self.attention_out = tf.div(self.attention_exp,self.attention_exp_sum,name='attention_out') # N * ( F * F - 1 / 2) * 1

 
可思数据-正版天机报图库资讯平台sykv.com

最后,我们计算得到经 attention net 加权后的二次项结果:

内容来自可思数据sykv.com

可思数据-www.sykv.cn,sykv.com

self.attention_x_product = tf.reduce_sum(tf.multiply(self.attention_out,self.element_wise_product),axis=1,name='afm') # N * K

self.attention_part_sum = tf.matmul(self.attention_x_product,self.weights['attention_p']) # N * 1

 

内容来自可思数据sykv.com

得到预测输出
为了得到预测输出,除 Attention part 的输出外,我们还需要两部分,分别是偏置项和一次项:

可思数据sykv.com,sykv.cn
# first order term
self.y_first_order = tf.nn.embedding_lookup(self.weights['feature_bias'], self.feat_index)
self.y_first_order = tf.reduce_sum(tf.multiply(self.y_first_order, feat_value), 2)

# bias
self.y_bias = self.weights['bias'] * tf.ones_like(self.label)
 内容来自可思数据sykv.com 

而我们的最终输出如下:

本文来自可思数据(sykv.com),转载请联系本站及注明出处
# out
self.out = tf.add_n([tf.reduce_sum(self.y_first_order,axis=1,keep_dims=True),
                     self.attention_part_sum,
                     self.y_bias],name='out_afm')

 

可思数据-正版天机报图库资讯平台sykv.com

剩下的代码就不介绍啦!
好啦,本文只是提供一个引子,有关 AFM 的知识大家可以更多的进行学习呦。 可思数据-AI,sykv.com智能驾驶,人脸识别,区块链,大数据

?

可思数据-数据挖掘,智慧医疗,机器视觉,机器人sykv.com

转发量:

网友评论:

发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片 匿名?

关于我们?? 免责声明?? 广告合作?? 版权声明?? 联系方式?? 原创投稿?? 网站地图??

Copyright?2005-2019 Sykv.com 可思数据 版权所有 ?? ICP备案:京ICP备14056871号

正版天机报图库资讯?? 正版天机报图库资讯?? 正版天机报图库资讯?? 正版天机报图库资讯

?扫码入群
咨询反馈
扫码关注

微信公众号

返回顶部
关闭