Keras中组合Embedder与Recovery构建自编码器时出现'trainable_variables'属性错误的技术求助
问题分析与解决方案
嘿,这个问题我之前踩过坑,咱们来一步步拆解问题出在哪:
错误根源
你现在把embedder和recovery定义成了普通函数(或类内的普通方法),但Keras的trainable_variables是Layer或Model实例才有的属性——普通函数只是在构建计算图的逻辑,本身并没有被封装成可训练的模块,自然就没有这个属性啦。
修复方案:把模块封装成Keras子Model
要解决这个问题,核心是把embedder和recovery这两个模块分别封装成独立的Keras Model实例,这样它们就会自带trainable_variables属性,也能更清晰地管理模块结构。
方案1:自定义Model类(推荐,适合复杂模型)
from tensorflow.keras import Model, Input, layers class CustomAutoencoder(Model): def __init__(self, timesteps, feat, hidden_nodes, output_nodes, batch_size): super().__init__() # 初始化参数 self.timesteps = timesteps self.feat = feat self.hidden_nodes = hidden_nodes self.output_nodes = output_nodes self.batch_size = batch_size # 构建两个子模块(作为Model实例) self.embedder = self._build_embedder() self.recovery = self._build_recovery() def _build_embedder(self): """构建编码器子模型""" inputs = Input(shape=[self.timesteps, self.feat], batch_size=self.batch_size) x = layers.LSTM(self.hidden_nodes, return_sequences=True)(inputs) x = layers.LSTM(self.hidden_nodes, return_sequences=True)(x) x = layers.LSTM(self.hidden_nodes, return_sequences=True)(x) outputs = layers.Dense(self.hidden_nodes, activation='sigmoid')(x) return Model(inputs=inputs, outputs=outputs) def _build_recovery(self): """构建解码器子模型(注意输入形状要和编码器输出匹配)""" inputs = Input(shape=[self.timesteps, self.hidden_nodes]) x = layers.LSTM(self.hidden_nodes, return_sequences=True)(inputs) x = layers.LSTM(self.hidden_nodes, return_sequences=True)(x) x = layers.LSTM(self.hidden_nodes, return_sequences=True)(x) outputs = layers.Dense(self.output_nodes, activation='sigmoid', name='OUTPUT')(x) return Model(inputs=inputs, outputs=outputs) def call(self, inputs): """定义完整前向传播逻辑""" h = self.embedder(inputs) x_tilde = self.recovery(h) return x_tilde
使用方式:
# 替换成你的实际参数 TIMESTEPS = 10 FEAT = 5 HIDDEN_NODES = 32 OUTPUT_NODES = 5 BATCH_SIZE = 16 # 实例化并构建模型 autoencoder = CustomAutoencoder(TIMESTEPS, FEAT, HIDDEN_NODES, OUTPUT_NODES, BATCH_SIZE) autoencoder.build(input_shape=(BATCH_SIZE, TIMESTEPS, FEAT)) autoencoder.summary() # 现在可以正常获取可训练变量了 var_list = autoencoder.embedder.trainable_variables + autoencoder.recovery.trainable_variables
方案2:纯函数式API(适合简单场景)
如果不想写类,也可以直接用函数式API把两个模块封装成独立Model:
from tensorflow.keras import Model, Input, layers def build_embedder(timesteps, feat, hidden_nodes, batch_size): inputs = Input(shape=[timesteps, feat], batch_size=batch_size) x = layers.LSTM(hidden_nodes, return_sequences=True)(inputs) x = layers.LSTM(hidden_nodes, return_sequences=True)(x) x = layers.LSTM(hidden_nodes, return_sequences=True)(x) outputs = layers.Dense(hidden_nodes, activation='sigmoid')(x) return Model(inputs=inputs, outputs=outputs) def build_recovery(timesteps, hidden_nodes, output_nodes): inputs = Input(shape=[timesteps, hidden_nodes]) x = layers.LSTM(hidden_nodes, return_sequences=True)(inputs) x = layers.LSTM(hidden_nodes, return_sequences=True)(x) x = layers.LSTM(hidden_nodes, return_sequences=True)(x) outputs = layers.Dense(output_nodes, activation='sigmoid', name='OUTPUT')(x) return Model(inputs=inputs, outputs=outputs) # 构建完整自编码器 embedder = build_embedder(TIMESTEPS, FEAT, HIDDEN_NODES, BATCH_SIZE) recovery = build_recovery(TIMESTEPS, HIDDEN_NODES, OUTPUT_NODES) X = Input(shape=[TIMESTEPS, FEAT], batch_size=BATCH_SIZE, name='RealData') H = embedder(X) X_tilde = recovery(H) autoencoder = Model(inputs=X, outputs=X_tilde) # 正常获取可训练变量 var_list = embedder.trainable_variables + recovery.trainable_variables
总结
本质就是把原来的普通函数逻辑,包装成Keras官方认可的Model实例——这样不仅能解决trainable_variables的属性问题,还能让模型结构更清晰,方便后续的模块复用、单独训练等操作。
内容的提问来源于stack exchange,提问作者HenDoNR
相关产品推荐
相关产品推荐

