【问题标题】:How to input a list to the embedding layer?如何将列表输入到嵌入层?
【发布时间】:2020-03-24 21:19:41
【问题描述】:

我有三个稍后连接的输入。 其中两个输入的形状为 (1,),但第三个输入本身是一个列表(每个列表 25 个元素)。 我正在尝试将这 3 个输入到嵌入层。但是第三个(这是一个列表)会产生一个错误:ValueError:新数组的总大小必须保持不变

def rec(n_users, n_movies, n_factors, min_rating, max_rating):

    user = Input(shape=(1,))
    u = Embedding(n_users, n_factors, embeddings_initializer='he_normal',
                  embeddings_regularizer=l2(1e-6))(user)
    u = Reshape((n_factors,))(u)

    movie = Input(shape=(1,))
    m = Embedding(n_movies, n_factors, embeddings_initializer='he_normal',
                  embeddings_regularizer=l2(1e-6))(movie)
    m = Reshape((n_factors,))(m)

    tags = Input(shape=(25,))
    t = Embedding(500, n_factors)(tags)
    t = Reshape((n_factors,))(t)

    x = Concatenate()([u, m, t])
    x = Dropout(0.05)(x)

    x = Dense(10, kernel_initializer='he_normal')(x)
    x = Activation('relu')(x)
    x = Dropout(0.5)(x)

    x = Dense(1, kernel_initializer='he_normal')(x)
    x = Activation('sigmoid')(x)

    x = Lambda(lambda x: x * (max_rating - min_rating) + min_rating)(x)
    model = Model(inputs=[user, movie, tags], outputs=x)
    opt = Adam(lr=0.001)
    model.compile(loss='mean_squared_error', optimizer=opt)
    return model

X_train_array 如下所示:

[array([ 90, 291, 473, ..., 479,   5, 102], dtype=int64),
 array([1829,   98, 1321, ..., 4601,  748, 4522], dtype=int64),
 array([[  0,   0,   0, ..., 401, 201, 100],
        [  0,   0,   0, ..., 235, 100, 385],
        [  0,   0,   0, ..., 439, 487, 385],
        ...,
        [  0,   0,   0, ..., 471, 235, 100],
        [  0,   0,   0, ...,   0,   0, 100],
        [  0,   0,   0, ...,   0,   0, 221]], dtype=int64)]

【问题讨论】:

  • 这个模型在 TF 1.15 上编译得很好。你还有错误吗?如果是这样,你在哪一行代码得到这个?
  • @thushv89 t = Reshape((n_factors,))(t) 是行..说ValueError:新数组的总大小必须保持不变
  • 我明白了。那么现在它是有道理的。对于um,您只有一个输入,但对于t,它是25,所以很明显t 不能重新整形为相同的大小um 将被重新整形。你能告诉我每次重塑后你期望的输出大小吗?
  • @thushv89 1,50 是我想要的..
  • 我需要更多信息,um 将有 [None, 50] 输出,但问题是 t。它将有一个[None, 25, 50] 大小的输出。因此,如果您需要[None,1,50] 输出,则需要在时间维度上减少(例如平均)t 的嵌入。这就是你需要的。

标签: python-3.x machine-learning keras deep-learning


【解决方案1】:

所以,这是我给你的建议。这是我的解决方案的描述。您可以看到问题出在问号所在的位置。此时您需要执行一些转换才能连接并获得[None, 150]

顺便说一句,请注意我做了一些小改动(这不应该影响解决方案的正确性)。

  • 删除了l2 正则化
  • 不是创建 Adam 优化器,而是将字符串 'adam' 传递给优化器参数
import tensorflow.keras.backend as K

def rec(n_users, n_movies, n_factors, min_rating, max_rating):

    user = Input(shape=(1,))
    u = Embedding(n_users, n_factors, embeddings_initializer='he_normal')(user)
    u = Reshape((n_factors,))(u)

    movie = Input(shape=(1,))
    m = Embedding(n_movies, n_factors, embeddings_initializer='he_normal')(movie)
    m = Reshape((n_factors,))(m)

    tags = Input(shape=(25,))
    t = Embedding(500, n_factors)(tags)
    t = Lambda(lambda x: K.mean(x, axis=1))(t)

    x = Concatenate()([u, m, t])
    x = Dropout(0.05)(x)

    x = Dense(10, kernel_initializer='he_normal')(x)
    x = Activation('relu')(x)
    x = Dropout(0.5)(x)

    x = Dense(1, kernel_initializer='he_normal')(x)
    x = Activation('sigmoid')(x)

    x = Lambda(lambda x: x * (max_rating - min_rating) + min_rating)(x)
    model = Model(inputs=[user, movie, tags], outputs=x)
    model.compile(loss='mean_squared_error', optimizer='adam')
    print(model.summary())
    return model

【讨论】:

  • 成功了!!太感谢了!真的很感激。非常简洁和有用!最后一件事,对于同样的问题陈述还有其他更好的方法吗?即考虑用户、电影和标签+流派的电影推荐。
  • @ashishjohn,所以当我提出解决方案时,我只是在查看模型的架构。为了对您提出的问题提供意见,我需要更多关于您要解决的问题的信息(也可能是一个示例)。 PS:如果您对答案感到满意,请接受它 SO 礼节 :)
  • 我还是新网站,所以我并不真正了解接受功能哈哈..显然对您的回答非常高兴和满意..现在选择!
  • 关于我现在要做的事情。我想只使用元数据列训练我的模型,以便模型向我推荐电影。我在想我会在嵌入后使用 rnn 或 lstm 。但是我如何推荐多部电影?再次谢谢你.. :)
  • 您确定不想采用Recommender Systems 方法吗?
猜你喜欢
  • 2021-10-29
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 2019-11-13
  • 2020-05-29
  • 2018-04-23
  • 1970-01-01
  • 2016-08-26
相关资源
最近更新 更多