如何解决Keras自编码器报错:You must feed a value for placeholder tensor
错误原因
- 解码器输入逻辑错误:你当前定义的解码器将原始输入
input_img也作为输入项,但解码器的核心逻辑是仅接收编码器输出的隐向量即可生成重建结果,额外引入的输入会导致计算图依赖异常。同时跳跃连接使用的x1是编码器的中间层张量,直接在解码器中引用会导致两个模型的计算图耦合,解码器无法独立获得x1的数值来源,进而触发占位符未赋值的报错。 - 计算图残留冲突:你代码中设置了
tf.compat.v1.disable_eager_execution()关闭了TF2默认的动态图模式,多次运行后旧模型的节点残留在计算图中,你当前定义的隐向量维度是2048,但报错中提示的占位符维度是1024,就是旧模型残留节点导致的。
修复方案
第一步:修正自编码器模型定义
核心逻辑是调整编码器输出项和解码器输入项,把跳跃连接需要的x1作为编码器的输出之一传递给解码器,避免跨模型直接引用张量:
def AE_V2_Model(filters, latentDim): HEIGHT = 28 WIDTH = 28 padding_ = "same" depth = 1 inputShape = (HEIGHT, WIDTH, depth) input_img = Input(shape=inputShape) # 编码器部分不变 x = Conv2D(filters[0], (3, 3), padding='same')(input_img) x = BatchNormalization()(x) x = Activation('relu')(x) x = MaxPooling2D((2, 2), padding='same')(x) x = Conv2D(filters[1], (3, 3), padding='same')(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = MaxPooling2D((2, 2), padding='same')(x) x1 = Conv2D(filters[2], (3, 3), padding='same')(x) x = BatchNormalization()(x1) x = Activation('relu')(x) x = MaxPooling2D((2, 2), padding='same')(x) x = Conv2D(filters[3], (3, 3), padding='same')(x) x = BatchNormalization()(x) x = Activation('relu')(x) encoded = MaxPooling2D((2, 2), padding='same')(x) volumeSize = K.int_shape(encoded) x = Flatten()(encoded) latent = Dense(latentDim)(x) # 编码器同时输出隐向量和跳跃连接需要的x1 encoder = Model(input_img, [latent, x1], name="encoder") # 解码器输入改为隐向量 + 编码器传递的x1 latentInputs = Input(shape=(latentDim,)) x1_input = Input(shape=K.int_shape(x1)[1:]) # 自动适配x1的形状,不用手动写死 x = Dense(np.prod(volumeSize[1:]))(latentInputs) x = Reshape((volumeSize[1], volumeSize[2], volumeSize[3]))(x) x = Conv2D(filters[3], (3, 3), padding='same')(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = UpSampling2D((2, 2))(x) x = Conv2D(filters[2], (3, 3), padding='same')(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = UpSampling2D((2, 2))(x) # 跳跃连接使用传入的x1_input,不直接引用编码器的x1 x = add([x, x1_input]) x = Conv2D(filters[1], (3, 3), padding='same')(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = UpSampling2D((2, 2))(x) x = Conv2D(filters[0], (3, 3), padding='same')(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = UpSampling2D((2, 2))(x) x = Conv2D(1, (3, 3), padding='same')(x) x = BatchNormalization()(x) decoded = Activation('sigmoid')(x) # 解码器定义只保留必要的两个输入 decoder = Model([latentInputs, x1_input], decoded, name="decoder") # 组装自动编码器,将编码器的两个输出直接传入解码器 autoencoder = Model(input_img, decoder(encoder(input_img)), name="autoencoder") return encoder, decoder, autoencoder
第二步:修复运行环境配置
- 删除代码中的
tf.compat.v1.disable_eager_execution(),TF2默认开启的动态图模式可以大幅减少这类计算图残留报错 - 在实例化模型之前添加一行
tf.keras.backend.clear_session(),清空之前运行残留的计算图节点
修改完成后重新运行代码即可正常训练。
内容的提问来源于stack exchange,提问作者aymane_it
相关产品推荐
相关产品推荐

