使用TensorFlow构建3层双向LSTM时维度不匹配错误排查
解决3层双向LSTM维度不匹配问题(tf.contrib.rnn.stack_bidirectional_dynamic_rnn)
嘿,我来帮你搞定这个维度不匹配的问题!你的核心问题出在**stack_bidirectional_dynamic_rnn的cell构建方式上**——这个函数本身就是用来逐层堆叠双向RNN的,不需要你再用MultiRNNCell去嵌套单个LSTM单元,否则会导致输入输出维度完全错位。
错误原因分析
你之前构建cell_forw和cell_back的时候,后面的层用了MultiRNNCell([BasicLSTMCell]*i),比如第二层是包含1个LSTM的MultiRNNCell,第三层是包含2个LSTM的MultiRNNCell。但stack_bidirectional_dynamic_rnn的设计逻辑是:
- 列表中的每个元素对应一层的前向/后向cell
- 每一层的双向输出(前向cell输出+后向cell输出,维度拼接为
2*num_hidden)会自动作为下一层的输入 - 它期望每个cell是单个RNN单元(比如BasicLSTMCell),而不是多层嵌套的MultiRNNCell
你的写法让函数误以为每一层是一个多层RNN,导致输入维度(上一层的双向输出2048=2*1024)和cell期望的输入维度不匹配,才出现了2048 vs 3072的报错。
修正后的代码
直接把cell_forw和cell_back改成每层一个BasicLSTMCell的列表即可,同时建议把输入占位符的batch维度设为None,支持可变batch size:
learning_rate=0.01 batch_size=3187 annealing_rate=0.85 beta1=0.9 beta2=0.99 epsilon=10**(-8) dropout=0.95 layer_size=3 lstm_size=1024 time_steps=34 num_hidden=1024 # 把batch维度设为None,支持可变批量大小(更灵活) place_x=tf.placeholder("float",[None, time_steps, 41]) place_y=tf.placeholder("float",[None,32,70]) # 正确构建3层前向/后向cell列表:每层一个BasicLSTMCell cell_forw = [tf.nn.rnn_cell.BasicLSTMCell(num_hidden, state_is_tuple=True) for _ in range(layer_size)] cell_back = [tf.nn.rnn_cell.BasicLSTMCell(num_hidden, state_is_tuple=True) for _ in range(layer_size)] # 可选:如果需要dropout,给每个cell包裹DropoutWrapper # cell_forw = [tf.nn.rnn_cell.DropoutWrapper(cell, output_keep_prob=dropout) for cell in cell_forw] # cell_back = [tf.nn.rnn_cell.DropoutWrapper(cell, output_keep_prob=dropout) for cell in cell_back] # 调用stack_bidirectional_dynamic_rnn outputs, fw_final_states, bw_final_states = tf.contrib.rnn.stack_bidirectional_dynamic_rnn( cell_forw, cell_back, place_x, dtype=tf.float32 )
额外说明
- 修正后,
outputs的维度是[batch_size, time_steps, 2*num_hidden],因为每一层的双向输出会拼接起来,最后一层的输出就是这个维度 - 如果需要在输出后接全连接层,记得根据这个维度来调整后续层的参数
内容的提问来源于stack exchange,提问作者shivam13juna
相关产品推荐
相关产品推荐

