【推荐系统】TensorFlow复现论文DeepCrossing特征交叉网络结构

简介: TensorFlow复现论文DeepCrossing特征交叉网络结构

@TOC


一、导包


from collections import namedtuple # 使用具名元组


import tensorflow as tf

from tensorflow import keras

from tensorflow.keras.layers import *

from tensorflow.keras.models import *


from tqdm import tqdm


from sklearn.model_selection import train_test_split

from sklearn.preprocessing import MinMaxScaler,LabelEncoder


import pandas as pd

import numpy as np


二、读取数据


"""读取数据"""

data = pd.read_csv('./data/criteo_sample.txt')



三、获取分类特征和数值特征


"""获取分类特征和数值特征"""

columns = data.columns.values

dense_features = [feat for feat in columns if 'I' in feat]

sparse_features = [feat for feat in columns if 'C' in feat]


四、数据处理


"""数据处理"""

def data_process(data, dense_features, sparse_features):

   # 将数值特征的空值位置填补为0

   data[dense_features] = data[dense_features].fillna(0.0)

   # 调整分布

   for f in dense_features:

       data[f] = data[f].apply(lambda x: np.log(x+1) if x > -1 else -1)

   

   # 将分类特征进行编码,由于原数据中的类别都是字符串,所以要使用LabelEncoder编码成数值

   data[sparse_features]=data[sparse_features].fillna("0") # 将类别特征进行填补,使用字符串

   

   for f in sparse_features:

       le = LabelEncoder()

       data[f]=le.fit_transform(data[f])

   

   return data[dense_features + sparse_features]


train_data = data_process(data, dense_features, sparse_features)

train_data['label'] = data['label']

train_data # (200,40)



五、使用具名元组为特征做标记


"""使用具名元组为特征做标记"""

SparseFeat = namedtuple('SparseFeat', ['name', 'vocabulary_size', 'embedding_dim'])

DenseFeat = namedtuple('DenseFeat', ['name', 'dimension'])


dnn_features_columns = [SparseFeat(name=feat, vocabulary_size=data[feat].nunique(), embedding_dim = 4) for feat in sparse_features] + [DenseFeat(name=feat, dimension=1) for feat in dense_features]

dnn_features_columns



六、构建模型


6.1 构建输入层


"""构建输入层"""

def build_input_layers(dnn_features_columns):

   dense_input_dict, sparse_input_dict = {}, {}

   

   for f in dnn_features_columns:

       if isinstance(f, SparseFeat):

           sparse_input_dict[f.name] = Input(shape=(1, ), name=f.name)

       elif isinstance(f, DenseFeat):

           dense_input_dict[f.name] = Input(shape=(f.dimension, ), name=f.name)

   

   return dense_input_dict, sparse_input_dict


6.2 将类别特征进行embedding


"""将类别特征进行embedding"""

def build_embedding_layers(dnn_features_columns, input_layers_dict, is_linear):

   embedding_layer_dict = {}

   

   # 将sparse特征筛选出来

   sparse_feature_columns = list(filter(lambda x: isinstance(x,SparseFeat), dnn_features_columns)) if dnn_features_columns else []

   

   # 如果是用于线性部分的embedding层,其维度为1,否则维度就是自己定义的embedding维度

   if is_linear:

       for f in sparse_feature_columns:

           embedding_layer_dict[f.name] = Embedding(f.vocabulary_size + 1, 1, name='1d_emb_' + f.name)

   

   else:

       for f in sparse_feature_columns:

           embedding_layer_dict[f.name] = Embedding(f.vocabulary_size + 1, f.embedding_dim, name='kd_emb_' + f.name)

   

   return embedding_layer_dict


6.3 将所有的sparse特征embedding进行拼接


"""将所有的sparse特征embedding进行拼接"""

def concat_embedding_list(dnn_features_columns, input_layer_dict, embedding_layer_dict, flatten=False):

   # 筛选sparse特征

   sparse_feature_columns = list(filter(lambda x: isinstance(x, SparseFeat), dnn_features_columns))

   

   embedding_list = []

   for f in sparse_feature_columns:

       _input = input_layer_dict[f.name]

       _embed = embedding_layer_dict[f.name]

       embed = _embed(_input)

       

       if flatten:

           embed = Flatten()(embed)

       

       embedding_list.append(embed)

   

   return embedding_list


6.4 构建残差块


"""构建残差块"""

class ResidualBlock(Layer):

   def __init__(self, units):

       super(ResidualBlock, self).__init__()

       self.units = units

   

   def build(self, input_shape):

       out_dim = input_shape[-1]

       self.dnn1 = Dense(self.units, activation='relu')

       self.dnn2 = Dense(out_dim, activation='relu')

   

   def call(self, inputs):

       x = inputs

       x = self.dnn1(x)

       x = self.dnn2(x)

       x = Activation('relu')(x + inputs)

       return x


6.5 构建输出层


"""构建输出层"""

def get_dnn_logits(dnn_inputs, block_nums=3):

   dnn_out = dnn_inputs

   

   for i in range(block_nums):

       dnn_out = ResidualBlock(64)(dnn_out)

   

   dnn_logits = Dense(1, activation='sigmoid')(dnn_out)


   return dnn_logits


6.6 构建模型


"""构建模型"""

def DeepCrossing(dnn_features_columns):

   # 1.构建输入层

   dense_input_dic, sparse_input_dic = build_input_layers(dnn_features_columns)

   input_layers = list(dense_input_dic.values()) + list(sparse_input_dic.values())

   

   # 2.将类别特征进行embedding

   embedding_layer_dict = build_embedding_layers(dnn_features_columns, sparse_input_dic, is_linear=False)

   

   # 3.将数值型特征拼接在一起

   dense_dnn_list = list(dense_input_dic.values())

   dense_dnn_inputs = Concatenate(axis=1)(dense_dnn_list)

   

   # 4.将类别Embedding向量进行Flatten

   sparse_dnn_list = concat_embedding_list(dnn_features_columns, sparse_input_dic, embedding_layer_dict, flatten=True)

   sparse_dnn_inputs = Concatenate(axis=1)(sparse_dnn_list)

   

   # 6.将数值特征和类别特征进行拼接

   dnn_inputs = Concatenate(axis=1)([dense_dnn_inputs, sparse_dnn_inputs])

   

   # 7.将所有特征输入到残差模块中

   output_layer = get_dnn_logits(dnn_inputs, block_nums=3)

   

   # 8.构建模型

   model = Model(input_layers, output_layer)

   

   return model


七、训练模型


7.1 构建模型


history = DeepCrossing(dnn_features_columns)

history.summary()



7.2 编译模型


history.compile(optimizer='adam',

              loss='binary_crossentropy',

              metrics=['binary_crossentropy', tf.keras.metrics.AUC(name='auc')])


7.3 准备输入数据


train_model_input = {name: data[name] for name in dense_features + sparse_features}


7.4 模型训练


history.fit(train_model_input,

          train_data['label'].values,

          batch_size=64,

          epochs=5,

          validation_split=0.2)


目录
相关文章
|
7月前
|
机器学习/深度学习 编解码 计算机视觉
【APFN】从大佬论文中探索如何分析改进金字塔网络
【APFN】从大佬论文中探索如何分析改进金字塔网络
273 0
|
2月前
|
机器学习/深度学习 人工智能
类人神经网络再进一步!DeepMind最新50页论文提出AligNet框架:用层次化视觉概念对齐人类
【10月更文挑战第18天】这篇论文提出了一种名为AligNet的框架,旨在通过将人类知识注入神经网络来解决其与人类认知的不匹配问题。AligNet通过训练教师模型模仿人类判断,并将人类化的结构和知识转移至预训练的视觉模型中,从而提高模型在多种任务上的泛化能力和稳健性。实验结果表明,人类对齐的模型在相似性任务和出分布情况下表现更佳。
68 3
|
2月前
|
机器学习/深度学习 Web App开发 人工智能
轻量级网络论文精度笔(一):《Micro-YOLO: Exploring Efficient Methods to Compress CNN based Object Detection Model》
《Micro-YOLO: Exploring Efficient Methods to Compress CNN based Object Detection Model》这篇论文提出了一种基于YOLOv3-Tiny的轻量级目标检测模型Micro-YOLO,通过渐进式通道剪枝和轻量级卷积层,显著减少了参数数量和计算成本,同时保持了较高的检测性能。
39 2
轻量级网络论文精度笔(一):《Micro-YOLO: Exploring Efficient Methods to Compress CNN based Object Detection Model》
|
2月前
|
机器学习/深度学习 编解码 算法
轻量级网络论文精度笔记(三):《Searching for MobileNetV3》
MobileNetV3是谷歌为移动设备优化的神经网络模型,通过神经架构搜索和新设计计算块提升效率和精度。它引入了h-swish激活函数和高效的分割解码器LR-ASPP,实现了移动端分类、检测和分割的最新SOTA成果。大模型在ImageNet分类上比MobileNetV2更准确,延迟降低20%;小模型准确度提升,延迟相当。
70 1
轻量级网络论文精度笔记(三):《Searching for MobileNetV3》
|
7月前
|
机器学习/深度学习 计算机视觉 知识图谱
【YOLOv8改进】MobileViT 更换主干网络: 轻量级、通用且适合移动设备的视觉变压器 (论文笔记+引入代码)
MobileViT是针对移动设备的轻量级视觉Transformer网络,结合CNN的局部特征、Transformer的全局注意力和ViT的表示学习。在ImageNet-1k上,它以600万参数实现78.4%的top-1准确率,超越MobileNetv3和DeiT。MobileViT不仅适用于图像分类,还在目标检测等任务中表现出色,且优化简单,代码已开源。YOLOv8引入了MobileViT块,整合卷积和Transformer结构,提升模型性能。更多详情可参考相关专栏和链接。
|
2月前
|
编解码 人工智能 文件存储
轻量级网络论文精度笔记(二):《YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object ..》
YOLOv7是一种新的实时目标检测器,通过引入可训练的免费技术包和优化的网络架构,显著提高了检测精度,同时减少了参数和计算量。该研究还提出了新的模型重参数化和标签分配策略,有效提升了模型性能。实验结果显示,YOLOv7在速度和准确性上超越了其他目标检测器。
54 0
轻量级网络论文精度笔记(二):《YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object ..》
|
4月前
|
机器学习/深度学习 算法 网络架构
神经网络架构殊途同归?ICML 2024论文:模型不同,但学习内容相同
【8月更文挑战第3天】《神经语言模型的缩放定律》由OpenAI研究人员完成并在ICML 2024发表。研究揭示了模型性能与大小、数据集及计算资源间的幂律关系,表明增大任一资源均可预测地提升性能。此外,论文指出模型宽度与深度对性能影响较小,较大模型在更多数据上训练能更好泛化,且能高效利用计算资源。研究提供了训练策略建议,对于神经语言模型优化意义重大,但也存在局限性,需进一步探索。论文链接:[https://arxiv.org/abs/2001.08361]。
52 1
|
4月前
|
人工智能 算法 安全
【2023 年第十三届 MathorCup 高校数学建模挑战赛】C 题 电商物流网络包裹应急调运与结构优化问题 赛后总结之31页论文及代码
本文总结了2023年第十三届MathorCup高校数学建模挑战赛C题的解题过程,详细阐述了电商物流网络在面临突发事件时的包裹应急调运与结构优化问题,提出了基于时间序列预测、多目标优化、遗传算法和重要性评价模型的综合解决方案,并提供了相应的31页论文和代码实现。
84 0
|
7月前
|
机器学习/深度学习 自然语言处理 搜索推荐
【传知代码】图神经网络长对话理解-论文复现
在ACL2023会议上发表的论文《使用带有辅助跨模态交互的关系时态图神经网络进行对话理解》提出了一种新方法,名为correct,用于多模态情感识别。correct框架通过全局和局部上下文信息捕捉对话情感,同时有效处理跨模态交互和时间依赖。模型利用图神经网络结构,通过构建图来表示对话中的交互和时间关系,提高了情感预测的准确性。在IEMOCAP和CMU-MOSEI数据集上的实验结果证明了correct的有效性。源码和更多细节可在文章链接提供的附件中获取。
【传知代码】图神经网络长对话理解-论文复现
|
7月前
|
计算机视觉
【YOLOv8改进】 AFPN :渐进特征金字塔网络 (论文笔记+引入代码).md
YOLO目标检测专栏介绍了YOLO的有效改进和实战案例,包括AFPN——一种解决特征金字塔网络信息丢失问题的新方法。AFPN通过非相邻层直接融合和自适应空间融合处理多尺度特征,提高检测性能。此外,还展示了YOLOv8中引入的MPDIoU和ASFF模块的代码实现。详情可参考提供的专栏链接。