使用Keras构建内容访问推荐模型训练时报Graph execution error如何解决
问题诊断
这个报错和布尔型访问标签、模型结构适配性没有关系,核心原因是内容Embedding层设置的可查询ID范围小于训练数据中实际传入的内容ID,触发了Embedding查表越界。
报错日志里已经给出了明确的错误提示:
indices[10,0] = 21530 is not in [0, 21025)
Node: 'model_10/content-Embedding/embedding_lookup'
意思是传入内容Embedding层的某条样本ID是21530,但你当前构建的内容Embedding只支持查询0~21024范围内的ID,超出范围直接触发执行错误。
常见触发场景
- 统计ID总数的逻辑错误:大概率是在拆分完训练集、测试集之后才统计
n_content的数值,或者直接用去重后的内容计数作为Embedding层大小,没有考虑ID不连续、训练集包含统计范围外ID的情况。 - 代码字段残留:你是从之前的1-5分图书推荐代码改的,代码里混杂了旧的字段名(
book_id、rating)和新数据集的字段名(public_id/content_id、visit),字段映射错误时会传入异常ID值。 - 旧模型缓存问题:如果本地已经存在之前训练图书推荐生成的
regression_model.h5文件,代码会直接加载旧模型,旧模型的Embedding大小是基于旧的图书ID范围设置的,传入新的内容ID自然会越界。
修复方案
- 拆分训练集、测试集之前,先基于全量访问数据统计ID最大值,Embedding层大小设为「最大ID+1」即可覆盖所有合法ID(ID从1开始计数,0预留作填充位):
# 先执行全量ID统计,再做数据集拆分 n_users = visits['user_id'].max() n_content = visits['public_id'].max() # 统一用你数据集里实际的内容ID字段名,不要一会用content_id一会用public_id
- 统一所有代码段的字段名,把训练逻辑里残留的旧字段全部替换为当前数据集的对应字段:
# 修正后的训练调用,输入顺序、字段名和模型定义、数据集完全对应 history = model.fit( [train.user_id, train.public_id], train.visit, epochs=5, verbose=1 )
- 删除本地旧的
regression_model.h5缓存文件,重新初始化模型训练,避免加载到旧参数的模型。
后续优化提示
你当前做的是0/1二分类预测任务,现在模型直接输出点积结果、用MSE作为损失函数并不适配,等修复越界问题后可以做两处调整:
- 在点积层后增加一个Sigmoid激活的全连接层,输出0~1区间的访问概率
- 损失函数替换为二分类交叉熵
binary_crossentropy,训练时增加AUC、准确率作为评估指标,效果会比当前的回归设置好很多。
内容的提问来源于stack exchange,提问作者psyvic
相关产品推荐
相关产品推荐

