动手实现wide and deep
实现 and 动手 Deep wide
2023-06-13 09:12:48 时间
关注我们,一起学习~
这里简单复现了一下wide and deep这个基础方法,和大家进行分享,wide and deep是推荐系统中的基础模型,主要由wide和deep两部分构成,这也是它名字的由来。deep部分是特征与特征之间的深度复杂交互,可以提升模型泛化能力,是黑盒的;而wide部分提供记忆,显式地记住一些特征的交互,比如图中曝光和用户安装之间的特征交互,将deep和wide部分结合,即记忆与泛化结合,从而增强模型的性能。
image.png
"""当然需要根据具体数据,实际问题进行不同层的构建以及对特征进行编码
"""
import torch
import torch.nn as nn
class WideAndDeep(nn.Module):
def __init__(self,
cat_features,
emb_dims, encode_dim,
deep_fea_nums,
wide_fea_nums):
"""wide and deep model
Args:
cat_features (dict): the number of each categorical feature
emb_dims (list): the list of layer dims
encode_dim (int): encoded embedding dim
deep_fea_nums (int): the number of deep features
wide_fea_nums (int): the number of wide features
"""
super(WideAndDeep, self).__init__()
self.cat_features = cat_features
self.emb_dims = emb_dims
self.encode_dim = encode_dim
self.deep_fea_nums = deep_fea_nums
self.wide_fea_nums = wide_fea_nums
self.embs = nn.ModuleDict()
# 存储不同的embedding层
for fea_name in self.cat_features.keys():
fea_nums = self.cat_features[fea_name]
emb = nn.Embedding(fea_nums, self.encode_dim)
self.embs[fea_name] = emb
self.dlayers = self.deep_layer()
self.wlayer = self.wide_layer()
self.softmax = nn.Softmax(dim=1)
def encoder(self, features):
# 对不同特征进行编码
emb_dict = {}
for fea_name in features.keys():
if fea_name in self.embs.keys():
emb_dict[fea_name] = self.embs[fea_name](features[fea_name])
elif 'cat_his' in fea_name:
emb_tmp = self.embs['cat'](features[fea_name])
emb_tmp = torch.mean(emb_tmp, 1)
emb_dict[fea_name] = emb_tmp
elif 'mid_his' in fea_name:
emb_tmp = self.embs['mid'](features[fea_name])
emb_tmp = torch.mean(emb_tmp, 1)
emb_dict[fea_name] = emb_tmp
return emb_dict
def deep_layer(self):
# 得到deep层
input_dim = self.deep_fea_nums * self.encode_dim
dlayers = nn.ModuleList([nn.BatchNorm1d(input_dim), nn.Linear(input_dim, self.emb_dims[0]), nn.PReLU()])
for i in range(1, len(self.emb_dims)):
linear = nn.Linear(self.emb_dims[i - 1], self.emb_dims[i])
dlayers.append(linear)
dlayers.append(nn.PReLU())
return dlayers
def wide_layer(self):
# 得到wide层
input_dim = self.wide_fea_nums * self.encode_dim
linear = nn.Linear(input_dim, self.emb_dims[-1])
return linear
def forward(self, features):
# 得到不同特征的embedding
emb_dict = self.encoder(features)
# 构建deep部分的输入
deep_emb = torch.cat(list(emb_dict.values()), 1)
# 构建wide部分的输入
item_emb = torch.cat([emb_dict['mid'], emb_dict['cat']], 1)
item_his_emb = torch.cat([emb_dict['mid_his'], emb_dict['cat_his']], 1)
wide_emb = torch.cat([item_emb, item_his_emb, item_emb * item_his_emb], 1)
# wide部分直接经过简单的一层layer
y_wide = self.wlayer(wide_emb)
# deep部分通过DNN进行特征交互
demb = deep_emb
for i in range(len(self.dlayers)-1):
demb = self.dlayers[i](demb)
y_deep = demb
final_embd = y_deep + y_wide
output = self.softmax(final_embd)
return output
相关文章
- 两数之和 II – 输入有序数组(Java实现)
- java map 二维数组_Java二维数组实现简单Map
- golang练手小项目系列(6)-使用map实现set
- java数据库的介绍和使用_java实现数据库的查询
- Blazor Server完美实现Cookie Authorization and Authentication
- 珠海企业无法实现精益生产的首要原因是什么
- MYSQL实现Oracle的Start with…Connect By递归树查询详解数据库
- MySQL数据库备份:实现完美的工具体验(mysql备份数据库工具)
- MySQL中的OR与AND操作符比较(mysqlor和and)
- Linux:实现右键复制的简单技巧(linux右键复制)
- Linux系统安全优化:实现更安全的网络环境(linux系统安全优化)
- 利用Oracle触发器实现数据库自动维护(oracle触发器类型)
- 轻松实现MySQL批量表格创建!(mysql批量创建表)
- Oracle数据库中的AND查询(oracle and查询)
- Oracle数据日志实现机制研究(oracle写数据日志)
- MySQL中的AND逻辑操作符是什么(mysql中and是什么)
- 管理系统设计与实现Research and Implementation of a Personal Salary Management System using MySQL
- Redis实现高效的标签检索技术(标签检索 redis)
- 个人使用Redis实现数据高效存储(个人用redis做什么)
- Oracle中使用除了And的其他查询关键字(oracle中除了and)
- 如何通过Redis实现原子操作(如何实现redis事物)
- Oracle中PKG的应用及实现(oracle中的pkg)
- and的区别Oracle数据库中的OR与AND的差异(oracle中or和)
- 实现支持逻辑搜索/单词搜索/词组搜索+支持OR/AND关键字的VBSCLASS!
- js实现tab选项卡函数代码
- js实现屏幕自适应局部代码分享