AFM模型原理及Pytorch代码复现

AFM模型是NFM的改进版,引入了注意力机制来学习不同特征交互对预测结果的影响程度。模型通过两两特征的元素级相乘得到交互向量,然后使用注意力网络分配不同权重,避免了同等对待所有交互特征的问题。AFM模型在保留了低阶特征交互的同时,能更好地关注重要特征,提高预测准确性。

一、前言

该模型是和NFM模型结构上非常相似, 算是NFM模型的一个延伸,在NFM中, 不同特征域的特征embedding向量经过特征交叉池化层的交叉,将各个交叉特征向量进行“加和”, 然后后面跟了一个DNN网络, 这里面的问题是这个加和池化,它相当于“一视同仁”地对待所有交叉特征, 没有考虑不同特征对结果的影响程度,作者认为这可能会影响最后的预测效果, 因为不是所有的交互特征都能够对最后的预测起作用。 没有用的交互特征可能会产生噪声。

二、AFM模型原理

作者在提出NFM之后, 又对其进行了改进, 把注意力机制引入到了里面去, 来学习不同交叉特征对于结果的不同影响程度

AFM模型结构如下:

 1、Input和embedding层

和NFM模型的一样,也是大部分深度学习模型的标配了, 这里为了简单,他们的输入把连续型的特征给省去了, 输入的是稀疏特征, 然后进入embedding层, 得到相应稀疏特征的embedding向量

2、Pair-wise Interaction Layer

这里和NFM是一样的,采用的也是每对Embedding向量进行各个元素对应相乘(element-wise product)交互, 这个和FM有点不太一样, 那里是每对embedding的内积, 而这里是对应元素相乘(不想加),这个要注意一下。 公式长下面这样子:

 3、Attention based Pooling layer

本篇论文的一个核心创新 — Attention based Pooling layer。

这个想法是不同的特征交互向量在将它们压缩为单个表示时根据对预测结果的影响程度给其加上不同权重, 然后在对其进行求和。

计算公式如下:

 其中a_{ij},表示V_{i}\bigodot V_{j}对的注意力分数, 表示该交互特征对于预测目标的重要性程度。为了解决泛化问题,这里才使用了一个多层感知器(MLP)将注意力得分参数化,就是上面的那个Attention Net。

该注意力网络的结构是一个简单的单全连接层加softmax输出层的结构, 数学表示如下:

 4、output

基于注意力的池化层的输出是一个k 维向量,该向量是所有特征交互向量根据重要性程度进行了区分了之后的一个聚合效果,然后我们将其映射到最终的预测得分中。所以AFM的总体公式如下:

AFM (Attentional Factorization Machine) 是一种用于CTR (Click-Through Rate) 预测的模型,其中的特征注意力部分对于模型的性能至关重要。在 PyTorch 中,可以通过以下方式控制特征添加注意力权重的比例: 1. 定义注意力网络 ```python import torch.nn as nn class AttentionNet(nn.Module): def __init__(self, feature_dim, attention_dim): super(AttentionNet, self).__init__() self.attention_layer = nn.Sequential( nn.Linear(feature_dim, attention_dim), nn.ReLU(inplace=True), nn.Linear(attention_dim, 1) ) def forward(self, x): """ :param x: feature tensor, shape: [batch_size, feature_dim] :return: attention weights tensor, shape: [batch_size, 1] """ attention_weights = self.attention_layer(x) return attention_weights ``` 2. 定义 AFM 模型 ```python class AFM(nn.Module): def __init__(self, feature_dim, attention_dim): super(AFM, self).__init__() self.embedding_layer = nn.Embedding(feature_dim, embedding_dim) self.attention_net = AttentionNet(embedding_dim, attention_dim) self.linear_layer = nn.Linear(embedding_dim, 1) def forward(self, x): """ :param x: input tensor, shape: [batch_size, num_features] :return: output tensor, shape: [batch_size] """ embeddings = self.embedding_layer(x) # [batch_size, num_features, embedding_dim] attention_weights = self.attention_net(embeddings) # [batch_size, num_features, 1] attention_weights = F.softmax(attention_weights.squeeze(dim=2), dim=1) # [batch_size, num_features] embeddings_weighted = embeddings * attention_weights.unsqueeze(dim=2) # [batch_size, num_features, embedding_dim] y_interactions = torch.sum(torch.sum(embeddings_weighted, dim=1), dim=1) # [batch_size, embedding_dim] y_linear = self.linear_layer(torch.mean(embeddings_weighted, dim=1)) # [batch_size, 1] y = y_interactions + y_linear.squeeze() # [batch_size] return y ``` 其中,`attention_weights` 表示特征注意力权重,通过 softmax 函数对其进行归一化,然后与特征向量相乘得到加权特征向量 `embeddings_weighted`,最终求和得到交互向量 `y_interactions`。在 `forward()` 方法中,还包含了一个线性层,用于学习偏置项。可以通过调整注意力网络的结构和超参数来控制特征注意力权重的比例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值