Keras Sequential模型与独立层计算结果不一致问题求助
Sequential模型与独立层计算结果不一致的原因分析
我是TensorFlow新手,按照官方指南实现简单Sequential模型,编写代码后发现Sequential模型输出的y1和独立定义层组合计算的y2结果不一致,修改层名称后二者仍不相同,请问原因是什么?
原代码
#The Sequential model_1 import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers if (__name__=="__main__"): # Define Sequential model_1 with 3 layers model_1 = keras.Sequential( [ layers.Dense(2, activation="relu", name="layer_1"), layers.Dense(3, activation="relu", name="layer_2"), layers.Dense(4, name="layer_3"), ] ) # Call model_1 on a test input x = tf.ones((3, 3)) y1 = model_1(x) model_1.layers #################################################################### # Create 3 discrete layers as above x = tf.ones((3, 3)) layer1 = layers.Dense(2, activation="relu", name="layer1") layer2 = layers.Dense(3, activation="relu", name="layer2") layer3 = layers.Dense(4, name="layer3") y2 = layer3(layer2(layer1(x))) #################################################################### print('y1=', y1) print('y2=', y2)
首次运行输出
y1= tf.Tensor([[0. 0. 0. 0.][0. 0. 0. 0.][0. 0. 0. 0.]], shape=(3, 4), dtype=float32)
y2= tf.Tensor([[ 0.16045676 0.02784279 0.2826522 -0.2760685 ][ 0.16045676 0.02784279 0.2826522 -0.2760685 ][ 0.16045676 0.02784279 0.2826522 -0.2760685 ]], shape=(3, 4), dtype=float32)
修改层名称后的代码
model_1 = keras.Sequential( [ layers.Dense(2, activation="relu", name="layer1"), layers.Dense(3, activation="relu", name="layer2"), layers.Dense(4, name="layer3"), ] )
修改后输出
y1= tf.Tensor([[-0.56710994 0.4444507 0.09539947 0.7368923 ][-0.56710994 0.4444507 0.09539947 0.7368923 ][-0.56710994 0.4444507 0.09539947 0.7368923 ]], shape=(3, 4), dtype=float32)
y2= tf.Tensor([[-0.05642081 0.04768222 -0.01716159 0.00080794][-0.05642081 0.04768222 -0.01716159 0.00080794][-0.05642081 0.04768222 -0.01716159 0.00080794]], shape=(3, 4), dtype=float32)
原因分析与解决方案
核心原因
你创建了两组完全独立的层实例:Sequential模型里的layer_1/layer_2/layer_3(或修改后的layer1/layer2/layer3),和后面单独定义的layer1/layer2/layer3是毫无关联的不同对象。Keras的层在实例化时会随机初始化权重,两组不同的层权重参数完全不一样,所以计算结果自然不一致。
第一次运行时y1全0是随机初始化的巧合:Sequential模型的第一层Dense(2)权重初始化后,对输入tf.ones((3,3))计算的结果全部小于等于0,经过relu激活后输出全0,后续层输入全0,最终输出也就全0。
修改层名称只是让两组层的名字相同,但它们的实例身份和权重仍然是独立的,所以结果还是不同。
解决方案
如果要让y1和y2结果一致,需要复用同一组层实例,代码示例如下:
import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers if (__name__=="__main__"): # 先定义独立层实例 layer1 = layers.Dense(2, activation="relu", name="layer1") layer2 = layers.Dense(3, activation="relu", name="layer2") layer3 = layers.Dense(4, name="layer3") # 用已定义的层构建Sequential模型 model_1 = keras.Sequential([layer1, layer2, layer3]) # 计算y1和y2,此时用的是同一组层 x = tf.ones((3, 3)) y1 = model_1(x) y2 = layer3(layer2(layer1(x))) print('y1=', y1) print('y2=', y2)
这样两组计算共享同一层的权重参数,输出结果会完全一致。
内容的提问来源于stack exchange,提问作者Gabriele
相关产品推荐
相关产品推荐

