意外找到 BatchNormalization 类型的实例。期望一个符号张量实例

Unexpectedly found an instance of type of BatchNormalization. Expected a symbolic tensor instance

我在 Keras 中实现残差网络时出错。下面是给我错误的代码(错误来自函数定义最后一步的第一行):

加载包:

import numpy as np
from keras import layers
from keras.layers import Input, Add, Concatenate, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D, GlobalMaxPooling2D
from keras.models import Model, load_model
from keras.preprocessing import image
from keras.utils import layer_utils
from keras.utils.data_utils import get_file
from keras.applications.imagenet_utils import preprocess_input
import pydot
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
from keras.utils import plot_model
from resnets_utils import *
from keras.initializers import glorot_uniform
import scipy.misc
from matplotlib.pyplot import imshow
%matplotlib inline

import keras.backend as K
K.set_image_data_format('channels_last')
K.set_learning_phase(1)

定义函数:(这是 "final step" 的第一行给我的错误)

def identity_block(X, f, filters, stage, block):
    """
    Implementation of the identity block as defined in Figure 4

    Arguments:
    X -- input tensor of shape (m, n_H_prev, n_W_prev, n_C_prev)
    f -- integer, specifying the shape of the middle CONV's window for the main path
    filters -- python list of integers, defining the number of filters in the CONV layers of the main path
    stage -- integer, used to name the layers, depending on their position in the network
    block -- string/character, used to name the layers, depending on their position in the network

    Returns:
    X -- output of the identity block, tensor of shape (n_H, n_W, n_C)
    """

    # defining name basis
    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'
    # Save the input value. You'll need this later to add back to the main path. 
    X_shortcut = X

    # First component of main path
    X = Conv2D(filters = F1, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2a', kernel_initializer = glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3, name = bn_name_base + '2a')(X)
    X = Activation('relu')(X)

    # Second component of main path 
    X = Conv2D(filters=F2, kernel_size=(f,f),strides=(1,1),padding='same',name=conv_name_base+'2b',kernel_initializer=glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis=3,name=bn_name_base+'2b')(X)
    X = Activation('relu')(X)

    # Third component of main path
    X = Conv2D(filters=F3,kernel_size=(1,1),strides=(1,1),padding='valid',name=conv_name_base+'2c',kernel_initializer=glorot_uniform(seed=0))(X)
    print(f'before BatchNormalization: X={X}');X = BatchNormalization(axis=3,name=bn_name_base+'2c');print(f'after  BatchNormalization: X={X}');

    # Final step: Add shortcut value to main path, and pass it through a RELU activation
    X = Add()([X_shortcut,X])
    X = Activation('relu')(X)

    ### END CODE HERE ###

return X

Call/test 上面的函数:

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 = identity_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]))

下面是打印信息和错误信息:

BatchNormalization 之前:X=Tensor("res1a_branch2c/BiasAdd:0", shape=(3, 4, 4, 6), dtype=float32) BatchNormalization 之后:X= <keras.layers.normalization.BatchNormalization object at 0x7f169c6d9668>

ValueError: Unexpectedly found an instance of type `<class 'keras.layers.normalization.BatchNormalization'>`. Expected a symbolic tensor instance.

下面是完整的日志(以备不时之需)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/opt/conda/lib/python3.6/site-packages/keras/engine/topology.py in assert_input_compatibility(self, inputs)
    424             try:
--> 425                 K.is_keras_tensor(x)
    426             except ValueError:

/opt/conda/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py in is_keras_tensor(x)
    399                           tf.SparseTensor)):
--> 400         raise ValueError('Unexpectedly found an instance of type `' + str(type(x)) + '`. '
    401                          'Expected a symbolic tensor instance.')

ValueError: Unexpectedly found an instance of type `<class 'keras.layers.normalization.BatchNormalization'>`. Expected a symbolic tensor instance.

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-6-b3d1050f50dc> in <module>()
      5     A_prev = tf.placeholder("float", [3, 4, 4, 6])
      6     X = np.random.randn(3, 4, 4, 6)
----> 7     A = identity_block(A_prev, f = 2, filters = [2, 4, 6], stage = 1, block = 'a')
      8     test.run(tf.global_variables_initializer())
      9     out = test.run([A], feed_dict={A_prev: X, K.learning_phase(): 0})

<ipython-input-5-013941ce79d6> in identity_block(X, f, filters, stage, block)
     43 
     44     # Final step: Add shortcut value to main path, and pass it through a RELU activation (≈2 lines)
---> 45     X = Add()([X_shortcut,X])
     46     X = Activation('relu')(X)
     47 

/opt/conda/lib/python3.6/site-packages/keras/engine/topology.py in __call__(self, inputs, **kwargs)
    556                 # Raise exceptions in case the input is not compatible
    557                 # with the input_spec specified in the layer constructor.
--> 558                 self.assert_input_compatibility(inputs)
    559 
    560                 # Collect input shapes to build layer.

/opt/conda/lib/python3.6/site-packages/keras/engine/topology.py in assert_input_compatibility(self, inputs)
    429                                  'Received type: ' +
    430                                  str(type(x)) + '. Full input: ' +
--> 431                                  str(inputs) + '. All inputs to the layer '
    432                                  'should be tensors.')
    433 

ValueError: Layer add_1 was called with an input that isn't a symbolic tensor. Received type: <class 'keras.layers.normalization.BatchNormalization'>. Full input: [<tf.Tensor 'Placeholder:0' shape=(3, 4, 4, 6) dtype=float32>, <keras.layers.normalization.BatchNormalization object at 0x7f169c6d9668>]. All inputs to the layer should be tensors.

我想我在函数定义的最后一步遗漏了一些东西,但我不知道为什么会出错。这里有 Keras 专家可以帮助我吗?

永远记得将张量传递到层中:

print(f'before BatchNormalization: X={X}');
#X = BatchNormalization(axis=3,name=bn_name_base+'2c')    # <--- INCORRECT
X = BatchNormalization(axis=3,name=bn_name_base+'2c')(X)  # <--- CORRECT
print(f'after  BatchNormalization: X={X}');

'CORRECT' 和 'INCORRECT' 之间的区别是,后者产生一个 - 而前者 将该层评估为张量 当喂 X.

此外,您的 identity_block() 缺少 return,这将引发另一个错误;添加: return X。最后,F1, F2, F3 既未在函数内定义也未作为参数传递 - 您可能不会将其视为错误,因为它们是在函数 外部 定义的 - 例如在您的本地命名空间中。