深度学习 - 43.SeNET、Bilinear Interaction 实现特征交叉 By Keras
目录
一.引言
二.SENET Layer
1.简介
2.Keras 实现
2.1 Init Function
2.2 Build Function
2.3 Call Function
2.4 Test Main Function
2.5 完整代码
三.BiLinear Intercation Layer
1.简介
2.Keras 实现
2.1 Init Function
2.2 Build Function
2.3 Call Function
2.4 Test Main Function
2.5 完整代码
四.总结
一.引言
上一篇文章我们对 FiBiNet 网络做了全面的了解,其引入 SENET 与 BiLinear Interaction 实现特征交叉,实验表明 FiBiNet 在浅层网络效果优于 FM、FFM,在深层网络效果优于 DeepFm、XdeepFm。本文用 kears 实现基本的 SENET Layer 与 Bilinear Interaction Layer。
二.SENET Layer
1.简介
SENet 全称为 Squeeze-and-Excitation Networks, 可翻译为压缩与激励网络。
实现流程:
AvgPool 平均池化 => FC + σ 全连接激活 => FC + σ 全连接激活 => Multiply 加权
这里第一个激活函数 σ 为 ReLU,第二个激活函数有的使用 Sigmoid 有的使用 ReLU。
2.Keras 实现
2.1 Init Function
def __init__(self, reduction_ratio=3, **kwargs):self.field_size = Noneself.embedding_size = Noneself.dense1 = Noneself.dense2 = Noneself.reduction_ratio = reduction_ratiosuper(SETNetLayer, self).__init__(**kwargs)
初始化函数主要定义 SENET 需要的变量,主要是 Field 数量,Embedding 嵌入维度以及 Squeeze 挤压和 Excitation 激发对应的两个 Full Connect 全连接 Dense 层以及对应的 Squeeze 参数 reduction_ratio。
2.2 Build Function
def build(self, input_shape):self.field_size, self.embedding_size = input_shapereduction_size = max(1, self.field_size // self.reduction_ratio)self.dense1 = Dense(reduction_size, activation='relu', kernel_initializer=glorot_normal_initializer)self.dense2 = Dense(self.field_size, activation='sigmoid', kernel_initializer=glorot_normal_initializer)super(SETNetLayer, self).build(input_shape)
这里没有调用 add_weight 方法初始化参数矩阵,直接使用 layer 层下的 Dense 层初始化。
2.3 Call Function
def call(self, inputs, training=None, **kwargs):# inputs = F x Kmean_pooling = tf.expand_dims(tf.reduce_mean(inputs, axis=-1), axis=0) # 1 x Fcompression = self.dense1(mean_pooling) # 1 x reductionreconstruction = self.dense2(compression) # 1 x Fadd_weight = tf.squeeze(tf.multiply(inputs, tf.expand_dims(reconstruction, axis=2))) # F x Kreturn add_weight
原始维度为 FxK,F 为 Field_size、K 为 Embedding_dim 输入输出,加权后输出维度仍然为 FxK。
2.4 Test Main Function
if __name__ == '__main__':# 数据准备F = 6 # Field 数量K = 8 # 特征维度samples = np.ones(shape=(F, K))seNetLayer = SETNetLayer()output = seNetLayer(samples)print(output)
实际场景同可以通过引入 SENET 达到动态更新 Field 重要性的目的。
2.5 完整代码
import numpy as np
import tensorflow as tf
from tensorflow.python.keras.layers import *
from tensorflow.keras.layers import Layer
from tensorflow.python.ops.init_ops import glorot_normal_initializerclass SETNetLayer(Layer):def __init__(self, reduction_ratio=3, **kwargs):self.field_size = Noneself.embedding_size = Noneself.dense1 = Noneself.dense2 = Noneself.reduction_ratio = reduction_ratiosuper(SETNetLayer, self).__init__(**kwargs)def build(self, input_shape):self.field_size, self.embedding_size = input_shapereduction_size = max(1, self.field_size // self.reduction_ratio)self.dense1 = Dense(reduction_size, activation='relu', kernel_initializer=glorot_normal_initializer)self.dense2 = Dense(self.field_size, activation='sigmoid', kernel_initializer=glorot_normal_initializer)super(SETNetLayer, self).build(input_shape)def call(self, inputs, training=None, **kwargs):# inputs = F x Kmean_pooling = tf.expand_dims(tf.reduce_mean(inputs, axis=-1), axis=0) # 1 x Fcompression = self.dense1(mean_pooling) # 1 x reductionreconstruction = self.dense2(compression) # 1 x Fadd_weight = tf.squeeze(tf.multiply(inputs, tf.expand_dims(reconstruction, axis=2))) # F x Kreturn add_weightdef compute_output_shape(self, input_shape):return input_shapeif __name__ == '__main__':# 数据准备F = 6 # Field 数量K = 8 # 特征维度samples = np.ones(shape=(F, K))seNetLayer = SETNetLayer()output = seNetLayer(samples)print(output)
三.BiLinear Intercation Layer
1.简介
BiLinear Inteaction Layer 引入参数交叉矩阵实现 i、j 特征之间的交互代替原有的内积或哈达玛积,其中共设计了三种模式:
- Filed All Type
所有交叉特征共享一个 kxk 的参数矩阵
- Field Each Type
每个 Field 一个参数矩阵 Wi ∈ R kxk
- Field Interaction Type
每个交叉特征 i、j 一个参数矩阵 W i,j ∈ R kxk
2.Keras 实现
2.1 Init Function
def __init__(self, biLinear_type='all', seed=1024, **kwargs):self.biLinear_type = biLinear_typeself.seed = seedself.field_size = Noneself.embedding_size = Noneself.W = Noneself.W_list = Nonesuper(BiLinearInteraction, self).__init__(**kwargs)
biLinear_type 控制特征交互方式,Filed_size 为特征数量,Embedding_size 为嵌入维度,Filed-All-Type 场景下使用单一 W 参数矩阵,Field-Each-Type 和 Field-Interaction-Type 使用 W_list 多参数矩阵的形式,前者 W 个数为 Field 个,后者为 (F-1)·F / 2 个。
2.2 Build Function
def build(self, input_shape):self.field_size, self.embedding_size = input_shapeif self.biLinear_type == "all":self.W = self.add_weight(shape=(self.embedding_size, self.embedding_size),initializer=glorot_normal_initializer(seed=self.seed),name="biLinearWeight")elif self.biLinear_type == "each":self.W_list = [self.add_weight(shape=(self.embedding_size, self.embedding_size),initializer=glorot_normal_initializer(seed=self.seed),name="biLinearWeight" + str(i)) for i in range(self.field_size)]elif self.biLinear_type == "interaction":self.W_list = [self.add_weight(shape=(self.embedding_size, self.embedding_size),initializer=glorot_normal_initializer(seed=self.seed),name="biLinearWeight" + str(i) + '_' + str(j)) for i, j initertools.combinations(range(self.field_size), 2)]else:raise NotImplementedErrorsuper(BiLinearInteraction, self).build(input_shape)
根据 input_shape 解析得到 Field_size 和 Embedding_size,根据 biLinear_type 的不同,初始化不同的参数矩阵 W 与 W_list,itertools.combinations 方法用于生成所有 Filed 的组合。
2.3 Call Function
def call(self, inputs, **kwargs):n = len(inputs)if self.biLinear_type == "all":# 所有特征交叉公用一个参数矩阵 Wv_dots = [tf.tensordot(inputs[i], self.W, axes=(-1, 0)) for i in range(n)] # F x Kp = [tf.multiply(v_dots[i], inputs[j]) for i, j in itertools.combinations(range(n), 2)] # (F-1)·F/2 x Kelif self.biLinear_type == "each":# 每个特征一个参数矩阵 Wiv_dots = [tf.tensordot(inputs[i], self.W_list[i], axes=(-1, 0)) for i in range(n)] # F x Kp = [tf.multiply(v_dots[i], inputs[j]) for i, j in itertools.combinations(range(n), 2)] # (F-1)·F/2 x Kelif self.biLinear_type == "interaction":# 每一个组合特征 Vi-Vj 以及对应的 Wijp = [tf.multiply(tf.tensordot(v[0], w, axes=(-1, 0)), v[1])for v, w in zip(itertools.combinations(inputs, 2), self.W_list)] # (F-1)·F/2 x Kelse:raise NotImplementedError# (F-1)·F/2 x K_output = tf.reshape(p, shape=(-1, int(self.embedding_size)))return _output
分别执行内积与哈达玛积,区别是交互的 W 参数矩阵不同,这里与 SENET 不同,SENET 输入输出维度相同,BiLinear Interaction Layer 输入 F x K,输出 (F-1)·F / 2 x K,因为前者是对 Field 的交叉,后者是对每一个 FF 特征的交叉。
2.4 Test Main Function
if __name__ == '__main__':# 数据准备F = 4 # Field 数量K = 8 # 特征维度samples = np.ones(shape=(F, K))BiLinearLayer = BiLinearInteraction("interaction")output = BiLinearLayer(samples)print(output)
F = 4,K = 8,所以输出 6x8。
2.5 完整代码
import itertoolsimport numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Layer
from tensorflow.python.ops.init_ops import glorot_normal_initializerclass BiLinearInteraction(Layer):def __init__(self, biLinear_type='interaction', seed=1024, **kwargs):self.biLinear_type = biLinear_typeself.seed = seedself.field_size = Noneself.embedding_size = Noneself.W = Noneself.W_list = Nonesuper(BiLinearInteraction, self).__init__(**kwargs)def build(self, input_shape):self.field_size, self.embedding_size = input_shapeif self.biLinear_type == "all":self.W = self.add_weight(shape=(self.embedding_size, self.embedding_size),initializer=glorot_normal_initializer(seed=self.seed),name="biLinearWeight")elif self.biLinear_type == "each":self.W_list = [self.add_weight(shape=(self.embedding_size, self.embedding_size),initializer=glorot_normal_initializer(seed=self.seed),name="biLinearWeight" + str(i)) for i in range(self.field_size)]elif self.biLinear_type == "interaction":self.W_list = [self.add_weight(shape=(self.embedding_size, self.embedding_size),initializer=glorot_normal_initializer(seed=self.seed),name="biLinearWeight" + str(i) + '_' + str(j)) for i, j initertools.combinations(range(self.field_size), 2)]else:raise NotImplementedErrorsuper(BiLinearInteraction, self).build(input_shape)def call(self, inputs, **kwargs):n = len(inputs)if self.biLinear_type == "all":# 所有特征交叉公用一个参数矩阵 Wv_dots = [tf.tensordot(inputs[i], self.W, axes=(-1, 0)) for i in range(n)] # F x Kp = [tf.multiply(v_dots[i], inputs[j]) for i, j in itertools.combinations(range(n), 2)] # (F-1)·F/2 x Kelif self.biLinear_type == "each":# 每个特征一个参数矩阵 Wiv_dots = [tf.tensordot(inputs[i], self.W_list[i], axes=(-1, 0)) for i in range(n)] # F x Kp = [tf.multiply(v_dots[i], inputs[j]) for i, j in itertools.combinations(range(n), 2)] # (F-1)·F/2 x Kelif self.biLinear_type == "interaction":# 每一个组合特征 Vi-Vj 以及对应的 Wijp = [tf.multiply(tf.tensordot(v[0], w, axes=(-1, 0)), v[1])for v, w in zip(itertools.combinations(inputs, 2), self.W_list)] # (F-1)·F/2 x Kelse:raise NotImplementedError# (F-1)·F/2 x K_output = tf.reshape(p, shape=(-1, int(self.embedding_size)))return _outputif __name__ == '__main__':# 数据准备F = 4 # Field 数量K = 8 # 特征维度samples = np.ones(shape=(F, K))BiLinearLayer = BiLinearInteraction("interaction")output = BiLinearLayer(samples)print(output)
四.总结
如果我们去掉 SENET 层和双线性交互层,我们的浅 FiBiNET 和深 FiBiNET 将降级为 FM 和FNN,为了进一步提高性能,将上述浅层模型与 DNN 结合得到 FiBiNet 由于 DeepFm 和 XdeepFm 等深层模型。上图为 FiBiNet 模型架构,其中绿框部分为 SENET Layer,红框部门为 Bilinear-Interaction Layer,剩下的 Combination Layer 和 DNN 的构建比较基础,有兴趣的同学可以自己实现 FiBiNet。
相关文章:

深度学习 - 43.SeNET、Bilinear Interaction 实现特征交叉 By Keras
目录 一.引言 二.SENET Layer 1.简介 2.Keras 实现 2.1 Init Function 2.2 Build Function 2.3 Call Function 2.4 Test Main Function 2.5 完整代码 三.BiLinear Intercation Layer 1.简介 2.Keras 实现 2.1 Init Function 2.2 Build Function 2.3 Call Functi…...

Ceph入门到精通-Cephadm安装Ceph(v17.2.5 Quincy)全网最全版本
Deploy Ceph(v17.2.5 Quincy) cluster to use Cephadm - DevOps - dbaselife Install cephadm Cephadm creates a new Ceph cluster by “bootstrapping” on a single host, expanding the cluster to encompass any additional hosts, and then depl…...
BIOS与POST自检
一、什么是BIOS BIOS是英文"BasicInput-Output System",中文名称就是"基本输入输出系统",是集成在主板上的一个ROM芯片,意思是只读存储器基本输入输出系统。顾名思义,它保存着计算机最重要的基本输入输出的程…...

交友项目【查询好友动态,查询推荐动态】实现
目录 1:圈子 1.1:查询好友动态 1.1.1:接口分析 1.1.2:流程分析 1.1.2:代码实现 1.2:查询推荐动态 1.2.1:接口分析 1.2.2:流程分析 1.2.3:代码实现 1:…...
24个强大的HTML属性,建议每位前端工程师都应该掌握!
HTML属性非常多,除了一些基础属性外,还有许多有用的特别强大的属性 本文将介绍24个强大的HTML属性,可以使您的网站更具有动态性和交互性,让用户感到更加舒适和愉悦。 让我们一起来探索这24个强大的HTML属性吧! 1、Acc…...

前端--移动端布局--2移动开发之flex布局
目标: 能够说出flex盒子的布局原理 能够使用flex布局的常用属性 能够独立完成携程移动端首页案例 目录: flex布局体验 flex布局原理 flex布局父项常见属性 flex布局子项常见属性 写出网首页案例制作 1.flex布局体验 1.1传统布局与flex布局 传…...

【移动端网页布局】移动端网页布局基础概念 ① ( 移动端浏览器 | 移动端屏幕分辨率 | 移动端网页调试方法 )
文章目录 一、移动端浏览器二、移动端屏幕分辨率三、移动端网页调试方法 一、移动端浏览器 移动端浏览器 比 PC 端浏览器发展要晚 , 使用的技术比较新 , 对 HTML5 CSS3 支持较好 , 常见的浏览器如下 : UC / QQ / Opera / Chrom / 360 / 百度 / 搜狗 / 猎豹 国内的浏览器 基本…...

无线洗地机哪款性价比高?高性价比的洗地机分享
虽说现在市面上清洁工具很多,但是要说清洁效果最好的,肯定非洗地机莫属。它集合了吸,洗,拖三大功能,干湿垃圾一次清理,还能根据地面的脏污程度进行清洁,达到极致的清洁效果,省时省力…...
精通 Python OpenCV4:第三、四部分
原文:Mastering OpenCV 4 with Python 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 计算机视觉 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 当别人说你没有底线的时候,你最好真…...

在现成的3D打印机上进行实验理论:一种数据孪生的攻击探测框架
在现成的3D打印机上提供了一种DT中攻击探测框架的DT解决方案的实验演示,作为说明性CPMS资源。通过网络安全DT对打印机正常运行、异常运行和攻击三种情况下的实验数据进行收集和分析,得出攻击检测结果。实验装置概述如下图所示。该实验研究是在现实世界设…...

网络通信之传输层协议
文章目录 传输层在网络通信中扮演的角色认识TCP协议TCP协议的多种机制确认应答(ACK)机制超时重传机制连接管理机制🔺滑动窗口流量控制拥塞控制延迟应答捎带应答面向字节流粘包问题TCP异常处理 总结 传输层在网络通信中扮演的角色 上图是网络通信中五个模块ÿ…...

短视频app开发:如何提高视频播放稳定性
简介 如今,短视频已经成为人们日常生活中不可或缺的一部分,而短视频app的开发也日益成为了人们热议的话题。在短视频app开发的过程中,如何提高视频播放稳定性是一个非常重要的问题。本文将从短视频源码角度出发,分享提高短视频ap…...

软件测试,想找一份20k以上的工作需要掌握哪些知识?
都知道IT行业是高薪人员的聚集地,但想要成为高薪程序员却并不容易。月薪20k是测试工程师的一个门槛,想要突破就必须掌握更多的技能。 因为程序员职业发展很快,即使是相同起点的人,经过几年的工作或学习,会迅速拉开极…...

PostgreSQL标准复制方案
集群拓扑 假设我们使用4单元的标准配置:主库,同步从库,延迟备库,远程备库,分别用字母M,S,O,R标识。 M:Master, Main, Primary, Leader, 主库,权威数据源。S: Slave, Secondary, Standby, Sync…...

AOD实践,modis数据下载,modis数据处理
modis数据下载-数据读取-重投影-拼接-均值 一、数据下载 1、Cygwin安装 Cygwin安装教程:https://blog.csdn.net/u010356768/article/details/90756742 1.2 数据采集 现提供遥感数据下载服务,主要是NASA数据,数据下载网站包括:…...

常见的注册中心Nacos、Eureka
常见的注册中心 1.Eureka(原生,2.0遇到瓶颈,停止维护) 2.Zookeeper(支持,专业的独立产品。例如:dubbo) 3.Consul(原生,GO语言开发) 4.Nacos …...
逆向思维书籍推荐
《逆向思维》作者:德鲁克 《逆向思维法》作者:艾伦哈勃 《逆向思维:如何解决问题》作者:托尼布赖恩特 《逆向思维的力量》作者:李开复 《逆向思维:掌握创新的关键》作者:李嘉诚 《逆向思维》作…...
centos系统简析
服务器所使用的最多的系统之一便是Linux系统,Linux下centos系统也是常用的系统,今天来给大家详细说名下centos系统。 CentOS于2004年5月发布,作为一个完全免费且基于Linux内核的操作系统。CentOS 起源于 RHEL。其目标是提供一个免费提供的企…...
「SQL面试题库」 No_43 只出现一次的最大数字
🍅 1、专栏介绍 「SQL面试题库」是由 不是西红柿 发起,全员免费参与的SQL学习活动。我每天发布1道SQL面试真题,从简单到困难,涵盖所有SQL知识点,我敢保证只要做完这100道题,不仅能轻松搞定面试࿰…...
TEB算法详解 参数详解
teb算法的基本思路之前已经看完了,今天主要看一下teb算法的参数配置文件,分析一下每个配置参数的作用: teb的参数主要可以包含以下几个部分: 1、Trajectory Trajectory的参数顾名思义,就是对路径生效的一些参数&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...