VAE添加Concatenate/Add层报Graph disconnected错误求助
问题描述
我正在为自回归时间序列任务扩展现有VAE网络,引入输入泄漏机制。使用LSTM模块时,无Concatenate或Add层的标准网络可正常运行,但精度不理想。因此我希望实现自回归:生成时序时结合mu、sigma与历史样本。
为此我编写代码添加输入及维度匹配层,但始终报错:
ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_39:0", shape=(None, 4, 96), dtype=float32) at layer "lstm_29". The following previous layers were accessed without issue: ['repeat_vector_11', 'lstm_30', 'time_distributed_8']
相关代码如下:
from tensorflow import keras import tensorflow as tf from tensorflow.keras import layers class Sampling(layers.Layer): """Uses (z_mean, z_log_var) to sample z.""" def call(self, inputs): z_mean, z_log_var = inputs batch = tf.shape(z_mean)[0] dim = tf.shape(z_mean)[1] epsilon = tf.keras.backend.random_normal(shape=(batch, dim), mean=0., stddev=1.) return z_mean + tf.exp(0.5 * z_log_var) * epsilon # Build encoder and decoder latent_dim = 2 input_shape = (4, 96) encoder_input = keras.Input(shape=input_shape) enc = layers.LSTM(64)(encoder_input) z_mean = layers.Dense(latent_dim, name="z_mean")(enc) z_log_sigma = layers.Dense(latent_dim, name="z_log_var")(enc) z = Sampling()([z_mean, z_log_sigma]) encoder = keras.Model(encoder_input, [z_mean, z_log_sigma, z], name="encoder") encoder.summary() # Extra layers for leaky input to decoder leak_input_dec_ip = keras.Input(shape=input_shape) leak_input_dec = layers.LSTM(2)(leak_input_dec_ip) # Decoder where we have inputs from leaky input and sampling layer inp_z = keras.Input(shape=(latent_dim,)) dec = layers.Concatenate()([leak_input_dec, inp_z]) # or Add dec = layers.RepeatVector(96)(inp_z) dec = layers.LSTM(64, return_sequences=True)(dec) out = layers.TimeDistributed(layers.Dense(96))(dec) decoder = keras.Model([leak_input_dec, inp_z], out) decoder.summary()
问题原因与解决方案
错误核心
报错源于模型计算图断开:你在定义Decoder时,将中间层输出leak_input_dec作为模型输入,但Keras要求Model的输入必须是keras.Input实例。同时代码中拼接泄漏输入后未使用拼接结果,等于白加了泄漏机制的逻辑。
修正步骤
- 把泄漏输入的
Input层直接作为Decoder的输入,而非中间层张量 - 确保拼接后的张量被用于后续网络计算,让泄漏信息真正传入模型
- 检查维度匹配,保证各层输入输出维度兼容
修正后的代码
from tensorflow import keras import tensorflow as tf from tensorflow.keras import layers class Sampling(layers.Layer): """Uses (z_mean, z_log_var) to sample z.""" def call(self, inputs): z_mean, z_log_var = inputs batch = tf.shape(z_mean)[0] dim = tf.shape(z_mean)[1] epsilon = tf.keras.backend.random_normal(shape=(batch, dim), mean=0., stddev=1.) return z_mean + tf.exp(0.5 * z_log_var) * epsilon # Build encoder and decoder latent_dim = 2 input_shape = (4, 96) encoder_input = keras.Input(shape=input_shape) enc = layers.LSTM(64)(encoder_input) z_mean = layers.Dense(latent_dim, name="z_mean")(enc) z_log_sigma = layers.Dense(latent_dim, name="z_log_var")(enc) z = Sampling()([z_mean, z_log_sigma]) encoder = keras.Model(encoder_input, [z_mean, z_log_sigma, z], name="encoder") encoder.summary() # Decoder with leaky input # 直接将Input层作为模型输入 leak_input_dec_ip = keras.Input(shape=input_shape) # 处理泄漏输入 leak_processed = layers.LSTM(2)(leak_input_dec_ip) inp_z = keras.Input(shape=(latent_dim,)) # 拼接泄漏输入处理结果与z dec_concat = layers.Concatenate()([leak_processed, inp_z]) # 使用拼接后的张量进行后续处理 dec = layers.RepeatVector(96)(dec_concat) dec = layers.LSTM(64, return_sequences=True)(dec) out = layers.TimeDistributed(layers.Dense(96))(dec) # 模型输入为两个Input层实例 decoder = keras.Model([leak_input_dec_ip, inp_z], out) decoder.summary()
额外提示
- 自回归逻辑在推理阶段需要循环传入历史生成样本:训练时可用真实历史数据,推理时需将上一步生成结果作为泄漏输入传入
- 如果需要逐步依赖前序输出的严格自回归,可考虑用
tf.while_loop或递归LSTM结构实现序列的逐步生成
内容的提问来源于stack exchange,提问作者ikespand
相关产品推荐
相关产品推荐

