简体   繁体   English

从 Keras model 中间移除一层

[英]Removing a layer from the middle of a Keras model

I have tried to remove the layer number 10 from a pre trained VGG16 model so as to keep the pre-trained weights intact.我试图从预训练的 VGG16 model 中删除第 10 层,以保持预训练的权重不变。 However I am running into an unknown error.但是我遇到了一个未知的错误。 Here is my code:这是我的代码:

from keras import Model
from keras.layers import Dropout
from keras.applications.vgg16 import VGG16

model = VGG16(include_top=False, input_shape=(H, W, 3), weights='imagenet')

# Disassemble layers
layers = [l for l in model.layers]

# Now stack everything back
# Note: If you are going to fine tune the model, do not forget to
#       mark other layers as un-trainable
    
x = layers[9].output
x = layers[11](x)
x = layers[12](x)
x = layers[13](x)
    
# Final touch
result_model = Model(input=layers[0].input, output=x)
result_model.summary()

I get the foollowing error:我得到了愚蠢的错误:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-60-2ec8c5fab52d> in <module>()
      8 # Important: the number of filters should be the same!
      9 # Note: the receiptive field of two 3x3 convolutions is 5x5.
---> 10 dropout1 = Dropout(0.5)(layers[-3].output)
     11 dropout2 = Dropout(0.5)(layers[-2].output)
     12 dropout3 = Dropout(0.5)(layers[-1].output)

/usr/local/lib/python3.6/dist-packages/keras/engine/base_layer.py in output(self)
    843         if len(self._inbound_nodes) > 1:
    844             raise AttributeError('Layer ' + self.name +
--> 845                                  ' has multiple inbound nodes, '
    846                                  'hence the notion of "layer output" '
    847                                  'is ill-defined. '

AttributeError: Layer block4_conv1 has multiple inbound nodes, hence the notion of "layer output" is ill-defined. Use `get_output_at(node_index)` instead.

The problem is that when you call a layer with a new input node, the old input node is not deleted.问题是当你用一个新的输入节点调用一个层时,旧的输入节点并没有被删除。 You can see that when you call layers[11].inbound_nodes which has a length of 2 after running your code.您可以看到,当您在运行代码后调用长度为 2 的layers[11].inbound_nodes时。

My solution is to manually remove the old inbound and outbound nodes.我的解决方案是手动删除旧的入站和出站节点。 This is not so nice because these lists are protected variables.这不太好,因为这些列表是受保护的变量。

layers[9]._outbound_nodes = []
x = layers[9].output

for layer in layers[11:]:
    layer._inbound_nodes = []
    x = layer(x)
    layer._outbound_nodes = []

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM