首页 > 解决方案 > 重复的张量名称在不应该的情况下起作用

问题描述

def convolutional_block(X, f, filters, stage, block, s = 2):        
    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'

    F1, F2, F3 = filters

    X_shortcut = X

    X = Conv2D(F1, (1, 1), strides = (s,s), name = conv_name_base + '2a', padding='valid', kernel_initializer = glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3, name = bn_name_base + '2a')(X)
    X = Activation('relu')(X)

    X = Conv2D(F2, (f, f), strides = (1,1), name = conv_name_base + '2b', padding='same', kernel_initializer = glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3, name = bn_name_base + '2b')(X)
    X = Activation('relu')(X)

    X = Conv2D(F3, (1, 1), strides = (1,1), name = conv_name_base + '2c', padding='valid', kernel_initializer = glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3, name = bn_name_base + '2c')(X)      # <<<  X = BatchNormalization(axis = 3, name = bn_name_base + '2b')(X) also works!

    X_shortcut = Conv2D(F3, (1, 1), strides = (s,s), name = conv_name_base + '1', padding='valid', kernel_initializer = glorot_uniform(seed=0))(X_shortcut)
    X_shortcut = BatchNormalization(axis = 3, name = bn_name_base + '1')(X_shortcut)

    X = Add()([X, X_shortcut])
    X = Activation('relu')(X)

    return X

tf.reset_default_graph()

with tf.Session() as test:
    np.random.seed(1)
    A_prev = tf.placeholder("float", [3, 4, 4, 6])
    X = np.random.randn(3, 4, 4, 6)
    A = convolutional_block(A_prev, f = 2, filters = [2, 4, 6], stage = 1, block = 'a')
    test.run(tf.global_variables_initializer())
    out = test.run([A], feed_dict={A_prev: X, K.learning_phase(): 0})
    print("out = " + str(out[0][1][1][0]))
    print(tf.global_variables())

我很惊讶这条线X = BatchNormalization(axis = 3, name = bn_name_base + '2c')(X)可以复制X = BatchNormalization(axis = 3, name = bn_name_base + '2b')(X)并且代码没有错误。我希望它会给出重复的名称错误。谁能解释它为什么起作用。谢谢你。

标签: pythontensorflowkeras

解决方案


Tensorflow/Keras 有自己的内部变量名解析。所以当你用相同的名字(即x_bx_b)命名两个变量时,后者将被重命名为x_b_1

例如,在您的代码中,这是其中带有名称的变量2b。这是换线后

X = Conv2D(F3, (1, 1), strides = (1,1), name = conv_name_base + '2c', padding='valid', kernel_initializer = glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3, name = bn_name_base + '2c')(X)    

X = Conv2D(F3, (1, 1), strides = (1,1), name = conv_name_base + '2b', padding='valid', kernel_initializer = glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3, name = bn_name_base + '2b')(X)      # <<<  X = BatchNormalization(axis = 3, name = bn_name_base + '2b')(X) also works!

如您所见,有两组变量(后缀为2band 2b_1

<tf.Variable 'res1a_branch2b/kernel:0' shape=(2, 2, 2, 4) dtype=float32>
<tf.Variable 'res1a_branch2b/bias:0' shape=(4,) dtype=float32>
<tf.Variable 'bn1a_branch2b/gamma:0' shape=(4,) dtype=float32>
<tf.Variable 'bn1a_branch2b/beta:0' shape=(4,) dtype=float32>
<tf.Variable 'bn1a_branch2b/moving_mean:0' shape=(4,) dtype=float32>
<tf.Variable 'bn1a_branch2b/moving_variance:0' shape=(4,) dtype=float32>
<tf.Variable 'res1a_branch2b_1/kernel:0' shape=(1, 1, 4, 6) dtype=float32>
<tf.Variable 'res1a_branch2b_1/bias:0' shape=(6,) dtype=float32>
<tf.Variable 'bn1a_branch2b_1/gamma:0' shape=(6,) dtype=float32>
<tf.Variable 'bn1a_branch2b_1/beta:0' shape=(6,) dtype=float32>
<tf.Variable 'bn1a_branch2b_1/moving_mean:0' shape=(6,) dtype=float32>
<tf.Variable 'bn1a_branch2b_1/moving_variance:0' shape=(6,) dtype=float32>

推荐阅读