【推荐系统】TensorFlow复现论文NeuralCF网络结构

简介: 【推荐系统】TensorFlow复现论文NeuralCF网络结构

下图为NeutralCF的模型结构图,总共两个分支,第一个分支为GML,第二个为MLP,GML通路将两个特征的Embedding向量进行内积操作,MLP将两个特征的Embedding的向量进行拼接,然后使用多层感知机进行传播,然后将两个通路输出的向量进行拼接,导入全连接层(输出层),输出Score。

一、导包

import tensorflow as tf
from tensorflow.keras.layers import *
from tensorflow.keras.models import *
from tensorflow.keras.utils import plot_model
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import  MinMaxScaler, LabelEncoder
import itertools
import pandas as pd
import numpy as np
from tqdm import tqdm
from collections import namedtuple
import warnings
warnings.filterwarnings("ignore")

二、读取数据

# 读取数据,NCF使用的特征只有user_id和item_id
rnames = ['user_id','movie_id','rating','timestamp']
data = pd.read_csv('./data/ml-1m/ratings.dat', sep='::', engine='python', names=rnames)

三、特征编码处理

lbe = LabelEncoder()
data['user_id'] = lbe.fit_transform(data['user_id'])
data['movie_id'] = lbe.fit_transform(data['movie_id'])
train_data = data[['user_id', 'movie_id']]
train_data['label'] = data['rating']

四、使用具名元组为特征进行处理

SparseFeat = namedtuple('SparseFeat', ['name', 'vocabulary_size', 'embedding_dim'])
DenseFeat = namedtuple('DenseFeat', ['name', 'dimension'])
dnn_features_columns = [SparseFeat('user_id', train_data['user_id'].nunique(), 8),
                        SparseFeat('movie_id', train_data['movie_id'].nunique(), 8)]

五、构建模型

5.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

5.2 Embedding层

def build_embedding_layers(dnn_features_columns, sparse_input_dict, prefix="", is_linear=True):
    embedding_layers_dict = {}
    sparse_feature_columns = list(filter(lambda x: isinstance(x, SparseFeat), dnn_features_columns)) if dnn_features_columns else []
    if is_linear:
        for f in sparse_feature_columns:
            embedding_layers_dict[f.name] = Embedding(f.vocabulary_size + 1, 1, name= prefix + '_1d_emb_' +  + f.name)
    else:
        for f in sparse_feature_columns:
            embedding_layers_dict[f.name] = Embedding(f.vocabulary_size + 1, f.embedding_dim, name=prefix + '_kd_emb_' +  f.name)
    return embedding_layers_dict

5.3 GML

def build_gml_layers(gml_user_embedding, gml_movie_embedding):
    return Multiply()([gml_user_embedding, gml_movie_embedding])

5.4 MLP

def build_mlp_layers(mlp_input, units=(32, 16)):
    for out_dim in units:
        mlp_input = Dense(out_dim)(mlp_input)
    return mlp_input

5.5 输出层

def bulid_output_layers(concat_output):
    return Dense(1)(concat_output)

5.6 构建模型

def NCF(dnn_features_columns):
    # 1. 获取字典输入层,键为列名,值为对应的Input
    _, sparse_input_dict = build_input_layers(dnn_features_columns)
    # 2. 获取真实输入层,使用列表存储每个列的Input
    input_layers = list(sparse_input_dict.values())
    # 3. 将SparseFeature进行Embedding,有两路,分别是GML和MLP
    embedding_gml_dict = build_embedding_layers(dnn_features_columns, sparse_input_dict, prefix="GML", is_linear=False)
    embedding_mlp_dict = build_embedding_layers(dnn_features_columns, sparse_input_dict, prefix="MLP", is_linear=False)
    # 4. 将Embedding后的特征进行展开,因为Embedding后为(?,1,8)
    gml_user_embedding = Flatten()(embedding_gml_dict['user_id'](sparse_input_dict['user_id']))
    gml_movie_embedding = Flatten()(embedding_gml_dict['movie_id'](sparse_input_dict['movie_id']))
    mlp_user_embedding = Flatten()(embedding_mlp_dict['user_id'](sparse_input_dict['user_id']))
    mlp_movie_embedding = Flatten()(embedding_mlp_dict['movie_id'](sparse_input_dict['movie_id']))
    # 5. 进行GML,就是展开后的特征进行内积
    gml_output = build_gml_layers(gml_user_embedding, gml_movie_embedding)
#     gml_output = tf.multiply(gml_movie_embedding, gml_user_embedding)
#     gml_output = Multiply()([gml_user_embedding, gml_movie_embedding])
    # 6. 进行MLP,将特征进行连接,传入MLP层
    mlp_input = Concatenate(axis=1)([mlp_user_embedding, mlp_movie_embedding])
    mlp_output = build_mlp_layers(mlp_input, (32, 16))
    # 7. 将GML和MLP层的输出进行连接
    concat_output = Concatenate(axis=1)([gml_output, mlp_output])
    # 8.传入到输出层中,获取评分
    output_layers = bulid_output_layers(concat_output)
    # 构建模型
    model = Model(input_layers, output_layers)
    return model

六、运转模型

history = NCF(dnn_features_columns)
# 编译模型
history.compile(optimizer="adam", 
                loss="mse", 
                metrics=['mae'])
# 训练数据做成字典,与输入层做对应
train_model_input = {name: train_data[name] for name in ['user_id', 'movie_id']}
history.fit(train_model_input, 
            train_data['label'].values,
            batch_size=128, 
            epochs=2, 
            validation_split=0.2)

# 绘制网络结构图
plot_model(history,show_shapes=True)


目录
相关文章
|
9月前
|
机器学习/深度学习 资源调度 算法框架/工具
AI-ANNE: 将神经网络迁移到微控制器的深度探索——论文阅读
AI-ANNE框架探索将深度学习模型迁移至微控制器的可行路径,基于MicroPython在Raspberry Pi Pico上实现神经网络核心组件,支持本地化推理,推动TinyML在边缘设备中的应用。
513 10
|
9月前
|
机器学习/深度学习 边缘计算 算法
SEENN: 迈向时间脉冲早退神经网络——论文阅读
SEENN提出一种时间脉冲早退神经网络,通过自适应调整每个样本的推理时间步数,有效平衡脉冲神经网络的准确率与计算效率。该方法基于置信度判断或强化学习策略,在保证高精度的同时显著降低能耗与延迟,适用于边缘计算与实时处理场景。
500 13
|
机器学习/深度学习 编解码 TensorFlow
RT-DETR改进策略【模型轻量化】| 替换骨干网络为EfficientNet v1 高效的移动倒置瓶颈结构
RT-DETR改进策略【模型轻量化】| 替换骨干网络为EfficientNet v1 高效的移动倒置瓶颈结构
815 0
RT-DETR改进策略【模型轻量化】| 替换骨干网络为EfficientNet v1 高效的移动倒置瓶颈结构
|
9月前
|
机器学习/深度学习 缓存 算法
2025年华为杯A题|通用神经网络处理器下的核内调度问题研究生数学建模|思路、代码、论文|持续更新中....
2025年华为杯A题|通用神经网络处理器下的核内调度问题研究生数学建模|思路、代码、论文|持续更新中....
680 1
|
机器学习/深度学习 自动驾驶 计算机视觉
RT-DETR改进策略【模型轻量化】| 替换骨干网络为 GhostNet V1 基于 Ghost Module 和 Ghost Bottlenecks的轻量化网络结构
RT-DETR改进策略【模型轻量化】| 替换骨干网络为 GhostNet V1 基于 Ghost Module 和 Ghost Bottlenecks的轻量化网络结构
732 61
RT-DETR改进策略【模型轻量化】| 替换骨干网络为 GhostNet V1 基于 Ghost Module 和 Ghost Bottlenecks的轻量化网络结构
|
人工智能 算法 异构计算
阿里云基础网络技术5篇论文入选全球网络顶会NSDI
近日,阿里云基础网络技术5篇论文被NSDI 2025主会录用。研究涵盖大模型训练网络故障诊断、仿真、容器网络性能诊断、CDN流控算法智能选择及GPU解耦推理优化等领域。其中,《Evolution of Aegis》提出增强现有体系+训练过程感知的两阶段演进路线,显著降低故障诊断耗时;《SimAI》实现高精度大模型集群训练模拟;《Learning Production-Optimized Congestion Control Selection》通过AliCCS优化CDN拥塞控制;《Prism》设计全新GPU解耦推理方案;《ScalaCN》解决容器化RDMA场景性能问题。
767 7
阿里云基础网络技术5篇论文入选全球网络顶会NSDI
|
SQL 缓存 Cloud Native
NSDI'24 | 阿里云飞天洛神云网络论文解读——《Poseidon》揭秘新型超高性能云网络控制器
NSDI'24 | 阿里云飞天洛神云网络论文解读——《Poseidon》揭秘新型超高性能云网络控制器
594 63
|
机器学习/深度学习 搜索推荐 算法
推荐系统网络序言
推荐系统的基本架构包括用户画像、召回、粗排、精排与混排五个模块。用户画像构建兴趣,召回筛选候选集,粗排和精排排序商品,混排处理多内容展示。精排阶段是学术界和工业界的重点,目标是筛选用户可能最喜欢的item列表,主要采用CTR预估模型进行排序。CTR模型从LR进化到embedding+MLP范式,探索高效高阶交叉信息。推荐系统是一个系统工程,需考虑在线与离线一致性,特征和模型的在离线不一致会带来问题。CTR模型输入为大量成对(features、label)数据,特征包含用户本身、行为、上下文和物品特征,离散型特征可采用one-hot或embedding方式处理,连续型特征可分段离散化。
|
canal 负载均衡 智能网卡
阿里云洛神云网络论文入选SIGCOMM'25主会,相关实习生岗位火热招聘中
阿里云飞天洛神云网络的两项核心技术Nezha和Hermes被SIGCOMM 2025主会录用。Nezha通过计算网络解耦实现vSwitch池化架构,大幅提升网络性能;Hermes则提出用户态引导I/O事件通知框架,优化L7负载均衡。这两项技术突破解决了云网络中的关键问题,展现了阿里云在网络领域的领先实力。
2004 2