TensorFlow实现GMF时嵌入向量维度不匹配无法点乘报错
问题根因
- Keras的
Embedding层原生接收整数格式的ID作为输入,不需要提前做One-hot编码。你额外加的One-hot步骤把输入形状从[batch_size, 1]变成了[batch_size, 1, 词表长度],喂给Embedding后会对词表每个位置都生成一个latent_dim长度的向量,最终输出多了一维:- 词表长度为671的侧,Embedding输出形状为
[None, 1, 671, 15],展平后长度是1*671*15=10065 - 词表长度为9066的侧,Embedding输出形状为
[None, 1, 9066, 15],展平后长度是1*9066*15=135990
- 词表长度为671的侧,Embedding输出形状为
- 两个展平后的向量长度不匹配,自然无法执行点乘操作,和报错信息完全对应。
修复方法
直接删除多余的One-hot编码步骤,把原始整数ID直接传入Embedding层即可。此时Embedding只会为当前输入的单个ID查找对应的隐向量,输出形状为[batch_size, 1, latent_dim],展平后两侧向量长度均为latent_dim=15,维度完全匹配,可以正常点乘。
修正后的可运行代码:
import tensorflow as tf from tensorflow.keras import Input, Model from tensorflow.keras.layers import Embedding, Flatten, dot from sklearn.model_selection import train_test_split num_users = len(dataset.user_id.unique()) num_movies = len(dataset.movie_id.unique()) train, test = train_test_split(dataset, test_size=0.2) latent_dim = 15 # 电影侧输入与嵌入 movie_input = Input(shape=(1,), name='movie-input', dtype='int64') # 直接传入ID到Embedding,不需要one-hot movie_embedding = Embedding(num_movies + 1, latent_dim, name='movie-embedding')(movie_input) movie_vec = Flatten(name='movie-flatten')(movie_embedding) # 用户侧输入与嵌入 user_input = Input(shape=(1,), name='user-input', dtype='int64') # 直接传入ID到Embedding,不需要one-hot user_embedding = Embedding(num_users + 1, latent_dim, name='user-embedding')(user_input) user_vec = Flatten(name='user-flatten')(user_embedding) # 两个向量维度均为[None,15],可正常点乘 prod = dot([movie_vec, user_vec], axes=1, normalize=False) model = Model([user_input, movie_input], prod) model.compile('adam', 'mean_absolute_error')
维度校验
修复后各层输出维度如下,完全符合GMF的计算逻辑:
- 输入层:
[None, 1] - 用户Embedding输出:
[None, 1, 15] - 电影Embedding输出:
[None, 1, 15] - 展平后用户隐向量:
[None, 15] - 展平后电影隐向量:
[None, 15] - 点乘输出:
[None, 1]
内容的提问来源于stack exchange,提问作者RED أحمر
相关产品推荐
相关产品推荐

