特征交叉04 SENet 和 Bilinear 交叉

  SENet 和 Bilinear 交叉这两种模型用在排序上都有收益。

  SENet:

根据所有的特征,自动判断每一个field的特征重要性。对离散特征做field-wise 加权。

embedding向量维度相同

离散特征的处理:表示成K维的向量,m个特征

对矩阵的行做avgpooling得到一个向量,向量每个元素对应一个离散特征。

再用一个全连接层和relu激活函数把m维向量压缩成m/r维向量。r是压缩比例,一个大于1的数。

再用一个全连接层和sigmoid函数恢复成m维向量,元素介于0-1之间欸。

把向量成行乘到最初的mxk矩阵上,得到新的矩阵。新矩阵第二行是原矩阵第二行乘以m维向量第二个元素。

中间m维向量的作用就是对特征对加权。

embedding向量维度不同

### FiBiNet 中 SENet特征交叉实现 SENet(Squeeze-and-Excitation Network)的核心思想在于通过学习通道间的依赖关系,动态调整各个通道的重要性权重。这种机制能够增强有用的信息并抑制无用的信息。 #### Squeeze 操作 在 SENet 中,“Squeeze” 是指通过对输入特征图 \( X \in R^{C \times H \times W} \) 进行全局平均池化操作,将每个通道的空间维度压缩为单个数值。这一步骤的结果是一个形状为 \( C \times 1 \times 1 \) 的向量[^3]。 具体公式如下: \[ z_c = \frac{1}{H \cdot W}\sum_{i=1}^H\sum_{j=1}^W x_{c,i,j} \] ```python import torch.nn as nn class SELayer(nn.Module): def __init__(self, channel, reduction=16): super(SELayer, self).__init__() self.squeeze = nn.AdaptiveAvgPool2d(1) ``` --- #### Excite 操作 “Excite” 阶段旨在基于挤压后的特征生成通道注意力权重。这一阶段通常由两个全连接层组成,中间加入激活函数(ReLU Sigmoid),用于建模非线性归一化权重。 具体计算流程如下: 1. 使用第一个全连接层降低维度至 \( \frac{C}{r} \),其中 \( r \) 表示降维比例; 2. 应用 ReLU 激活函数引入非线性; 3. 使用第二个全连接层恢复原始维度 \( C \) 并应用 Sigmoid 函数得到最终的权重。 代码实现如下: ```python def __init__(self, channel, reduction=16): super(SELayer, self).__init__() self.excite = nn.Sequential( nn.Linear(channel, channel // reduction, bias=False), nn.ReLU(inplace=True), nn.Linear(channel // reduction, channel, bias=False), nn.Sigmoid() ) def forward(self, x): b, c, _, _ = x.size() # 获取批量大小通道数 y = self.squeeze(x).view(b, c) # 全局平均池化 + 展平 y = self.excite(y).view(b, c, 1, 1) # 计算通道权重 return x * y.expand_as(x) # 权重加权到原特征图 ``` --- #### 特征交叉的具体作用 SENet 的 “Squeeze and Excite” 本质上是一种跨通道的特征交互方式。通过显式地建模通道间的关系,SENet 能够突出重要的特征而削弱不相关的特征。这种方式不仅增强了模型的表现力,还保持了较低的额外计算开销。 在 FiBiNet 中,SENet 被用来处理嵌入后的低维稠密向量,进一步提升特征选择的效果[^1]。对于离散型连续型特征,均会先经过 Embedding 层转换为固定长度的向量后再送入 SE 模块进行优化[^2]。 --- #### 完整代码示例 以下是结合 FiBiNet 构造的一个简单例子,展示如何利用 SENet 处理特征交叉问题: ```python import torch from torch import nn class FeatureInteractionModule(nn.Module): def __init__(self, input_dim, embedding_dim, num_fields, reduction_ratio=8): super(FeatureInteractionModule, self).__init__() # 初始化Embedding层 self.embedding_layer = nn.Embedding(input_dim, embedding_dim) # 添加SE模块 self.se_block = SELayer(num_fields * embedding_dim, reduction=reduction_ratio) def forward(self, discrete_features, continuous_features): batch_size = discrete_features.shape[0] # 对离散特征做Embedding embedded_discrete = self.embedding_layer(discrete_features.long()) flat_embedded_discrete = embedded_discrete.view(batch_size, -1) # 对连续特征标准化后直接乘以Embedding结果 normalized_continuous = (continuous_features - continuous_features.mean()) / \ (continuous_features.std() + 1e-7) combined_input = flat_embedded_discrete * normalized_continuous.unsqueeze(-1) # 输入SE模块 se_output = self.se_block(combined_input.view(batch_size, -1)) return se_output ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值