PS: Keras版本为2.4.3
下面的函数构建了没有全连接层的VGG16神经网络,因为我只想获取特征图。
from keras.models import Modelfrom keras.layers import Conv2D, MaxPooling2D, Inputimport keras.backend as Kimport tensorflow as tfdef VGG16(input_tensor=None): input_shape = (None, None, 3) if input_tensor == None: input_tensor = Input(shape=input_shape) elif not K.is_keras_tensor(input_tensor): input_tensor = Input(tensor=input_tensor, shape=input_shape) vgg = Conv2D(64, (3, 3), padding='same', activation='relu', name='b1c1')(input_tensor) vgg = Conv2D(64, (3, 3), padding='same', activation='relu', name='b1c2')(vgg) vgg = MaxPooling2D((2, 2), strides=(2, 2), name='b1m')(vgg) vgg = Conv2D(128, (3, 3), padding='same', activation='relu', name='b2c1')(vgg) vgg = Conv2D(128, (3, 3), padding='same', activation='relu', name='b2c2')(vgg) vgg = MaxPooling2D((2, 2), strides=(2, 2), name='b2m')(vgg) vgg = Conv2D(256, (3, 3), padding='same', activation='relu', name='b3c1')(vgg) vgg = Conv2D(256, (3, 3), padding='same', activation='relu', name='b3c2')(vgg) vgg = MaxPooling2D((2, 2), strides=(2, 2), name='b3m')(vgg) vgg = Conv2D(512, (3, 3), padding='same', activation='relu', name='b4c1')(vgg) vgg = Conv2D(512, (3, 3), padding='same', activation='relu', name='b4c2')(vgg) vgg = Conv2D(512, (3, 3), padding='same', activation='relu', name='b4c3')(vgg) vgg = MaxPooling2D((2, 2), strides=(2, 2), name='b4m')(vgg) vgg = Conv2D(512, (3, 3), padding='same', activation='relu', name='b5c1')(vgg) vgg = Conv2D(512, (3, 3), padding='same', activation='relu', name='b5c2')(vgg) vgg = Conv2D(512, (3, 3), padding='same', activation='relu', name='b5c3')(vgg) vgg = MaxPooling2D((2, 2), strides=(2, 2), name='b5m')(vgg) return vgg
此函数接收VGG16作为基础层,并将它们与第一个Conv2D层rpn_conv
连接。最后一个连接到rpn_cls
和rpn_reg
def rpn(base_layers): rpn_conv = Conv2D(512, (3, 3), padding='same', kernel_initializer='normal', activation='relu', name='rpn_conv')(base_layers) rpn_cls = Conv2D(9, (1, 1), kernel_initializer='uniform', activation='sigmoid', name='rpn_cls')(rpn_conv) rpn_reg = Conv2D(4*9, (1, 1), kernel_initializer='zero', activation='linear', name='rpn_reg')(rpn_conv) return [rpn_cls, rpn_reg, rpn_conv]
我运行了这两个函数,并将结果存储在bnn
(作为基础层)和rpn
中:
bnn = VGG16(Input(shape=(None, None, 3)))rpn = rpn(bnn)
然后我使用Keras的Model
类构建模型:
model = Model(inputs=Input(shape=(None, None, 3)), outputs=rpn[:2])
然后我得到了这个错误:
---------------------------------------------------------------------------ValueError Traceback (most recent call last)<ipython-input-43-8c789d1b6abf> in <module>() 2 rpn = rpn(bnn) 3 ----> 4 model = Model(inputs=Input(shape=(None, None, 512)), outputs=rpn[:2])5 frames/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/functional.py in _map_graph_network(inputs, outputs) 929 'The following previous layers ' 930 'were accessed without issue: ' +--> 931 str(layers_with_complete_input)) 932 for x in nest.flatten(node.outputs): 933 computable_tensors.add(id(x))ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_19:0", shape=(None, None, None, 3), dtype=float32) at layer "b1c1". The following previous layers were accessed without issue: []
回答:
当你使用model = Model(inputs=Input(shape=(None, None, 3)), outputs=rpn[:2])
构建模型时,你正在创建一个新的Input
张量。这会断开图形,你必须使用传入VGG16()
的那个。试试
input_tensor = Input(shape=(None, None, 3))bnn = VGG16(input_tensor)rpn = rpn(bnn)model = Model(inputs=input_tensor, outputs=rpn[:2])