TF.Keras中GRU模型Embedding与GRU层参数计算疑问
字符生成GRU模型参数疑问解答
问题背景
基于TF.Keras构建的字符生成GRU模型代码如下:
class CharGenModel(tf.keras.Model): def __init__(self, vocab_size, num_timesteps, embedding_dim, **kwargs): super(CharGenModel, self).__init__(**kwargs) self.embedding_layer = tf.keras.layers.Embedding(vocab_size, embedding_dim) self.rnn_layer = tf.keras.layers.GRU( num_timesteps, recurrent_initializer="glorot_uniform", recurrent_activation="sigmoid", stateful=True, return_sequences=True ) self.dense_layer = tf.keras.layers.Dense(vocab_size) def call(self, x): print(x.shape) x = self.embedding_layer(x) print(x.shape) x = self.rnn_layer(x) print(x.shape) x = self.dense_layer(x) print(x.shape) return x vocab_size = 92 embedding_dim = 256 seq_length = 100 batch_size = 64 model = CharGenModel(vocab_size, seq_length, embedding_dim) model.build(input_shape=(batch_size, seq_length)) model.summary()
运行model.summary()输出结果:
(64, 100) (64, 100, 256) (64, 100, 100) (64, 100, 92) Model: "char_gen_model_4" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding_4 (Embedding) multiple 23552 gru_4 (GRU) multiple 107400 dense_4 (Dense) multiple 9292 ================================================================= Total params: 140,244 Trainable params: 140,244 Non-trainable params: 0
疑问点
- 误以为Embedding层的
input_dim是输入数据维度64×100,但实际参数是92×256=23552,为何不是100×256? - 按公式
num_params = 3 × [100×(100+256)+100] = 107100计算GRU参数,和模型显示的107400不符,哪里遗漏了?
解答
疑问1:Embedding层参数计算逻辑
Embedding层的input_dim指的是词汇表的总大小,也就是输入字符的唯一类别数量,和输入数据的batch_size、seq_length完全无关。
在你的场景中,vocab_size=92意味着所有输入字符都是0~91之间的索引值,Embedding层会为每个索引学习一个长度为embedding_dim=256的向量,因此参数总数是92×256=23552。你混淆了输入数据的形状((batch_size, seq_length))和Embedding层的核心参数定义,输入数据只是承载字符索引的容器,每个索引对应一个预学习的嵌入向量。
疑问2:GRU层参数计算遗漏点
你的计算公式是基于标准GRU的实现,但TensorFlow的Keras GRU默认启用了reset_after=True参数(一种改进版GRU结构),这种结构会为每个门(更新门、重置门、候选隐藏状态)多添加一组偏置参数。
正确的参数计算方式(对应TF默认GRU):num_params = 3 × [units×(input_dim + units) + 2×units]
其中:
units=100(你传入的num_timesteps实际是GRU的隐藏单元数,命名容易混淆)input_dim=256(Embedding层的输出维度)
代入数值计算:3 × [100×(256+100) + 2×100] = 3 × (35600 + 200) = 3×35800 = 107400,和模型summary结果完全匹配。
你之前的公式少算了每组门的额外偏置,三个门总共少算3×100=300个参数,因此结果差了300。
内容的提问来源于stack exchange,提问作者batuman
相关产品推荐
相关产品推荐

