Keras张量与生成层的关联及代码训练逻辑疑问
在《Machine Learning with scikit-learn and Tensorflow》一书第16章的这段代码里,我对层与张量的训练逻辑感到困惑:
import tensorflow_addons as tfa encoder_inputs = keras.layers.Input(shape=[None], dtype=np.int32) decoder_inputs = keras.layers.Input(shape=[None], dtype=np.int32) sequence_lengths = keras.layers.Input(shape=[], dtype=np.int32) embeddings = keras.layers.Embedding(vocab_size, embed_size) encoder_embeddings = embeddings(encoder_inputs) decoder_embeddings = embeddings(decoder_inputs) encoder = keras.layers.LSTM(512, return_state=True) encoder_outputs, state_h, state_c = encoder(encoder_embeddings) encoder_state = [state_h, state_c] sampler = tfa.seq2seq.sampler.TrainingSampler() decoder_cell = keras.layers.LSTMCell(512) output_layer = keras.layers.Dense(vocab_size) decoder = tfa.seq2seq.basic_decoder.BasicDecoder(decoder_cell, sampler, output_layer=output_layer) final_outputs, final_state, final_sequence_lengths = decoder( decoder_embeddings, initial_state=encoder_state, sequence_length=sequence_lengths) Y_proba = tf.nn.softmax(final_outputs.rnn_output) model = keras.models.Model( inputs=[encoder_inputs, decoder_inputs, sequence_lengths], outputs=[Y_proba])
后续训练代码:
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam") X = np.random.randint(100, size=10*1000).reshape(1000, 10) Y = np.random.randint(100, size=15*1000).reshape(1000, 15) X_decoder = np.c_[np.zeros((1000, 1)), Y[:, :-1]] seq_lengths = np.full([1000], 15) history = model.fit([X, X_decoder, seq_lengths], Y, epochs=2)
我的疑问是:创建Embedding层后直接用它处理输入张量,LSTM层也是直接处理嵌入张量,这些层看起来没有被“显式加入模型”,但为什么嵌入层的参数能被训练、模型还能收敛?另外,Keras张量和生成它的层之间到底是怎么关联的?
核心解释:Keras函数式API的张量追踪机制
层与张量的关联自动建立:当你用Keras层处理输入张量时(比如
embeddings(encoder_inputs)),Keras会自动记录该张量的生成来源(即对应的层),以及完整的计算链路。后续创建Model对象时,只要指定最终的输入和输出张量,Keras会自动回溯整个计算图,把所有参与运算的层都纳入模型,无需手动“添加”层。嵌入层参数可训练的原因:Embedding层的权重参数会被自动包含在模型的可训练参数集合中。从
encoder_inputs到Y_proba的计算路径里,Embedding层是核心节点,Keras构建模型时会识别这一点,训练时梯度会反向传播到Embedding层的权重,完成参数更新。函数式API的本质是构建计算图:和Sequential模型的“线性堆叠”不同,函数式API通过张量间的运算构建计算图。每个Keras张量都携带着它的生成层信息,当你把输入、输出张量传给
Model时,Keras会自动梳理出所有依赖的层,形成完整的模型结构。
举个简单例子:x = Input(...),y = Dense(10)(x),model = Model(x, y),这里的Dense层没有被手动加入模型,但Keras通过y回溯到x,自动将Dense层纳入模型,和你这段代码的逻辑完全一致。
- tfa Decoder组件的兼容性:
BasicDecoder作为TensorFlow Addons的组件,同样遵循Keras的计算图规则。它接收的decoder_embeddings关联着前面的Embedding层,initial_state关联着LSTM层,因此这些层都会被纳入模型的训练体系。
内容的提问来源于stack exchange,提问作者Marek M.

