【问题标题】:How to use Embedding layer for RNN with a categorical feature - Classification Task for RecoSys如何使用具有分类特征的 RNN 嵌入层 - RecoSys 的分类任务
【发布时间】:2019-08-20 09:43:45
【问题描述】:

我想为分类特征(项目 ID)构建一个带有嵌入层的模型(RNN >> LSTM),我的训练集如下所示:

train_x = [[[184563.1], [184324.1], [187853.1], [174963.1], [181663.1]], [[…],[…],[…],[…],[… ]], …]

我预测第六个物品ID:

train_y = [0,1,2, ...., 12691]

我有 12692 个唯一项目 ID,时间步长 = 5,这是一个分类任务。

这是我到目前为止所做的简要总结:(如果我错了,请纠正我)

  1. 分类特征的单热编码:

train_x = [[[1 0 0 … 0 0 0], [0 1 0 … 0 0 0], [0 0 1 … 0 0 0], […], […]], [ […],[…],[…],[…],[…]],…]

  1. 构建模型:
model = Sequential()

model.add(Embedding(input_dim=12692 , output_dim=250, input_length=5))

model.add(LSTM(128, return_sequences=True)
model.add(Dropout(0.2)) 
model.add(BatchNormalization())

model.add(LSTM(128, return_sequences=True))
model.add(Dropout(0.1)) 
model.add(BatchNormalization())

model.add(LSTM(128))
model.add(Dropout(0.2)) 
model.add(BatchNormalization())

model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))

model.add(Dense(12692, activation='softmax'))

opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)
model.compile(
      loss='sparse_categorical_crossentropy',
      optimizer=opt,
      metrics=['accuracy'])

print(model.summary())

history = model.fit(
      train_x, train_y,
      batch_size=64,
      epochs=epochs,
      validation_data=(validation_x, validation_y))

score = model.evaluate(validation_x, validation_y, verbose=0)

我得到了这个模型摘要:

训练 131204 个样本,验证 107904 个样本

但是之后出现这个错误:

ValueError: 检查输入时出错:预期 embedding_input 有 2 维,但得到的数组形状为 (131204, 5, 12692)

我的错误在哪里,解决办法是什么?

【问题讨论】:

    标签: python tensorflow lstm recurrent-neural-network embedding


    【解决方案1】:

    嵌入层将正整数(索引)转换为固定大小的密集向量(Docs)。因此,您的 train_x 不是单热编码,而是表示其在词汇表中的索引的整数。它将是与分类特征对应的整数。

    train_x.shape 将是(No:of sample X 5) --> 每个代表分类特征的索引

    train_y.shape 将是 (No:of sample) --> 每个代表时间序列中第六项的索引。

    工作样本

    import numpy as np
    import keras
    from keras.layers import Embedding, LSTM, Dense
    n_samples = 100
    
    train_x = np.random.randint(0,12692,size=(n_samples ,5))
    train_y = np.random.randint(0,12692,size=(n_samples))
    
    
    model = keras.models.Sequential()
    
    model.add(Embedding(input_dim=12692+1, output_dim=250, input_length=5))
    model.add(LSTM(128, return_sequences=True))
    model.add(LSTM(32))
    model.add(Dense(32, activation='relu'))
    model.add(Dense(12692, activation='softmax'))
    
    opt = keras.optimizers.Adam(lr=0.001, decay=1e-6)
    model.compile(
          loss='sparse_categorical_crossentropy',
          optimizer=opt,
          metrics=['accuracy'])
    
    print(model.summary())
    
    history = model.fit(
          train_x, train_y,
          batch_size=64,
          epochs=32)
    

    【讨论】:

    • 感谢您的回答。如果您也能解释这 3 点,那就太好了: 1. 为什么 input_dim=12692+1 中的“+1”? 2. 如您在本例中所见,如果我想将价格(数字)作为第二个特征,我只考虑 itemID 作为一个特征,我应该如何将这两个特征组合为模型中的输入? 3. 你有什么改进模型的建议,比如使用:TimeDistributed 还是 GRU?
    • 1.第一个 itemID 表示为 1 而不是 0,因此它将是 vocab_size + 1(我在答案中给出的文档链接中也提到过) 2. 为其他特征创建一个输入层,并将嵌入层的输出与输入层合并。 3. 你将不得不进行实验。通常,使用 GRU 进行训练比 LSTM 更快,但从性能点(准确性)来看,两者几乎相同。
    猜你喜欢
    • 2021-09-21
    • 1970-01-01
    • 2019-06-13
    • 2016-07-29
    • 2021-10-05
    • 1970-01-01
    • 2020-05-27
    • 2017-08-17
    • 1970-01-01
    相关资源
    最近更新 更多