【推荐系统】NCF神经协同过滤

NCF框架

NCF框架是本文要实现的3个模型的主体结构。

首先是输入层,分别包含两个特征向量 v u v_u vu v i v_i vi,描述了用户u和物品i。输入仅由一个用户向量和一个物品向量构成,它们分别是以one-hot编码的二值化稀疏向量。

接着是Embedding层,这是一个全连接层,用于将输入层的系数向量表示成一个稠密向量。

接着用户和物品的embedding向量被送入多层神经网络架结构中,这一层叫做神经协同过滤层(Neural CF Layer),它用于将潜在特征向量映射成预测分数(Score)。

在这里插入图片描述

class NCF(object):def __init__(self, config, latent_dim_gmf=8, latent_dim_mlp=8):self._config = configself._num_users = config['num_users']self._num_items = config['num_items']self._latent_dim_gmf = latent_dim_gmfself._latent_dim_mlp = latent_dim_mlpself._embedding_user_mlp =  torch.nn.Embedding(num_embeddings=self._num_users,embedding_dim=self._latent_dim_mlp)self._embedding_item_mlp =  torch.nn.Embedding(num_embeddings=self._num_items,embedding_dim=self._latent_dim_mlp)# 建立GMP模型的user Embedding层和item Embedding层,输入的向量长度分别为用户的数量,item的数量,输出都是隐式空间的维度latent dimself._embedding_user_gmf = torch.nn.Embedding(num_embeddings=self._num_users, embedding_dim=self._latent_dim_gmf)self._embedding_item_gmf = torch.nn.Embedding(num_embeddings=self._num_items, embedding_dim=self._latent_dim_gmf)# 全连接层self._fc_layers = torch.nn.ModuleList()for idx, (in_size, out_size) in enumerate(zip(config['layers'][:-1], config['layers'][1:])):self._fc_layers.append(torch.nn.Linear(in_size, out_size))# 激活函数self._logistic = nn.Sigmoid()@propertydef fc_layers(self):return self._fc_layers@propertydef embedding_user_gmf(self):return self._embedding_user_gmf@propertydef embedding_item_gmf(self):return self._embedding_item_gmf@propertydef embedding_user_mlp(self):return self._embedding_user_mlp@propertydef embedding_item_mlp(self):return self._embedding_item_mlpdef saveModel(self):torch.save(self.state_dict(), self._config['model_name'])@abstractmethoddef load_preTrained_weights(self):pass

GMF模型(广义矩阵分解)

p u p_u pu为用户u的潜在向量,$q_i为物品i的潜在向量。
则,神经协同网络的第一层映射函数为:
ϕ 1 ( p u , q i ) = p u ⊙ q i \phi_1(p_u,q_i) = p_u \odot q_i ϕ1(pu,qi)=puqi
然后将此向量映射到输出层:
y ^ u , i = a o u t ( h T ( p u ⊙ q i ) ) \hat{y} _{u,i} =a_{out}(h^T( p_u \odot q_i)) y^u,i=aout(hT(puqi))
如果把 a o u t a_{out} aout看作恒等函数, h h h全为1的单位向量,就变成了MF模型。

在这里插入图片描述

class GMF(NCF,nn.Module):def __init__(self, config, latent_dim_gmf):nn.Module.__init__(self)NCF.__init__(self, config = config, latent_dim_gmf=latent_dim_gmf)# 创建线性模型,输入:潜在特征向量, 输出:len =1self._affine_output = nn.Linear(in_features=self.latent_dim_gmf, out_features=1)@propertydef affine_output(self):return self._affine_outputdef forward(self, user_indices, item_indices):user_embedding = self._embedding_user_gmf(user_indices)item_embedding = self._embedding_item_gmf(item_indices)# 将user_embedding和user_embedding进行逐元素相乘element_product = torch.mul(user_embedding, item_embedding)# 通过s神经元logits = self._affine_output(element_product)rating = self._logistic(logits)def load_preTrained_weights(self):pass

MLP模型

简单的结合是不足以说明用户和物品之间的潜在特征。为了解决这个问题,我们需要向量连接的基础上增加隐藏层,可以使用标准的MLP来学习用户和物品潜在特征之间的相互作用。

在经过Embedding层后,将得到的用户和物品的潜在向量做连接(concatenation),即:
z 1 = ϕ 1 ( p u , q i ) = [ p u q i ] z_1 = \phi_1(p_u, q_i) = \begin{bmatrix} p_u \\ q_i \end{bmatrix} z1=ϕ1(pu,qi)=[puqi]
接着将模型通过一层层感知层,激活函数选择ReLU函数。
ϕ 2 ( z 1 ) = a 2 ( W 2 T z 1 + b 2 ) \phi_2(z_1) = a_2(W_2^{T}z_1 + b_2) ϕ2(z1)=a2(W2Tz1+b2)
以此类推。
到最后:
y ^ u i = σ ( h T ϕ L ( z L − 1 ) ) \hat{y}_{ui} = \sigma{(h_T\phi_L(z_{L-1}))} y^ui=σ(hTϕL(zL1))

在这里插入图片描述

class MLP(NCF, nn.Module):def __init__(self, config, latent_dim_mlp):nn.Module.__init__(self)NCF.__init__(self, config = config, latent_dim_mlp= latent_dim_mlp)self._affine_output = torch.nn.Linear(in_features=config['layers'][-1], out_features=1)@propertydef affine_output(self):return self._affine_outputdef forward(self, user_indices, item_indices):user_embedding = self._embedding_user_mlp(user_indices)item_embedding = self._embedding_item_mlp(item_indices)# 把潜在向量进行连接vector = torch.cat([user_embedding, item_embedding],dim=-1)for idx, _ in enumerate(range(len(self._fc_layers))):vector = self._fc_layers[idx](vector)vector = torch.nn.ReLU()(vector)logits = self._affine_output(vector)rating = self._logistic(logits)return ratingdef load_preTrained_weights(self):config = self._configgmf_model = GMF(config, config['latent_dim_gmf'])if config['use_cuda'] is True:gmf_model.cuda()# 加载GMF模型参数到指定的GPU上state_dict = torch.load(self._config['pretrain_gmf'])#map_location=lambda storage, loc: storage.cuda(device=self._config['device_id']))#map_location = {'cuda:0': 'cpu'})gmf_model.load_state_dict(state_dict, strict=False)self._embedding_item_mlp.weight.data = gmf_model.embedding_item_gmf.weight.dataself._embedding_user_mlp.weight.data = gmf_model.embedding_user_gmf.weight.data

NeuMF模型

GMF应用了线性内核来模拟潜在的特征交互;MLP使用了非线性内核从数据中学习潜在特征,那么自然而然地想到,我们可以将这两个模型融合在NCF框架下。
为了使得融合模型具有更大的灵活性,我们允许GMF和MLP学习独立的Embedding,并结合两种模型的最后的输出。

对左边的GMF模型:
ϕ G M F = p u G ⊙ q i G \phi^{GMF} = p_u^G \odot q_i^G ϕGMF=puGqiG
即 GMF模型的用户潜在向量和物品潜在向量做内积

对右边的MLP模型:
ϕ M L P = a L ( W L T ( a L − 1 ( . . . a 2 ( W 2 T [ p u M q i M ] + b 2 ) . . . ) ) + b L ) \phi^{MLP} = a_L(W_L^T(a_{L-1}(...a_2(W_2^T\begin{bmatrix} p_u^M \\ q_i^M \end{bmatrix} + b_2)...)) + b_L) ϕMLP=aL(WLT(aL1(...a2(W2T[puMqiM]+b2)...))+bL)

综合MLP和GMF模型得到:
y ^ u i = σ ( h T [ ϕ G M F ϕ M L P ] ) \hat{y}_{ui} = \sigma(h^T \begin{bmatrix} \phi^{GMF} \\ \phi^{MLP} \end{bmatrix} ) y^ui=σ(hT[ϕGMFϕMLP])

在这里插入图片描述

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

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

相关文章

[HNCTF 2022 WEEK2]e@sy_flower

获取基本信息 获取关键字符串 进来“开门红” 上一篇博客才发现这个 按u转换为二进制 有个无效db,最简单的花指令 nop掉 重新u一下p一下 就正常了 然后编译完main函数 int __cdecl __noreturn main(int argc, const char **argv, const char **envp) {signed in…

Python深度学习技术教程

原文链接:Python深度学习技术教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247597949&idx4&sn65c0d353d02b060fec98ec799f217ae1&chksmfa823e9acdf5b78cd71cfcb060e3b60125b17afbe3e19ef423d4709d2df7fc93d90ce3097253&token14787…

Unity InputField实现框自适应内容简便方法

要实现InputField框自适应输入内容,除了通过代码进行处理,还可以是使用以下简便的方法。 1、创建InputField组件:右键->UI->Input Field -TextMeshPro。 2、把Input Field Settings中的Line Type设置为Multi Line Newline模式&#x…

Jenkins + Docker + ASP.NET Core自动化部署

本来没想着要写这篇博客,但是在实操过程中,一个是被网络问题搞炸了心态(真心感觉网络能把人搞疯,别人下个包、下个镜像几秒钟搞定,我看着我的几KB小水管真是有苦说不出),另一个就是这里面坑还是…

【Java】高级篇1:异常处理

异常:程序在执行过程中出现的非正常情况,如果不处理最终会导致JVM的非正常停止。 Java的异常抛出机制 Java异常体系 1、Throwable 2、Error和Exception 异常处理方式 1、try-catch-finally(捕获异常) 基本结构: 使用…

Day68:WEB攻防-Java安全原生反序列化SpringBoot攻防heapdump提取CVE

目录 Java安全-反序列化-原生序列化类函数 原生序列化类函数 SnakeYaml XMLDecoder ObjectInputStream.readObject 工具利用 ysoserial Yakit SerializedPayloadGenerator Java安全-SpringBoot框架-泄漏&CVE SpringBoot Actuator-黑白盒发现 人工识别 BurpSui…

数据库事务中“锁”的分类

数据库事务中的锁可以按照不同的维度进行分类。以下是一些常见的分类方式: 1、按锁的粒度分类: 行锁(Row-level lock):锁定单个或少量的数据行。这种锁粒度小,允许高度的并发,但管理开销大。页…

LeetCode 2312.卖木头块:动态规划(DP)

【LetMeFly】2312.卖木头块:动态规划(DP) 力扣题目链接:https://leetcode.cn/problems/selling-pieces-of-wood/ 给你两个整数 m 和 n ,分别表示一块矩形木块的高和宽。同时给你一个二维整数数组 prices ,其中 prices[i] [hi, …

LeetCode118 杨辉三角形

题目 给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1 输出: [[1]] 解…

汽车电子拓扑架构的演进过程

汽车电子拓扑架构的演进过程 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师 (Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝完再挣扎,出门靠…

Python 常用的开源爬虫库介绍

Python 是一种广泛使用的编程语言,特别是在 Web 爬虫领域。有许多优秀的开源爬虫库可以帮助开发者高效地抓取网页内容。以下是几个常用的 Python 爬虫库及其特点和优势: BeautifulSoup 特点 - **HTML/XML 解析**:BeautifulSoup 是一个…

linux(Ubuntu22) 一篇带你学会Linux,详细篇

Linux 简介 精通Linux,自带python,系统开源 电脑可安装双系统 c盘安装win D盘安装linux 在一套硬件上只能同时运行一个操作系统 虚拟机 模拟真实环境 在虚拟机内运行操作系统 需要硬件支持虚拟化 开启VT-X VM…

opengl程序错误,无法定位程序输入点 glewGetErrorString@4 于动态链接库

使用mingw编译器编译运行opengl程序,编译通过运行时崩溃 怀疑是之前的mingw版本编译的glew库版本不对,又重新编译一遍,还是这个错误 之后检查环境变量配置,发现有两个glew的路径,一个是msvc版的,另一个是m…

Unity WebGL服务器标头的问题

目录 现象: 报错文本: 原因: 解决方案: 现象: 打包前,ProjectSetting 压缩选项设置为Brotli, 将打包的WebGL部署到阿里云OSS环境后,运行弹框提示错误. 报错文本: Unable to parse Build/WebGL.framework.js.br! This canha…

三级等保技术建议书

1信息系统详细设计方案 1.1安全建设需求分析 1.1.1网络结构安全 1.1.2边界安全风险与需求分析 1.1.3运维风险需求分析 1.1.4关键服务器管理风险分析 1.1.5关键服务器用户操作管理风险分析 1.1.6数据库敏感数据运维风险分析 1.1.7“人机”运维操作行为风险综合分析 1.2…

QT----基于QT的人脸考勤系统

目录 1 编译opencv库1.1 下载源代码1.2 qt编译opencv1.3 执行Cmake一直卡着data: Download: face_landmark_model.dat 2 编译SeetaFace2代码2.1 遇到报错By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has2.2遇到报错Model missing 3 测试…

web高可用集群(nginx负载均衡+keepalived实现调度器HA)

web高可用集群(nginx负载均衡keepalived实现调度器HA) 主机IP地址代理服务器192.168.88.66代理服务器192.168.88.38Real server192.168.88.10Real server192.168.88.20 配置俩台Real server [rootweb1 ~]# vim /etc/yum.repos.d/nginx.repo [rootweb1 ~]# cat /e…

KT6368A蓝牙主从一体芯片_功能简要说明

一、功能简介 新增KT1328A芯片方案的蓝牙主从一体版本,实现的是主从一体相互切换,也就是说可以设置为主机【类似于手机的角色】,也可以设置为从机角色,通过AT指令 此版本的型号命名为:KT1328A-SOP8 。后续需要下单…

牛客NC125 和为K的连续子数组【中等 哈希+前缀和 Java,Go,PHP】

题目 题目链接: https://www.nowcoder.com/practice/704c8388a82e42e58b7f5751ec943a11 思考 滑动窗口,map,前缀和参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修…

奇舞周刊第522期:“Vite 又开始搞事情了!!!”

奇舞推荐 ■ ■ ■ Vite 又开始搞事情了!!! Vite 的最新版本将引入一种名为 Rolldown 的新型打包工具。 unocss 究竟比 tailwindcss 快多少? 我们知道 unocss 很快,也许是目前最快的原子化 CSS 引擎 (没有之一)。 巧用…