You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TF2子类API构建双输入模型调用model.summary()报错求助

问题说明

使用TensorFlow 2子类API构建模型时,需要在call()中同时接收输入图像和目标解以完成图像重建,但双输入模式下调用model.summary()报错,单输入模式可正常运行。

可运行的单输入代码

import tensorflow as tf

class subclass(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.conv = tf.keras.layers.Conv2D(28, 3, strides=1)
        self.pool = tf.keras.layers.MaxPool2D((2, 2))

        self.dense_1 = tf.keras.layers.Dense(units=512, activation='relu')
        self.dense_2 = tf.keras.layers.Dense(units=784, activation='relu')

    def model(self):
        x = tf.keras.layers.Input(shape=(28, 28, 3))
        return tf.keras.Model(inputs=[x], outputs=self.call(x))

    def call(self, inputs):
        x = inputs
        x = self.conv(x)
        x = self.pool(x)
        v = tf.nn.relu(x)

        rec = self.dense_1(v)
        rec = self.dense_2(rec)

        return v, rec


sub = subclass()
sub.model().summary()

报错的双输入代码

import tensorflow as tf

class subclass(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.conv = tf.keras.layers.Conv2D(28, 3, strides=1)
        self.pool = tf.keras.layers.MaxPool2D((2, 2))

        self.dense_1 = tf.keras.layers.Dense(units=512, activation='relu')
        self.dense_2 = tf.keras.layers.Dense(units=784, activation='relu')

    def model(self):
        x = tf.keras.layers.Input(shape=(28, 28, 3))
        y0 = tf.cast(tf.range(0, 10, 1), dtype=tf.float32)
        y = tf.keras.layers.Input(y0)
        return tf.keras.Model(inputs=[x, y], outputs=self.call([x, y]))

    def call(self, inputs):
        x, y = inputs

        # Match shapes for product
        y = tf.expand_dims(y, axis=-1)
        y = tf.expand_dims(y, axis=0)
        y = tf.expand_dims(y, axis=0)

        x = self.conv(x)
        x = self.pool(x)
        x = tf.reshape(x, (-1, x.shape[1] * x.shape[2], 10))
        x = tf.expand_dims(x, axis=-1)
        v = tf.nn.relu(x)

        # Necessary operation for my reconstruction
        v_masked = tf.multiply(y, v)

        reconstruction = self.dense_1(v_masked)
        rec = self.dense_2(reconstruction)

        return v, rec

sub = subclass()
sub.model().summary()

报错信息

TypeError: Dimension value must be integer or None or have an __index__ method, got value '<tf.Tensor: shape=(), dtype=float32, numpy=0.0>' with type '<class 'tensorflow.python.framework.ops.EagerTensor'>'

或类似报错:

OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed in Graph execution. Use Eager execution or decorate this function with @tf.function.

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
TypeError: only integer scalar arrays can be converted to a scalar index    
...    
TypeError: Error converting shape to a TensorShape: only integer scalar arrays can be converted to a scalar index.
问题根源
  1. Input层定义错误:tf.keras.layers.Input()需要传入形状参数(如shape=(10,)),而非具体张量y0,否则会导致维度解析失败。
  2. 静态形状误用:x.shape[1] * x.shape[2]使用了Tensor的静态形状,在图模式下静态形状元素是Tensor对象,无法直接做算术运算,需改用动态形状获取方式tf.shape(x)。
修正后的代码
import tensorflow as tf

class subclass(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.conv = tf.keras.layers.Conv2D(28, 3, strides=1)
        self.pool = tf.keras.layers.MaxPool2D((2, 2))

        self.dense_1 = tf.keras.layers.Dense(units=512, activation='relu')
        self.dense_2 = tf.keras.layers.Dense(units=784, activation='relu')

    def model(self):
        # 正确定义Input层:指定输入形状
        x = tf.keras.layers.Input(shape=(28, 28, 3))
        # y是长度为10的向量,指定shape=(10,)
        y = tf.keras.layers.Input(shape=(10,))
        return tf.keras.Model(inputs=[x, y], outputs=self.call([x, y]))

    def call(self, inputs):
        x, y = inputs

        # 扩展y的维度以匹配x的形状,保持批量维度兼容
        y = tf.expand_dims(y, axis=1)
        y = tf.expand_dims(y, axis=1)
        y = tf.expand_dims(y, axis=-1)

        x = self.conv(x)
        x = self.pool(x)
        
        # 使用tf.shape获取动态形状,避免图模式下的静态形状问题
        x_shape = tf.shape(x)
        hw = x_shape[1] * x_shape[2]
        x = tf.reshape(x, (-1, hw, 10))
        x = tf.expand_dims(x, axis=-1)
        v = tf.nn.relu(x)

        v_masked = tf.multiply(y, v)

        reconstruction = self.dense_1(v_masked)
        rec = self.dense_2(reconstruction)

        return v, rec

sub = subclass()
sub.model().summary()
关键修正点
  • Input层:将y = tf.keras.layers.Input(y0)改为y = tf.keras.layers.Input(shape=(10,)),明确输入形状而非传入具体张量。
  • 动态形状计算:用tf.shape(x)[1] * tf.shape(x)[2]替代x.shape[1] * x.shape[2],确保图模式下能正确处理维度计算。
  • 维度扩展调整:调整y的expand_dims顺序,确保和处理后的x维度完全匹配,避免广播错误。

内容的提问来源于stack exchange,提问作者Nankin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:50:26