IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 再看Attention之细节问题 -> 正文阅读

[人工智能]再看Attention之细节问题

作者:recommend-item-box type_blog clearfix

hi我是CIA小明哥,简称菜鸟小明哥,之前对Attention的了解不深,这次再来一遍,温故而知新,主要是其中的代码实现问题【不区分具体哪个版本啥的,按最简单的来】

For Recommendation in Deep learning QQ Second Group 102948747
For Visual in deep learning QQ Group 629530787
I'm here waiting for you?

不接受这个网页的私聊/私信!!
本宝宝长期征集真实情感经历(发在我公号:美好时光与你同行),长期接受付费咨询(啥问题都可),付费改代码。

付费咨询,专属服务,快人一步!!!
1-根据help再次理解Attention

 |  1. Calculate scores with shape `[batch_size, Tq, Tv]` as a `query`-`key` dot
 |     product: `scores = tf.matmul(query, key, transpose_b=True)`.
 |  2. Use scores to calculate a distribution with shape
 |     `[batch_size, Tq, Tv]`: `distribution = tf.nn.softmax(scores)`.
 |  3. Use `distribution` to create a linear combination of `value` with
 |     shape `[batch_size, Tq, dim]`:
 |     `return tf.matmul(distribution, value)`.

三步走:计算query和key的点积(这个就是个打分),然后由点积得到分布(由softmax计算得到),由计算得到的分布与value得到最终的结果。关于上次解说的SRGNN中attention用法,我觉得还有点问题,主要是query没有明确说明是啥子(可以再看下链接),这个我查看了原paper也没找到,查看了原作者代码也没看懂,而且一头雾水,这个十分懵逼【或许这就是屏蔽中下水平的】

从shape上来说,这个query的shape必然与session的embedding shape相同,如下示例:

query=tf.Variable(tf.keras.initializers.get('uniform')(shape=[1000,1,4]))
value=tf.Variable(tf.keras.initializers.get('uniform')(shape=[1000,16,4]))

res=tf.keras.layers.Attention()([query,value])
>>> res
<tf.Tensor: shape=(1000, 1, 4), dtype=float32, numpy=
array([[[-0.00338019,  0.00189824, -0.0002874 , -0.00784647]],

       [[-0.00513936,  0.00389516,  0.00647767, -0.00183488]],

       [[ 0.00516016,  0.01167186, -0.01381158, -0.0025348 ]],

       ...,

       [[ 0.0104752 , -0.00862713,  0.00424046, -0.00106742]],

       [[ 0.00435216,  0.00232145,  0.00339274,  0.00424616]],

       [[-0.0039812 ,  0.00517946,  0.00704541,  0.00448983]]],
      dtype=float32)>

释义:16个点击的item聚合成一个session,item及session的emb_size=4

参考网络上attention自定义的函数,可得同样的shape,

attention3(tf.squeeze(query,1),value,[1]*1000)
<tf.Tensor: shape=(1000, 1, 4), dtype=float32, numpy=
array([[[-0.02236429,  0.02304715, -0.04459522,  0.03128466]],

       [[-0.03680242, -0.03430416, -0.0360697 , -0.0039628 ]],

       [[-0.00501503, -0.006629  , -0.04473983, -0.011972  ]],

       ...,

       [[ 0.02507205, -0.01383727, -0.02684764, -0.00787603]],

       [[-0.02620304, -0.02197758, -0.0469028 , -0.04654911]],

       [[-0.01396894,  0.0357385 ,  0.0449436 , -0.03041291]]],
      dtype=float32)>

其中最后一个变量为value的长度,其真实理解参考这个博文,意为:每1000个user为一个batch,其中每个user的点击序列最大为16,那么序列中不够16的就要补零,因此需要知道真实的item个数,即value的长度,其值应该最大为16

2-SRGNN中的Attention如何改?

根据我用的版本,我看了这部分并不是用的Attention,至少不是attention上面的定义那种,而是直接相加除以个数,尽管这点与attention整个流程差别不大,但我改成self attention应该可以试试。

将item embeding的均值视为query进行attention(用均值这个我觉得也可以从数学含义来理解吧,毕竟也不是毫无意义的,也比其他采用CNN等方式得到的有意义多了),然后直接采用Attention函数进行尝试。

最终结果:似乎没啥子差别啊,因为生成的训练集可能是不同的【下面回答了这个问题】

#my results
(161848, 24)
(164988, 24)
all_cpu function cost: 0.025261s
mid degree= 800 length= 161848
answer length, 161848
evaluate_score function cost: 1.160040s
[0.0441067  0.22833152 0.02539149 0.08006249 0.00597751]

#old version
(161848, 24)
(164988, 24)
all_cpu function cost: 0.020104s
mid degree= 800 length= 161848
answer length, 161848
evaluate_score function cost: 1.171112s
[0.04728771 0.22843656 0.01959937 0.0824017  0.00446279]

#稍微增加点数据量
#my results #90min
(178744, 24)
(166144, 24)
all_cpu function cost: 0.020473s
mid degree= 809 length= 178744
answer length, 178744
evaluate_score function cost: 1.374818s
[0.04293859 0.2293951  0.0251032  0.07909438 0.00599198]

#old version#84min
(178744, 24)
(166144, 24)
all_cpu function cost: 0.024985s
mid degree= 809 length= 178744
answer length, 178744
evaluate_score function cost: 1.302567s
[0.04529781 0.22891398 0.02311195 0.08095484 0.00557914]

关于训练集是否相同,这里做个测试验证,由于是采用的random获取的随机样本,那么这里测试下:多次执行的结果是一样的,说明训练集应该是相同的。【又加了一层循环结果仍旧是一样的】

$ python random_test_.py 
[6, 34, 11, 52, 78, 13, 4, 48, 68, 42, 43, 79]
[20, 17, 43, 71, 42, 31, 79, 0, 55, 11, 48, 8]
[0, 40, 57, 13, 5, 11, 18, 16, 2, 37, 55, 61]
[33, 60, 4, 39, 43, 66, 61, 26, 67, 40, 1, 50]

$ python random_test_.py 
[6, 34, 11, 52, 78, 13, 4, 48, 68, 42, 43, 79]
[20, 17, 43, 71, 42, 31, 79, 0, 55, 11, 48, 8]
[0, 40, 57, 13, 5, 11, 18, 16, 2, 37, 55, 61]
[33, 60, 4, 39, 43, 66, 61, 26, 67, 40, 1, 50]

由于增加了attention,多了计算量,所以时间稍长了点。

【补充0811】关于将均值视为query可能有一定的局限,一般来说应该将最后一个item的emb视为query,再次尝试。

效果似乎是差的,因此均值还是有一定的效果。

(178744, 24)
(166144, 24)
all_cpu function cost: 0.010592s
mid degree= 809 length= 178744
answer length, 178744
evaluate_score function cost: 1.271092s
[0.04128582 0.22607751 0.02650155 0.07752591 0.00639287]

3-DIN中Attention如何改?

最近的任务是加特征啊,没特征纯ID的embedding已经不行了,其实我的想法和DIN作者是一直的,不加特征才是真正的高手,因为ID本就表示隐藏的群众智慧,用户喜欢看那就说明这个id好,加上特征反而有种多此一举的感觉,当然也就会陷入特征的无限组合与改进(交叉啥的),这种才是没有任何解释性。

然而原代码是用tf1写的将其中函数直接改为tf2的不行,因为有reuse这个,所以要改成tf.keras.Model这种形式才可以,当然tf2也可只用一个GPU。其中有BN和Dense层反复使用,而且Dense中的参数也是一样的,是否可以用一样的初始化放在init?我觉得可以一试,但是tf1到tf2要改动placeholder及loss,这个烦死了。那么本文就不再细说这部分了,详见DIN分布式训练(待续)。

回归正题,增加特征啊,what the fuck !

4-ComiRec中的Attention怎么改?

【0801】参考din的做法将cate_emb拼接到item_emb只得到如下最优的效果,【注意得到的emb不要进行norm,norm后的结果反而差】在comirec中

[0.03017408 0.23074329 0.06357089 0.06946561 0.01762796]

位置权重改为glorot_uniform反而比全是正的效果好一点

[0.03157817 0.23335858 0.06607778 0.07114853 0.01890373]

位置权重不加效果有点差,所以必须要。

【0806】考虑到时间问题,可能在不同时间,用户的喜好的类别会发生变化,因此有必要固定user侧的数据。

回归正题,下面需要读懂原作者代码,以及充分发挥聪明才智,才能将作者写的代码改成Attention函数的形式。【我使用的就是ComiRec-SA,另外一个效果不怎么好,SA即为self-attention】

【0812】将mask与item点击序列的emb相乘得到的结果就是item序列的emb,这个emb经过处理(attention或dense或mean等)就得到user的emb,表示用户的喜好。

有的将item点击序列的emb经过一些处理(比如dense)再与mask相乘,后再与item序列emb相乘得到user的emb,不用attention看下效果,如下,【采用的新的数据集】

[0.05328959 0.28999886 0.07196955 0.09957801 0.01879087]

比用attention的效果(如下)差点,但也可接受

[0.054718,0.2933,0.074638,0.10140117,0.0194518]

但这部分是是attention的全部么?我感觉不是,因为后面还有softmax,这部分才是attention的关键点:由user及item的emb相乘得到分数,然后经softmax得到归一化后的结果,选出分数最大的为最终的emb(按照attention的思想,应该是各个emb与分数的加权和,也就是均值),这个emb具体是什么要参考之前的ytb,因为放入了sample_softmax进行训练。

经查看help结果与该博文详细介绍,这个emb是inputs,对应的是user的embedding(多兴趣中最值最大的,ComiRec代码是这样的),至此,即复习了旧的知识,也掌握新的知识,融会贯通只在一刹那。

下面要做的是将attention的结果视为最终的user_embedding,结果如下:此时的query为item embedding,key=value为user多兴趣的embedding。

4.1将最终上述user_emb最为sample_softmax_loss的输入inputs,而eval时仍旧采用user多个embedding,如下

[0.03615532 0.17327368 0.00076964 0.06306674 0.00017446]

效果有点差啊。

4.2将最终user_emb作为eval时的user的emb,结果如下:

[0.00607047 0.03211236 0.0214467  0.0111672  0.00549694]

效果更差了。我天,那么这其中就是ComiRec多兴趣的一个关键点了,这也是这篇文章发表的idea,当然也可能是我没有正确理解代码及其中的含义,下周再见。

愿我们终有重逢之时,而你还记得我们曾经讨论的话题。

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-08-14 14:01:52  更:2021-08-14 14:03:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/17 3:57:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码