【序列召回推荐】(task6)多兴趣召回Comirec-SA

news2024/11/24 14:30:05

note

  • Comirec-SA基于attention的多兴趣建模,论文中先通过attention提取单一兴趣,再推广到多兴趣建模。另外使用贪心算法优化带有准确度+多样性的目标函数。
  • DR把MIND的attention换成argmax(还有初始化方式不同、序列胶囊到兴趣胶囊用可学习权重矩阵替代的不同),SR则本质是多头注意力进行多兴趣建模。
  • torch.einsum(Einstein summation convention,即爱因斯坦求和约定)可以写tensor运算和更高维度tensor写法更加简洁,如用torch.einsum("bij, bjk -> bik", batch_tensor_1, batch_tensor_2)进行batch内矩阵乘法运算。

文章目录

  • note
  • 一、Comirec模型概览
    • 1.1 Notation
    • 1.2 模型框架
    • 1.3 model training
  • 二、Comirec-SA模型
    • 2.0 数据集划分
    • 2.1 基于Attention的单一兴趣建模
    • 2.2 基于Attention的多兴趣建模
      • (1)K-Q-V注意力
        • 1)自注意力机制
        • 2)计算 K-Q-V 注意力(矩阵形式):
    • 2.3 多样性控制
  • 三、代码实践
    • 3.1 MultiInterest_SA类定义
    • 3.2 einsum函数的用法
    • 3.3 Comirec-SA类定义
  • 时间安排
  • Reference

一、Comirec模型概览

第一部分和task5差不多,是同一篇论文Comirec-SA用self-attentive method代替之前DR多兴趣抽取层,
在这里插入图片描述
Comirec:Controllable Multi-Interest Framework for Recommendation
论文链接:https://arxiv.org/abs/2005.09347
在这里插入图片描述
Comirec是阿里发表在KDD 2020上的一篇工作,这篇论文对MIND多行为召回进行了扩展:

  • 一方面改进了MIND中的动态路由算法,
  • 另一方面提出了一种新的多兴趣召回方法,同时对推荐的多样性层面也做出了一定的贡献,通过一种贪心的做法,在损失较小的推荐效果的情况下可以显著的提高推荐的多样性(感觉非常非常牵强,我们这里就不介绍这个了),从而极大的提高用户的使用体验,可以更进一步的探索用户的潜在兴趣。

1.1 Notation

假设一个用户集合 u ∈ U u \in \mathcal{U} uU 和一个物品集合 i ∈ I i \in \mathcal{I} iI, 对于每一个用户, 定义用户序列 ( e 1 ( u ) , e 2 ( u ) , … , e n ( u ) ) \left(e_1^{(u)}, e_2^{(u)}, \ldots, e_n^{(u)}\right) (e1(u),e2(u),,en(u)), 根据时间先后顺序排序,其中 e t ( u ) e_t^{(u)} et(u) 记录了第 t t t 个物品与用户交互。

在这里插入图片描述

1.2 模型框架

在这里插入图片描述
Comirec流程和MIND类似:

  • 用户历史交互item ids经过embedding layer转为item embeddings;
  • 把刚才的item embedding经过多兴趣抽取层(这里是self-attentive模块),得到K个interest embeddings;
  • training:和之前MIND说的做法一样(取内积最大值),即选出与target item embedding最接近的interest embeddings,基于多分类任务,使用负采样sampled softmax loss;
  • serving(predict):对于每个用户的K个interest embedding进行top-N检索,即召回K X N个item。
  • aggregation module:将K X N个item送入该模块得到N个item(选内积分数最高的N个,和MIND做法一致): f ( u , i ) = max ⁡ 1 ≤ k ≤ K ( e i ⊤ v u ( k ) ) f(u, i)=\max _{1 \leq k \leq K}\left(\mathbf{e}_i^{\top} \mathbf{v}_u^{(k)}\right) f(u,i)=1kKmax(eivu(k))

1.3 model training

和1.1说的一样,某用户经过多兴趣提取层后得到K个interest embeddings后,从中找出和target item i(即下面embedding为 e i e_i ei)最接近,即内积最大的一个interest embeeding,方法如下 v u = V u [ : , argmax ⁡ ( V u ⊤ e i ) ] , \mathbf{v}_u=\mathbf{V}_u\left[:, \operatorname{argmax}\left(\mathbf{V}_u^{\top} \mathbf{e}_i\right)\right], vu=Vu[:,argmax(Vuei)],
和之前一样是结合负采样的最大似然法(后面代码用少量数据,直接交叉熵损失函数)。给出一个训练样本 ( u , i ) (u, i) (u,i), 用户embedding v u \mathbf{v}_u vu, 和物品embedding e i \mathbf{e}_i ei,则用户与物品交互的似然函数:
P θ ( i ∣ u ) = exp ⁡ ( v u ⊤ e i ) ∑ k ∈ I exp ⁡ ( v u ⊤ e k ) P_\theta(i \mid u)=\frac{\exp \left(\mathbf{v}_u^{\top} \mathbf{e}_i\right)}{\sum_{k \in I} \exp \left(\mathbf{v}_u^{\top} \mathbf{e}_k\right)} Pθ(iu)=kIexp(vuek)exp(vuei)
目标为最小化该似然函数:
 loss  = ∑ u ∈ U ∑ i ∈ I u − log ⁡ P θ ( i ∣ u ) \text { loss }=\sum_{u \in \mathcal{U}} \sum_{i \in I_u}-\log P_\theta(i \mid u)  loss =uUiIulogPθ(iu)

二、Comirec-SA模型

2.0 数据集划分

原论文是按照8:1:1划分训练集、验证集、测试集(按照用户划分,更具泛化能力)。

  • 训练样本:全部点击序列 ( e 1 ( u ) , e 2 ( u ) , … , e k ( u ) , … , e n ( u ) ) \left(e_1^{(u)}, e_2^{(u)}, \ldots, e_k^{(u)}, \ldots, e_n^{(u)}\right) (e1(u),e2(u),,ek(u),,en(u)),用前(n-1)个item预测第n个;
  • 验证集合测试集则是使用用户前80%的点击序列作为模型输入,然后预测后面的点击序列。
  • 在验证集合测试集中的用户是从未在训练集中出现过的。

2.1 基于Attention的单一兴趣建模

在这里插入图片描述

  • 将用户的行为序列计作 H ∈ R d × n H \in \mathbb{R}^{d \times n} HRd×n,
    • 这里的 n n n 表示用户行为序列的长度,
    • d d d 表示Embedding向量的维度,
    • 这里的 H H H 就代表着用户行为序列中所有Item的Embedding向量,
  • 这里引入两个可学习参数 W 1 ∈ R d a × d , w 2 ∈ R d a W_1 \in \mathbb{R}^{d_a \times d}, w_2 \in \mathbb{R}^{d_a} W1Rda×d,w2Rda, 通过引入Attention机制进行加权求和,凸显重要性高的特征。

在我们的Comirec-SA中, 我们的特征重要性 (也就是我们学习出来的Attention Score) 是针对序列中每个Item的Attention Score, 在有了Attention Score之后就可以对序列中的|tem进行加权求和得到序列的单一兴趣表征了。单一兴趣建模时的Attention Score计算:
a = softmax ⁡ ( w 2 T tanh ⁡ ( W 1 H ) ) T a=\operatorname{softmax}\left(w_2^T \tanh \left(W_1 H\right)\right)^T a=softmax(w2Ttanh(W1H))T

  • a ∈ R n a \in \mathbb{R}^n aRn, 这里的 a a a 就是我们对序列的Attention Score(权重向量), 再将 a a a 与序列的所有Item的Embedding进行加权求和就可以得到单一兴趣的建模。

2.2 基于Attention的多兴趣建模

可以把 1.1 1.1 1.1单一兴趣建模中的 w 2 ∈ R d a w_2 \in \mathbb{R}^{d_a} w2Rda 扩充至 W 2 ∈ R d a × K W_2 \in \mathbb{R}^{d_a \times K} W2Rda×K(可训练化参数), 这里是因为在输入embedding中加入了可训练的position embedding,其维度和item embedding的维度一眼都是 d d d

Attention Score的计算公式就变成:
A = softmax ⁡ ( W 2 T tanh ⁡ ( W 1 H ) ) T A=\operatorname{softmax}\left(W_2^T \tanh \left(W_1 H\right)\right)^T A=softmax(W2Ttanh(W1H))T
其中:

  • A ∈ R n × K A \in \mathbb{R}^{n \times K} ARn×K,
  • 权重 W 2 ∈ R d a × K W_2 \in \mathbb{R}^{d_a \times K} W2Rda×K
  • K是兴趣向量个数

这时我们可以通过如下式子得到用户的多兴趣表征:
V u = H A V_u=H A Vu=HA
其中:

  • H d × n \mathbf{H}^{d \times n} Hd×n:用户行为序列的embedding矩阵,其中 n n n为用户行为序列的长度, d d d为item embedding维度;
  • V u ∈ R d × K V_u \in \mathbb{R}^{d \times K} VuRd×K, 即为 K \mathrm{K} K 个兴趣表征, 其核心代码如下:
class MultiInterest_SA(nn.Layer):
    def __init__(self, embedding_dim, interest_num, d=None):
        super(MultiInterest_SA, self).__init__()
        self.embedding_dim = embedding_dim
        self.interest_num = interest_num
        if d == None:
            self.d = self.embedding_dim*4

        self.W1 = self.create_parameter(shape=[self.embedding_dim, self.d])
        self.W2 = self.create_parameter(shape=[self.d, self.interest_num]) 

    def forward(self, seq_emb, mask = None):
        '''
        seq_emb : batch,seq,emb
        mask : batch,seq,1
        '''
        H = paddle.einsum('bse, ed -> bsd', seq_emb, self.W1).tanh()
        mask = mask.unsqueeze(-1)
        A = paddle.einsum('bsd, dk -> bsk', H, self.W2) + -1.e9 * (1 - mask)
        A = F.softmax(A, axis=1)
        A = paddle.transpose(A,perm=[0, 2, 1])
        multi_interest_emb = paddle.matmul(A, seq_emb)
        return multi_interest_emb

其实上面相当于用了一个多头注意力机制,首先来回顾单头和多头的注意力:

(1)K-Q-V注意力

1)自注意力机制

自注意力是指键(K)、查询(Q)和值(V)来自同一数据来源,即 K=Q=V。

Transformer 以特定方式执行此操作:
x 1 , x 2 , ⋯   , x T x_{1}, x_{2}, \cdots, x_{T} x1,x2,,xT 是 Transformer 编码器的输入向量, 其中 x i ∈ R d x_{i} \in R^{d} xiRd, 则键 ( K ) (K) (K) 、查询 ( Q ) (Q) (Q) 、值 ( V ) (V) (V) 是:
k i = K x i q i = Q x i v i = V x i \begin{aligned} k_{i} &=K x_{i} \\ q_{i} &=Q x_{i} \\ v_{i} &=V x_{i} \end{aligned} kiqivi=Kxi=Qxi=Vxi

  • 其中: 矩阵 K ∈ R d × d ; Q ∈ R d × d ; V ∈ R d × d K \in R^{d \times d} ; Q \in R^{d \times d} ; V \in R^{d \times d} KRd×d;QRd×d;VRd×d
  • 这些矩阵允许将x向量的不同方面用于三个角色的每一个。

2)计算 K-Q-V 注意力(矩阵形式):

X = [ x 1 , x 2 , ⋯   , x T ] ∈ R T × d \mathrm{X}=\left[x_{1}, x_{2}, \cdots, x_{T}\right] \in \mathrm{R}^{\mathrm{T} \times \mathrm{d}} X=[x1,x2,,xT]RT×d 是输入向量的串联(拼接), 其中:

  • X K ∈ R T × d , X Q ∈ R T × d , X V ∈ R T × d X K \in R^{T \times d}, X Q \in R^{T \times d}, X V \in R^{T \times d} XKRT×d,XQRT×d,XVRT×d
  • 输出定义为: output = softmax ⁡ ( X Q ( X K ) T × X V ) \operatorname{softmax}\left(X Q(X K)^{\mathrm{T}} \times X V\right) softmax(XQ(XK)T×XV)
  • 即计算过程:首先, 在一个矩阵乘法中取查询和键的点积, 得到: X Q ( X K ) T X Q(X K)^{\mathrm{T}} XQ(XK)T;其次, 对上述结果进行 softmax 计算, 再乘以矩阵 X V X V XV, 得到: softmax ⁡ ( X Q ( X K ) T ) × X V \operatorname{softmax}\left(X Q(X K)^{\mathrm{T}}\right) \times X V softmax(XQ(XK)T)×XV ,如下图的(a)。

在这里插入图片描述

如果想一次查询(Q)句子中的多个位置:
对于单词 i \mathrm{i} i, self-attention 只 “看” x i T Q T K x j x_{i}^{T} Q^{T} K x_{j} xiTQTKxj 分数高的地方, 即单头注意力, 见上图的(b) 。但是, 若出于不同的原因想要关注不同的 j \mathrm{j} j,则可通过多个 Q 、   K 、   V \mathrm{Q} 、 \mathrm{~K} 、 \mathrm{~V} Q K V 矩阵来定义多个注意力 “头”

令: Q l , K l , V l ∈ R d × d / h Q_{l}, K_{l}, V_{l} \in R^{d \times d / h} Ql,Kl,VlRd×d/h, 其中 h h h 是注意力头的数量, l l l 的范围从 1 到 h h h,则: 每个注意力头独立地计算注意力:  output  l = softmax ⁡ ( X Q l K l T X T ) ∗ X V l \text { output }_{l}=\operatorname{softmax}\left(X Q_{l} K_{l}^{T} X^{T}\right) * X V_{l}  output l=softmax(XQlKlTXT)XVl

其中:output l ∈ R d / h _{l} \in R^{d / h} lRd/h

然后合并所有头的输出:  output  = Y  [output  1 , … ,  output  h  ]  \text { output }=Y \text { [output }_{1}, \ldots, \text { output }_{h} \text { ] }  output =Y [output 1,, output h ] 

其中: Y ∈ R d × d Y \in R^{d \times d} YRd×d

因此, 每个头都可以 “看” 不同的事物, 并以不同的方式构建值 ( V \mathrm{V} V ) 向量。多头注意力和单头自注意力有相同的计算量。最简单的多头注意力,即两头注意力(如上图的c)。

2.3 多样性控制

为了强化推荐item的多样性,作者将item的类别作为衡量多样性的基础。

问题定义:给定从用户 u u u K K K 个兴趣中检索到一个集合 M \mathcal{M} M, 有 K ⋅ N K \cdot N KN 个物品, 找到一个输出集合 S \mathcal{S} S, 有 N N N 个 物品 (Top-N) , 使预定义的值函数 Q ( u , S ) Q(u, \mathcal{S}) Q(u,S)最大化。

(1)多样性:作者使用 g ( i , j ) g(i, j) g(i,j)用来衡量两个Item i, j之间的多样性:
g ( i , j ) = σ ( C A T E ( i ) ≠ C A T E ( j ) ) g(i, j)=\sigma(C A T E(i) \neq C A T E(j)) g(i,j)=σ(CATE(i)=CATE(j))

  • C A T E ( i ) C A T E(i) CATE(i) 表示物品 i i i 的类别
  • σ \sigma σ 为指示函数,这里就是如果两个item的类别不相同,那么其结果就是 1 , 反之就是 0
  • 可以看出如果一个推荐集合中两两Item的多样性得分大的话, 那么可以认为这个推荐结果中的Item的类别分布较为分散, 也就可以认为推荐结果的多样性较高了,

(2)推荐精度:当推荐结果的多样性较高的时候, 往往推荐的精度就会下降, 这是一个Trade Off,可以构造如下的目标函数(包含多样性指标和推荐精度指标): Q ( u , S ) = ∑ i ∈ S f ( u , i ) + λ ∑ i ∈ S ∑ j ∈ S g ( i , j ) Q(u, \mathcal{S})=\sum_{i \in \mathcal{S}} f(u, i)+\lambda \sum_{i \in \mathcal{S}} \sum_{j \in \mathcal{S}} g(i, j) Q(u,S)=iSf(u,i)+λiSjSg(i,j)

  • 通过 λ \lambda λ 来控制这两部分的占比, λ \lambda λ 越大则多样性更强,同事准确度会降低;
  • 作者这里提出使用一种贪心的做法来进行目标函数的优化, 优化流程如下:

在这里插入图片描述

三、代码实践

3.1 MultiInterest_SA类定义

如上面介绍的SA运算:
A = softmax ⁡ ( W 2 T tanh ⁡ ( W 1 H ) ) T A=\operatorname{softmax}\left(W_2^T \tanh \left(W_1 H\right)\right)^T A=softmax(W2Ttanh(W1H))T
可以得到 A ∈ R n × K A \in \mathbb{R}^{n \times K} ARn×K, 这时我们可以通过如下式子得到用户的多兴趣表征:
V u = H A V_u=H A Vu=HA
注意:

  • 两个维度不同的tensor也可以做加减法, 比如[256, 20, 4]的tensor-[256, 20, 1]的tensor,后者会减在全部(4个)第2维度之上。
  • 下面这里的paddle.einsum函数在tf和torch中都有,einsum(Einstein summation convention,即爱因斯坦求和约定)可以写tensor运算和更高维度tensor写法更加简洁。torch版本的多兴趣抽取层SA代码:
class MultiInterest_SA(nn.Module):
    def __init__(self, embedding_dim, interest_num, d=None):
        super(MultiInterest_SA, self).__init__()
        self.embedding_dim = embedding_dim
        self.interest_num = interest_num
        if d == None:
            self.d = self.embedding_dim*4

        # self.W1 = self.create_parameter(shape=[self.embedding_dim, self.d])
        # self.W2 = self.create_parameter(shape=[self.d, self.interest_num])
        self.W1 = Parameter(torch.Tensor(self.embedding_dim, self.d))
        self.W2 = Parameter(torch.Tensor(self.d, self.interest_num))

    def forward(self, seq_emb, mask = None):
        '''
        seq_emb : batch,seq,emb
        mask : batch,seq,1
        '''
        H = torch.einsum('bse, ed -> bsd', seq_emb, self.W1).tanh()
        mask = mask.unsqueeze(-1)  #  (batch, seq) -> (batch, seq, 1)
        # einsum爱因斯坦求和约定
        # (batch_size, seq_len, interest_num) - (batch_size, seq_len, 1)负无穷,
        # 两个维度不同可以做减法, 比如[256, 20, 4]-[256, 20, 1],后者会减在4个 全部之上
        A = torch.einsum('bsd, dk -> bsk', H, self.W2) + -1.e9 * (1 - mask)
        A = F.softmax(A, dim=1)
        A = torch.transpose(A, 2, 1)
        multi_interest_emb = torch.matmul(A, seq_emb)
        return multi_interest_emb

3.2 einsum函数的用法

einsum(Einstein summation convention,即爱因斯坦求和约定)的用法:

  • c i k = ∑ j a i j b j k c_{i k}=\sum_j a_{i j} b_{j k} cik=jaijbjk 的写法如下:
c = np.dot(a, b)                 # 常规
c = np.einsum('ij,jk->ik', a, b) # einsum
  • 再比如 c k l = ∑ i ∑ j a i j k b i j l c_{\mathrm{kl}}=\sum_{\mathrm{i}} \sum_{\mathrm{j}} \mathrm{a}_{\mathrm{ijk}} \mathrm{b}_{\mathrm{ijl}} ckl=ijaijkbijlc = np.einsum('ijk,jkl->kl', a, b)
import torch

# 1. 张量转置
A = torch.randn(3, 4, 5)
B = torch.einsum("ijk->ikj", A)
print(A.shape, "\n", B.shape, "\n", "======")  # (3, 4, 5) ; (3, 5, 4)

# 2. 取对角元素
A = torch.randn(5, 5)
B = torch.einsum("ii->i", A)
print(A.shape, "\n", B.shape, "\n", "======")

# 3. 求和降维
A = torch.randn(4, 5)
B = torch.einsum("ij->i", A)
print(A.shape, "\n", B.shape, "\n", "======")

# 4. 哈达玛积(两个矩阵维度相同)
A = torch.randn(3, 4)
B = torch.randn(3, 4)
C = torch.einsum("ij, ij->ij", A, B)
print(A.shape, "\n", B.shape, "\n", C.shape, "\n", "======")

# 5. 向量内积
A = torch.randn(10)
B = torch.randn(10)
#C=torch.dot(A,B)
C = torch.einsum("i,i->",A,B)

# 6. 向量外积
A = torch.randn(10)
B = torch.randn(5)
#C = torch.outer(A,B)
C = torch.einsum("i,j->ij",A,B)

# 7. 矩阵乘法
A = torch.randn(5,4)
B = torch.randn(4,6)
#C = torch.matmul(A,B)
C = torch.einsum("ik,kj->ij",A,B)

# 8. 张量缩并
A = torch.randn(3,4,5)
B = torch.randn(4,3,6)
#C = torch.tensordot(A,B,dims=[(0,1),(1,0)])
C = torch.einsum("ijk,jih->kh",A,B)

# 9. batch矩阵乘法
batch_tensor_1 = torch.arange(2 * 4 * 3).reshape(2, 4, 3)
batch_tensor_2 = torch.arange(2 * 3 * 4).reshape(2, 3, 4) 
torch.bmm(batch_tensor_1, batch_tensor_2)  # [2, 4, 4]
torch.einsum("bij, bjk -> bik", batch_tensor_1, batch_tensor_2) # [2, 4, 4]

3.3 Comirec-SA类定义

这部分和之前DR的类时一样的,改动的部分都体现在MultiInterest_SA上了。

class ComirecSA(nn.Layer):
    def __init__(self, config):
        super(ComirecSA, self).__init__()

        self.config = config
        self.embedding_dim = self.config['embedding_dim']
        self.max_length = self.config['max_length']
        self.n_items = self.config['n_items']

        self.item_emb = nn.Embedding(self.n_items, self.embedding_dim, padding_idx=0)
        self.multi_interest_layer = MultiInterest_SA(self.embedding_dim,interest_num=self.config['K'])
        self.loss_fun = nn.CrossEntropyLoss()
        self.reset_parameters()

    def calculate_loss(self,user_emb,pos_item):
        all_items = self.item_emb.weight
        scores = paddle.matmul(user_emb, all_items.transpose([1, 0]))
        return self.loss_fun(scores,pos_item)

    def output_items(self):
        return self.item_emb.weight

    def reset_parameters(self, initializer=None):
        for weight in self.parameters():
            paddle.nn.initializer.KaimingNormal(weight)

    def forward(self, item_seq, mask, item, train=True):

        if train:
            seq_emb = self.item_emb(item_seq)  # Batch,Seq,Emb
            item_e = self.item_emb(item).squeeze(1)

            multi_interest_emb = self.multi_interest_layer(seq_emb, mask)  # Batch,K,Emb

            cos_res = paddle.bmm(multi_interest_emb, item_e.squeeze(1).unsqueeze(-1))
            k_index = paddle.argmax(cos_res, axis=1)

            best_interest_emb = paddle.rand((multi_interest_emb.shape[0], multi_interest_emb.shape[2]))
            for k in range(multi_interest_emb.shape[0]):
                best_interest_emb[k, :] = multi_interest_emb[k, k_index[k], :]

            loss = self.calculate_loss(best_interest_emb,item)
            output_dict = {
                'user_emb': multi_interest_emb,
                'loss': loss,
            }
        else:
            seq_emb = self.item_emb(item_seq)  # Batch,Seq,Emb
            multi_interest_emb = self.multi_interest_layer(seq_emb, mask)  # Batch,K,Emb
            output_dict = {
                'user_emb': multi_interest_emb,
            }
        return output_dict

时间安排

任务信息截止时间完成情况
11月14日周一正式开始
Task01:Paddle开发深度学习模型快速入门11月14、15、16日周三完成
Task02:传统序列召回实践:GRU4Rec11月17、18、19日周六完成
Task03:GNN在召回中的应用:SR-GNN11月20、21、22日周二完成
Task04:多兴趣召回实践:MIND11月23、24、25、26日周六完成
Task05:多兴趣召回实践:Comirec-DR11月27、28日周一完成
Task06:多兴趣召回实践:Comirec-SA11月29日周二完成

Reference

[1] 多兴趣召回实践:Comirec-SA
论文:Controllable Multi-Interest Framework for Recommendation
链接:https://arxiv.org/abs/2005.09347
[2] 推荐场景中召回模型的演化过程. 京东大佬
[3] 原论文作者代码:https://github.com/THUDM/ComiRec/blob/a576eed8b605a531f2971136ce6ae87739d47693/src/train.py
[4] https://github.com/ShiningCosmos/pytorch_ComiRec/blob/main/ComiRec.py
[5] https://wangxiaocs.github.io/
[6] 推荐算法炼丹笔记:阿里序列化推荐算法ComiRec
[7] einsum is all you needed
[8] Understanding PyTorch einsum
[9] 矩阵操作万能函数 einsum 详细解析(通法教你如何看懂并写出einsum表达式)
[10] Sparse-Interest Network for Sequential Recommendation .AAAI 2021

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/47348.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2.线性代数基础

1.矩阵 2. 特殊矩阵 正交矩阵 AATE(E为单位矩阵,AT表示“矩阵A的转置矩阵”。)或ATAE,则n阶实矩阵A称为正交矩阵 正交矩阵有如下性质: A是正交矩阵,AT也是正交矩阵A的各行是单位向量且两两正交&#xff0…

html实现ezuikit.js萤石云直播监控,ezuikit.js实时监控实现,萤石云实时监控简单实现

效果图 实现 下面的播放url获取:登录萤石云->控制台->我的资源->设备列表->列表中:查看通道->监控地址 appKey和appSecret获取:登录萤石云->控制台->我的账号->应用信息->右侧:应用密钥 下载ezuikit…

(服务器客户端)网络通信是怎么实现的?7000字爆肝----原来java网络编程技术功不可没(多线程,URL,InetAddressm,TCP,UDP)集结

👨‍💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏 java ⭐java网络编程技术⭐ 文章目录⭐java网络编程技术⭐👨‍💻一,URL类…

[附源码]Python计算机毕业设计Django的4s店车辆管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

虎牙、斗鱼同道同命:共同御寒

配图来自Canva可画 回顾游戏直播行业过去十年,先是直播行业野蛮发展玩家快速跑马圈地,而后历经千播大战形成斗鱼、虎牙分天下的市场格局,现在头部平台进入精细化、多元化运作阶段,市场竞争愈加激烈。 也就是说,游戏直…

4G DTU能装4G物联网卡吗?

科技的发展日新月异,我们国家的发展战略也是支持高新科技公司的发展,所以越来越多的高新科技公司出现,但凡是高新科技公司,在设备的联网中,都会用到物联卡,所以物联卡的市场也愈发火爆,那么今天…

食物链【并查集+不知道1是A,B,C哪一类的?用x,x+n,x+n+n分别表示A,B,C中有个1】【并查集中用距离表示关系】【压缩路径】

欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示:重难点 蓝色文字表示:思…

jenkins项目构建类型 -----Pipeline流水线项目构建

壹,概念 pipeline 是一套运行在jenkins上得工作流框架,将原本运行于单个或者多个节点得任务连接起来,用来实现单个任务难以完成得复杂流程编排和可视化得工作。 贰 优点 代码持久可停止多功能可扩展 叁 如何创建Jenkins Pipeline pipeli…

计算机物联网控制|5.5常规控制方案 5.6先进控制方案

11.16日课堂作业 1.已知模拟PID算式为 试推导差分增量算式。 2.PID参数Kc、Ti、Td对系统动态特性和稳态特性有何影响? 目录 11.16日…

[附源码]计算机毕业设计springboot高校实验室仪器设备管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Telemetry原理

Telemetry是一种网络设备监控技术,提供周期采样网络设备内的统计数据和状态数据的能力。 一、Telemetry概述 1.1、技术背景: 网络设备的统一监控和性能管理是运维平台的重要功能,设备的监控数据包括数据、控制和管理平面数据。 获取设备监…

学习Python的8天

1、异常处理机制 Python 中,用try except语句块捕获并处理异常,其基本语法结构如下所示: try:可能产生异常的代码块 except [ (Error1, Error2, ... ) [as e] ]:#(e是别名,可以自己起)处理异常的代码块1 except [ (Error3, Error…

【强化学习论文合集 | 2020年合集】一. ICML-2020 强化学习论文

强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。 本专栏整理了近几年国际顶级会议中,涉及强化学习(Rein…

Workfine使用Oracle Express Edition数据库

Workfine 应用环境和工具 Win10 专业版操作系统Windows Terminaldocker desktop 4.10.1 安装设置Oracle Express Edition数据库 1、获取Oracle XE 18.4.0 docker 镜像,在 Windows Terminal 终端里执行如下命令 docker pull gvenzl/oracle-xe:18.4.0 2、下载成功…

小啊呜产品读书笔记001:《邱岳的产品手记-14》第26讲 写好产品文档的诀窍 第27讲 产品案例分析: QuartzHooked的对话式交互

小啊呜产品读书笔记001:《邱岳的产品手记-14》第26讲 写好产品文档的诀窍 & 第27讲 产品案例分析: Quartz&Hooked的对话式交互一、今日阅读计划二、泛读&知识摘录1、第26讲 写好产品文档的诀窍2、第27讲 产品案例分析: Quartz&am…

web前端-javascript-function函数(函数说明,创建和调用函数,其他方法函数声明创建函数、函数表达式创建函数)

函数 //var fun new Function("console.log(Hello 这是我的第一个函数);"); //fun();function fun2() {console.log("这是我的第二个函数");alert("哈哈哈哈");document.write("~~~~(>_<)~~~~"); }//console.log(fun2); //调用…

[附源码]计算机毕业设计springboot惠农微信小程序论文

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Nginx加载Lua脚本lrucache缓存

1、简介 lrucache缓存是单进程的&#xff0c;就像redis一样&#xff0c;所以不需要锁。 2、nginx配置 #lua_code_cache off; # 把这个缓存打开&#xff0c;因为里面的在new对象的时候&#xff0c;只允许实例一个对象&#xff0c;如果不打开的话 # 每次次请求会创建一个对象&a…

RK3588平台开发系列讲解(DisplayPort篇)DP相关模式说明

平台内核版本安卓版本RK3588Linux 5.10Android12🚀返回专栏总目录 文章目录 一、DP Alt Mode二、DP Legacy Mode2.1、Controller2.2、PHY三、Split Mode沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍DP的相关模式。

KNN最近邻算法分析及实现(Python实现)

KNN最近邻算法分析及实现&#xff08;代码附录后文&#xff09;1 KNN算法简介2 KNN基本原理3 简单实现KNN分析代码附录(Python)&#xff1a;呆&#xff0c;站住别跑&#xff0c;留个赞&#xff0c;给个关注嘛都看到这了Author&#xff1a; Nirvana Of Phoenixl Proverbs for yo…