TensorFlow.Keras时序分类seq2seq模型RNNCell属性缺失错误求助
错误原因与修复方案
你触发报错的核心原因是:tfa.seq2seq.AttentionWrapper要求传入的第一个参数必须是RNNCell实例或堆叠的RNNCell集合,但你的代码中将封装好的RNN层对象直接传入了AttentionWrapper,RNN层是处理完整序列计算的高阶包装类,没有Cell要求的output_size、state_size属性,因此触发了类型错误。
修复步骤
1. 解码器核心逻辑修改
不需要将堆叠的LSTMCell再封装为RNN层,而是用StackedRNNCells将多个LSTMCell包装为统一的Cell实例,直接传给AttentionWrapper即可:
class Decoder(tf.keras.Model): def __init__(self, char2numY, dec_units, batch_sz, layers, attention_type='luong', bidirectional=False): super(Decoder, self).__init__() self.batch_sz = batch_sz self.dec_units = dec_units #must be two times of enc_units self.attention_type = attention_type # Final Dense layer on which softmax will be applied self.fc = Dense(char2numY, use_bias=False) # Define the fundamental cell for decoder recurrent structure if bidirectional: decoder_cells = [LSTMCell(hidden_dim*2) for hidden_dim in layers] else: decoder_cells = [LSTMCell(hidden_dim) for hidden_dim in layers] # 【修改点1】用StackedRNNCells封装多Cell列表,不要包RNN层 self.decoder_stacked_cells = tf.keras.layers.StackedRNNCells(decoder_cells) # Sampler self.sampler = tfa.seq2seq.sampler.TrainingSampler() # Create attention mechanism with memory = None self.attention_mechanism = self.build_attention_mechanism(self.dec_units, None, None, self.attention_type) # Wrap attention mechanism with the fundamental rnn cell of decoder self.rnn_cell = self.build_rnn_cell(batch_sz) # Define the decoder with respect to fundamental rnn cell self.decoder = tfa.seq2seq.BasicDecoder(self.rnn_cell, sampler=self.sampler, output_layer=self.fc) def build_rnn_cell(self, batch_sz): # 【修改点2】传入堆叠的Cell实例,而非RNN层 rnn_cell = tfa.seq2seq.AttentionWrapper(self.decoder_stacked_cells, self.attention_mechanism, attention_layer_size=self.dec_units) return rnn_cell def build_attention_mechanism(self, dec_units, memory, memory_sequence_length, attention_type='luong'): return tfa.seq2seq.LuongAttention(units=self.dec_units, memory=memory, memory_sequence_length=None) def build_initial_state(self, batch_sz, encoder_state, Dtype): decoder_initial_state = self.rnn_cell.get_initial_state(batch_size=batch_sz, dtype=Dtype) decoder_initial_state = decoder_initial_state.clone(cell_state=encoder_state) return decoder_initial_state def call(self, inputs, initial_state): x = inputs outputs, final_states, final_sequence_lengths = self.decoder(x, initial_state=initial_state, sequence_length=None) logits = outputs.rnn_output return outputs, final_states
2. 测试代码配套修改
# 【修改点3】调整Decoder初始化传参顺序,和__init__参数对应 decoder = Decoder(vocab_size, dec_units, batch_sz, layers, 'luong', bidirectional=True) sample_x = tf.random.uniform((batch_sz, output_max_length, vocab_size)) # 输入要对应嵌入后的维度 # 【修改点4】用编码器输出作为注意力的memory,原sample_output未定义 decoder.attention_mechanism.setup_memory(encoder_outputs_and_states[0]) initial_state = decoder.build_initial_state(batch_sz, encoder_states, tf.float32) sample_decoder_outputs, _ = decoder(sample_x, initial_state) print("Decoder Outputs Shape: ", sample_decoder_outputs.rnn_output.shape)
内容的提问来源于stack exchange,提问作者Chandra
相关产品推荐
相关产品推荐

