eric-sjq 2024-07-21 21:20 采纳率: 66.7%
浏览 9
已结题

tensorflow自定义层报错:无法在第一维度未知的张量上迭代

我在用Tensorflow的自定义层构建模型时报错:

  File "seq2seq.py", line 414, in <module>
    _, state_h, state_c = encoder_lstm(encoder_embedding)
  File "C:\Users\sjq\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\keras\engine\keras_tensor.py", line 415, in __iter__
    raise TypeError(
TypeError: Cannot iterate over a Tensor with unknown first dimension.

这是我的层定义和模型定义代码:

    class EnhancedAttentionGRUCell_41(AttentionGRUCell):
        def __init__(self, units, att_units, temp=1.0, **kwargs):
            super().__init__(units, att_units, **kwargs)
            self.en = En(att_units)
            self.aaaaa = Aa(temp)
            
        def call(self, inputs, states, training=None):
            tf.compat.v1.enable_eager_execution()
            print('ss',inputs.shape)
            h_prev, seq_embed = states
            
            h_gru, _ = self.gru_cell(inputs, states=[h_prev])
            attended_seq = self.en(seq_embed)
            temp_pooled_attended_seq = self.aaaaa(attended_seq)
            output = tf.concat([h_gru, temp_pooled_attended_seq], axis=-1)
            
            return output, [output, seq_embed]
    class AttentionGRULayerEn_41(Layer):
        def __init__(self, units, att_units, **kwargs):
            super(AttentionGRULayerEn_41, self).__init__(**kwargs)
            self.cell = EnhancedAttentionGRUCell_41(units, att_units)
            self.units = units
            self.att_units = att_units
            self.input_dim=2048*20
            
        '''
        def get_initial_state(self, inputs):
            batch_size = tf.shape(inputs)[0]
            initial_hidden = tf.zeros(shape=(batch_size, self.units))
            return initial_hidden, inputs
        '''
        def get_initial_state(self, inputs):
            batch_size = batchsize#tf.shape(inputs)[0]  # 获取动态批次大小
            initial_hidden = tf.zeros(shape=(batch_size, self.units))  # 根据批次大小创建隐藏状态
            initial_seq_embed = tf.zeros(shape=(batch_size, tf.shape(inputs)[1], self.input_dim)) 
            return initial_hidden, initial_seq_embed
        

        def call(self, inputs, states=None, training=None):
            if not tf.executing_eagerly():
                return inputs
            if states is None:
                states = self.get_initial_state(inputs)
            #tf.assert_rank(x, 2)
            #print(inputs.shape)
            outputs, new_states = tf.keras.backend.rnn(self.cell, inputs, states,
                                                      constants=None, unroll=False, time_major=False,
                                                      go_backwards=False, mask=None)
            final_output = outputs if isinstance(outputs, tf.Tensor) else outputs[-1]
            return final_output, new_states




        encoder_inputs = Input(shape=(None,))
        encoder_embedding = Embedding(input_dim=input_vocab_size,
            output_dim=embedding_dim)(encoder_inputs)
        encoder_lstm = LSTM(units)
        _, state_h, state_c = encoder_lstm(encoder_embedding)
        encoder_states = [state_h, state_c]

        model_encoder = Model(encoder_inputs, encoder_states)

        # 解码器模型
        decoder_inputs = Input(shape=(None, ))
        decoder_embedding = Embedding(input_dim=output_vocab_size, output_dim=embedding_dim,
                                      batch_input_shape=[batchsize, None])(decoder_inputs)
        decoder_lstm = AttentionGRULayerEn_41(units, units)
        decoder_outputs, _, _ = decoder_lstm(decoder_embedding, initial_state=encoder_states)
        decoder_dense = Dense(output_vocab_size, activation='softmax')
        decoder_outputs = decoder_dense(decoder_outputs)

        model_decoder = Model([decoder_inputs] + encoder_states, [decoder_outputs])

        # 训练模型
        model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
        model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])


  • 写回答

4条回答 默认 最新

  • 阿里嘎多学长 2024-07-21 21:20
    关注

    以下内容由AIGC及阿里嘎多学长共同生成、有用望采纳:


    根据您提供的错误信息和代码,以下是可能的解决方案和一些建议:

    1. TypeError错误:这个错误通常发生在尝试迭代或操作一个形状不确定的Tensor时。在您的代码中,TypeError: Cannot iterate over a Tensor with unknown first dimension. 错误可能是由于encoder_embedding的输出形状不确定导致的。您需要确保encoder_embedding的输出形状是已知的,或者在使用它之前将其转换为具有确定形状的Tensor。

    2. 自定义层的兼容性问题:看起来您的自定义层AttentionGRULayerEn_41在某些方面与Tensorflow的预期行为不兼容。这可能是因为自定义层的实现与Tensorflow的内部机制不匹配。您需要检查自定义层的实现,确保它遵循Tensorflow的API规范。

    3. 确保张量维度一致性:在自定义层中使用tf.concat时,需要确保所有参与合并的Tensor在除了合并轴之外的其他维度上形状是一致的。检查h_grutemp_pooled_attended_seq的维度,确保它们在合并前是兼容的。

    4. 检查自定义层的初始化和调用逻辑:在EnhancedAttentionGRUCell_41call方法中,您启用了Eager Execution,这在自定义层中通常不是必需的。此外,您在get_initial_state中使用了batchsize变量,但没有在函数签名中定义它。确保所有变量在使用前都已经被正确定义和初始化。

    5. 动态批处理大小的处理:在get_initial_state方法中,您使用了batch_size来创建初始状态,但是注释中提到使用tf.shape(inputs)[0]来获取动态批次大小。确保您使用的是正确的方法来获取批次大小,并且它与模型的其他部分兼容。

    6. Eager Execution的启用:在自定义层中启用Eager Execution可能会影响Tensorflow的图执行模式,这可能会导致一些不可预见的问题。除非您有特别的理由需要这样做,否则建议不要在自定义层中启用Eager Execution。

    7. 模型构建和编译:确保在构建模型时,所有层都按照预期连接,并且在编译模型时指定了正确的优化器、损失函数和评估指标。检查modelmodel_encodermodel_decoder的构建逻辑,确保它们正确地组合了输入、输出和状态。

    针对您的代码,这里有一些具体的建议:

    • 移除tf.compat.v1.enable_eager_execution(),因为它可能不是必要的,并且可能会干扰Tensorflow的图执行模式。
    • 确保batchsize在使用之前已经被定义,并且是正确的值。
    • 检查encoder_embedding的输出形状,确保它在传递给encoder_lstm之前是已知的。
    • 在自定义层中,确保所有张量操作都有正确的维度,特别是在使用tf.concat时。
    • 仔细检查自定义层的实现,特别是状态管理和张量操作,确保它们与Tensorflow的预期行为一致。

    最后,如果您在解决这些问题时仍然遇到困难,您可能需要查阅Tensorflow的官方文档或社区论坛,以获取更多关于自定义层实现的帮助和建议。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 8月11日
  • 已采纳回答 8月3日
  • 修改了问题 7月21日
  • 创建了问题 7月21日

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见