深度学习 - 51.推荐场景下的 Attention And Multi-Head Attention 简单实现 By Keras

这篇具有很好参考价值的文章主要介绍了深度学习 - 51.推荐场景下的 Attention And Multi-Head Attention 简单实现 By Keras。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一.引言

二.计算流程

1.Attention 结构

2.Multi-Head Attention 结构

三.计算实现

1.Item、序列样本生成

2.OwnAttention Layer 实现

2.1 init 初始化

2.2 build 参数构建

2.3 call 逻辑调用

3.OwnAttention Layer 测试

四.总结


一.引言

Attention And Multi-Head Attention 一文中我们简单介绍了 Attention 与 Multi-Head Attention 在推荐场景下的计算,本文通过 Keras 自定义 Layer 的方式,实现 OwnAttention Layer 实现两种 Attention 的功能。

二.计算流程

1.Attention 结构

深度学习 - 51.推荐场景下的 Attention And Multi-Head Attention 简单实现 By Keras

• 输入

Query 为候选 Item

Keys 为用户行为序列 Goods id,key_i 代表第 i 个行为 good

Values 与 Keys 相同

• 计算

lookup 获取 query、keys、values 向量

query 向量 + keys 向量通过 ActivationUnit 获取每个 key_i 对应的权重 weight_i

weight_i softmax 归一化,此步骤可选

将 weight_i 与 value_i  加权平均得到 Attention Output

2.Multi-Head Attention 结构

深度学习 - 51.推荐场景下的 Attention And Multi-Head Attention 简单实现 By Keras

• 输入

Query 为候选 Item

Keys 为用户行为序列 Goods id,key_i 代表第 i 个行为 good

Values 与 Keys 相同

• 计算

lookup 获取 query、keys、values 向量

原始向量先经过一次 Linear 层

根据 head 的数量,将向量 Split 分为多个子向量,代表不同子空间

每一个 Head 下的子向量执行 Scaled Dot-Product Attention 得到权重 Weight

与子空间 Value 加权平均得到输出

输出再通过一次 Linear 层并 Concat 得到  Attention Output

三.计算实现

1.Item、序列样本生成

def genSamples(_batch_size=5, _T_k=10, _N=1000, seed=0):
    np.random.seed(seed)
    # 用户历史序列
    user_history = np.random.randint(0, N, size=(batch_size, _T_k))
    # 候选 Item
    user_candidate = np.random.randint(0, N, size=(batch_size, 1))
    return user_history, user_candidate

batch_size 为样本数,T_k 为行为数,N 为 Goods 总数,模拟数据,主要为了跑通逻辑:

    # 用户历史行为序列 && 候选商品 ID
    batch_size, T_k, N = 5, 10, 1000
    history, candidate = genSamples(batch_size, T_k, N)
    print(history[0:5])
    print(candidate[0:5])

深度学习 - 51.推荐场景下的 Attention And Multi-Head Attention 简单实现 By Keras

2.OwnAttention Layer 实现

2.1 init 初始化

import numpy as np
import tensorflow as tf
from tensorflow.python.keras.layers import *
from tensorflow.keras.layers import Layer

class OwnAttention(Layer):

    def __init__(self, _mode='Attention', _is_weight_normalization=True, **kwargs):
        self.activation_unit = None
        self.DNN = None
        self.LastDNN = None
        self.kernel = None
        self.N = 10000
        self.T_k = 10
        self.emd_dim = 8
        self.num_heads = 2
        self.mode = _mode
        self.is_weight_normalization = _is_weight_normalization
        super().__init__(**kwargs)

N、T_k、emd_dim 分别代表商品库大小、序列长度与向量维度

mode 供分两种 'Attention' 与 'Multi-Head Attention' 分别代表两种 Attention 模式

is_weight_normalization 权重是否归一化,这个根据自己场景与内积的量纲决定

2.2 build 参数构建

    def build(self, input_shape):
        # 获取 Item 向量
        self.kernel = self.add_weight(name='seq_emb',
                                      shape=(self.N, self.emd_dim),
                                      initializer='he_normal',
                                      trainable=True)
        # Multi-Head Linear
        self.DNN = Dense(self.emd_dim, activation='relu')
        self.LastDNN = Dense(self.emd_dim, activation='relu')

        # Activation Unit
        self.activation_unit = Dense(1, activation='relu')

        super(OwnAttention, self).build(input_shape)

kernel 为商品 id 对应的 Embedding 层,维度为 N x emd_dim

DNN 为 Multi-Head 的首层 Linear

LastDNN 为 Multi-Head 的末层 Linear

activation_unit 用于计算加权权重

Tips:

关于 activation_unit,除了上面的简单实现外,还可以加入 goods 对应的 Position Embedding 或者加入其它 SideInfo 侧信息辅助决策。

2.3 call 逻辑调用

    def call(self, inputs, **kwargs):
        _history, _candidate = inputs

        Q = tf.nn.embedding_lookup(self.kernel, _candidate)
        K = tf.nn.embedding_lookup(self.kernel, _history)
        V = tf.nn.embedding_lookup(self.kernel, _history)

        print("Q Shape: %s \nK Shape: %s \nV Shape: %s" % (Q.shape, K.shape, V.shape))

第一步 lookup 获取 id 对应的 Embedding,BS=5、T_k=1、emd_dim=8:

Q Shape: (5, 1, 8) 
K Shape: (5, 10, 8) 
V Shape: (5, 10, 8)

• mode = 'Attention'

        if self.mode == 'Attention':
            # 获取 Attention 权重
            # [None, T_k, emd_dim] -> [None, T_k, 1] -> [None, 1, T_k]
            din_out = self.activation_unit(K)
            din_out = tf.transpose(din_out, (0, 2, 1))

            # 构建 Mask [None, 1, T_k]
            seq_mask = tf.equal(_history, tf.zeros_like(_history))
            seq_mask = tf.expand_dims(seq_mask, axis=1)

            # 权重归一化, 权重不使用 softmax 归一化则默认为 0 填充 [None, 1, T_k]
            if self.is_weight_normalization:
                paddings = tf.ones_like(din_out) * (-2 ** 32 + 1)
            else:
                paddings = tf.zeros_like(din_out)

            # 归一化 + Padding 的 Attention 权重 [None, 1, T_k]
            din_out = tf.where(seq_mask, paddings, din_out)

            if self.is_weight_normalization:
                din_out = tf.nn.softmax(din_out, axis=2)

            # Attention 输出
            output = tf.matmul(din_out, V)
            output = tf.squeeze(output)
            return output

计算逻辑与维度可参考上面的文字注释,这里增加了 padding 与 weight_normalization,din_out 为最终的加权权重,V 为 values 即 lookup 得到的序列 Embedding。

• mode = 'Multi-Head Attention'

        elif self.mode == 'Multi-Head Attention':

            # Linear
            Q = self.DNN(Q)  # [None, T_q, emd_dim]
            K = self.DNN(K)  # [None, T_k, emd_dim]
            V = self.DNN(V)  # [None, T_k, emd_dim]

            # Split And Concat
            Q_ = tf.concat(tf.split(Q, self.num_heads, axis=2), axis=0)  # [h*None, T_q, emd_dim/h]
            K_ = tf.concat(tf.split(K, self.num_heads, axis=2), axis=0)  # [h*None, T_k, emd_dim/h]
            V_ = tf.concat(tf.split(V, self.num_heads, axis=2), axis=0)  # [h*None, T_k, emd_dim/h]

            # Scaled Dot-Product
            # [h*None, T_q, emd_dim/h] x [h*None, emd_dim/h, T_k] -> [h*None, T_q, T_k]
            d_k = Q_.shape[-1]
            weight = tf.matmul(Q_, tf.transpose(K_, [0, 2, 1]))
            weight = weight / (d_k ** 0.5)
            weight = tf.nn.softmax(weight)

            # Weighted-Sum
            # [h*None, T_q, T_k] * [h*None, T_k, emd_dim/h] -> [h*None, T_q, emd_dim/h]
            weighted = tf.matmul(weight, V_)
            print("Weight Shape: %s Value Shape: %s Weighted-Sum Shape: %s" % (weight.shape, V_.shape, weighted.shape))

            # Concat && Linear
            # [None, T_q, emd_dim]
            concat = tf.squeeze(tf.concat(tf.split(weighted, self.num_heads, axis=0), axis=2))
            multiHeadOutput = self.LastDNN(concat)

            return multiHeadOutput

Split 负责根据 head 数量将原始向量拆分为多个向量子空间,d_k 为缩放系数,这个可以根据自己场景决定,与上面 Attention 不同的是前后增加了两个 Linear 层,除此之外,实际应用时这里可能还需要 Paddiing 与 Dropout。

3.OwnAttention Layer 测试

• mode = 'Attention'

    mode = 'Attention'
    attention = OwnAttention(mode)
    attention_output = attention([history, candidate])
    print("%s Output Shape: %s" % (mode, attention_output.shape))
Attention Output Shape: (5, 8)

• mode = 'Multi-Head Attention'

    mode = 'Multi-Head Attention'
    attention = OwnAttention(mode)
    attention_output = attention([history, candidate])
    print("%s Output Shape: %s" % (mode, attention_output.shape))
Weight Shape: (10, 1, 10) Value Shape: (10, 10, 4) Weighted-Sum Shape: (10, 1, 4)
Multi-Head Attention Output Shape: (5, 8)

四.总结

实现的比较简单,主要是粗略了解 Attention 与 Multi-Head Attention 的实现流程,实际应用场景下,如果 Goods 商品库的 N 太大,也可以采用 Hash 的方式,在牺牲一定性能的情况下弥补工程上的不足。

更多推荐算法相关深度学习:深度学习导读专栏 文章来源地址https://www.toymoban.com/news/detail-464685.html

到了这里,关于深度学习 - 51.推荐场景下的 Attention And Multi-Head Attention 简单实现 By Keras的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 毕业设计选题-计算机视觉:复杂场景下的车牌识别系统 人工智能 深度学习 YOLO

    目录 前言 项目背景与简介 主要设计思路 一、算法理论技术 1.1 神经网络基础 1.2 深度神经网络 1.3 目标检测 二、数据处理 2.1 数据采集 三、实现的效果 更多帮助     📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设

    2024年02月03日
    浏览(48)
  • 深度学习10:Attention 机制

    目录 Attention 的本质是什么 Attention 的3大优点 Attention 的原理 Attention 的 N 种类型 Attention(注意力)机制如果浅层的理解,跟他的名字非常匹配。他的核心逻辑就是「 从关注全部到关注重点 」。   Attention 机制很像人类看图片的逻辑,当我们看一张图片的时候,我们并没有看

    2024年02月11日
    浏览(27)
  • 关于深度学习中Attention的一些简单理解

    Attention 机制 Attention应用在了很多最流行的模型中,Transformer、BERT、GPT等等。 Attention就是计算一个加权平均 ;通过加权平均的权值来自计算每个隐藏层之间的相关度; 示例 Attention 机制 Attention应用在了很多最流行的模型中,Transformer、BERT、GPT等等。 Attention就是计算一个加权

    2024年02月08日
    浏览(29)
  • 联邦学习:联邦场景下的域泛化

    域泛化(domain generalization, DG) [1][2] 旨在从多个源域中学习一个能够泛化到未知目标域的模型。形式化地说,给定 (K) 个训练的源域数据集 (mathcal{S}=left{mathcal{S}^k mid k=1, cdots, Kright}) ,其中第 (k) 个域的数据被表示为 (mathcal{S}^k = left{left(x_i^k, y_i^kright)right}_{i=1

    2024年02月04日
    浏览(35)
  • 深入理解深度学习——注意力机制(Attention Mechanism):位置编码(Positional Encoding)

    分类目录:《深入理解深度学习》总目录 相关文章: ·注意力机制(AttentionMechanism):基础知识 ·注意力机制(AttentionMechanism):注意力汇聚与Nadaraya-Watson核回归 ·注意力机制(AttentionMechanism):注意力评分函数(AttentionScoringFunction) ·注意力机制(AttentionMechanism):Bahda

    2024年02月08日
    浏览(35)
  • 基于深度学习的轴承寿命预测实践,开发CNN、融合LSTM/GRU/ATTENTION

    关于轴承相关的项目之前做的大都是故障识别诊断类型的,少有涉及回归预测的,周末的时候宅家发现一个轴承寿命加速实验的数据集就想着拿来做一下寿命预测。 首先看下数据集如下: 直接百度即可搜到,这里就不再赘述了。 Learning_set为训练集 Test_set为测试集 我这里为了

    2024年02月02日
    浏览(38)
  • 【深度学习-注意力机制attention 在seq2seq中应用】

    这是一个普通的seq2seq结构,用以实现机器对话,Encoder需要把一个输入的一个句子转化为一个最终的输出,上下文context vector,然后在Decoder中使用,但这里有些问题: 如果句子很长,这个向量很难包含sequence中最早输入的哪些词的信息,那么decoder的处理必然也缺失了这一部分

    2024年02月09日
    浏览(34)
  • youtobe深度学习推荐系统-学习笔记

    前言 本文是 Deep Neural Networks for YouTube Recommendations 论文的学习笔记。淘宝的召回模型曾经使用过这篇论文里面的方案,后续淘宝召回模型升级到了MGDSPR:多粒度深度语义商品检索。 转向深度学习 和谷歌的其他产品一样,you2b也经历了向深度学习转变的过程。矩阵分解技术在推

    2024年02月08日
    浏览(31)
  • 《深度学习推荐系统》笔记

    把相关内容整成了思维导图, 大家自提~ 用户角度 :解决”信息过载“的情况下,用户如何高效获得感兴趣信息; 公司角度 :解决产品能最大限度地吸引用户、留存用户、增加用户粘性、提高用户转化率,使公司商业目标连续增长。 2.1 逻辑架构 已知用户信息、物品信息和

    2024年02月16日
    浏览(27)
  • 深度学习论文: Rethinking Mobile Block for Efficient Attention-based Models及其PyTorch实现

    深度学习论文: Rethinking Mobile Block for Efficient Attention-based Models及其PyTorch实现 Rethinking Mobile Block for Efficient Attention-based Models PDF: https://arxiv.org/pdf/2301.01146.pdf PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: https://github.com/shanglianlm0525/PyTorch-Networks EMO是高效、轻量级的模型

    2024年02月09日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包