如何将维度为(3,50)的Embedding层接入LSTM层
解决方案
首先明确报错根因:
LSTM 要求输入为3阶张量,格式为(批量大小, 时间步数量, 单时间步特征维度),而你当前经过Embedding层后的输出是4阶张量(批量大小, 3, 50, 2*EMBEDDING_DIM),多了1维商品ID的嵌入维度,因此直接传入会报错,原代码中的Reshape操作属于冗余操作,没有解决维度不匹配的核心问题。
方案1:单时间步特征合并(最贴合你描述的业务场景)
你提到3是时间步数量,每个时间步对应50个商品ID,我们可以先把每个时间步下的50个商品的嵌入向量合并为单维度特征,把整体张量降为3阶后再传入LSTM:
layer_i_inp = Input(shape = (3,50), name = 'item') layer_i_emb = Embedding(output_dim = EMBEDDING_DIM*2, input_dim = us_it_count[0]+1, input_length = (3,50), name = 'item_embedding')(layer_i_inp) # 新增:把每个时间步下的50个嵌入向量展平为一维特征,输出shape为(None, 3, 50*2*EMBEDDING_DIM) layer_i_emb = TimeDistributed(Flatten())(layer_i_emb) # 现在直接传入LSTM即可,无需多余的维度转换 layer_i_emb = LSTM(MAX_FEATURES, dropout = 0.4, recurrent_dropout = 0.4, return_sequences = True)(layer_i_emb) layer_i_emb = LSTM(MAX_FEATURES, dropout = 0.4, recurrent_dropout = 0.4, return_sequences = True)(layer_i_emb) layer_i_emb = LSTM(MAX_FEATURES, dropout = 0.4, recurrent_dropout = 0.4)(layer_i_emb) layer_i_emb = Flatten()(layer_i_emb)
如果不想直接展平丢失商品序列信息,也可以把TimeDistributed(Flatten())换成TimeDistributed(LSTM(xxx)),先对每个时间步内的50个商品ID做序列建模,再把输出的特征传入外层处理时间步的LSTM。
方案2:调整时间步定义
如果你实际是要把3*50个商品ID整体作为一个长度为150的序列处理,可以直接把输入张量压平为2阶后再传入Embedding,调整如下:
layer_i_inp = Input(shape = (3,50), name = 'item') # 先压平成(None, 150)的序列 layer_i_inp_flat = Reshape([3*50])(layer_i_inp) layer_i_emb = Embedding(output_dim = EMBEDDING_DIM*2, input_dim = us_it_count[0]+1, input_length = 3*50, name = 'item_embedding')(layer_i_inp_flat) # 此时Embedding输出为(None, 150, 2*EMBEDDING_DIM),符合LSTM输入要求 layer_i_emb = LSTM(MAX_FEATURES, dropout = 0.4, recurrent_dropout = 0.4, return_sequences = True)(layer_i_emb) # 后续层保持不变
内容的提问来源于stack exchange,提问作者Alihan Urumov
相关产品推荐
相关产品推荐

